Whamcloud - gitweb
LU-16500 utils: 'lfs migrate' should select new OSTs
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47         always_except LU-17127 39o
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 # minutes runtime:                   5              12     8   12   15   10
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o 842"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
101         sles_version=$(sles_version_code)
102         (( $sles_version >= $(version_code 11.4.0) )) ||
103                 always_except LU-4341 170
104
105         (( $sles_version >= $(version_code 12.0.0) )) ||
106                 always_except LU-3703 234
107 elif [ -r /etc/redhat-release ]; then
108         rhel_version=$(cat /etc/redhat-release |
109                 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ ].*//')
110         if (( $(version_code $rhel_version) >= $(version_code 9.3.0) )); then
111                 # disable test_906 temporarily until rhel9.3 solves the
112                 # failure on fio io_uring I/O engine.
113                 always_except LU-17289 906
114         fi
115 fi
116
117 build_test_filter
118 FAIL_ON_ERROR=false
119
120 cleanup() {
121         echo -n "cln.."
122         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
123         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
124 }
125 setup() {
126         echo -n "mnt.."
127         load_modules
128         setupall || exit 10
129         echo "done"
130 }
131
132 check_swap_layouts_support()
133 {
134         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
135                 skip "Does not support layout lock."
136 }
137
138 check_swap_layout_no_dom()
139 {
140         local FOLDER=$1
141         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
142         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
143 }
144
145 check_and_setup_lustre
146 DIR=${DIR:-$MOUNT}
147 assert_DIR
148
149 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
150
151 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
152 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
153 rm -rf $DIR/[Rdfs][0-9]*
154
155 # $RUNAS_ID may get set incorrectly somewhere else
156 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
157         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
158
159 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
160
161 if [ "${ONLY}" = "MOUNT" ] ; then
162         echo "Lustre is up, please go on"
163         exit
164 fi
165
166 echo "preparing for tests involving mounts"
167 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
168 touch $EXT2_DEV
169 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
170 echo # add a newline after mke2fs.
171
172 umask 077
173
174 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
175
176 # ensure all internal functions know we want full debug
177 export PTLDEBUG=all
178 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
179
180 test_0a() {
181         touch $DIR/$tfile
182         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
183         rm $DIR/$tfile
184         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
185 }
186 run_test 0a "touch; rm ====================="
187
188 test_0b() {
189         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
190         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
191 }
192 run_test 0b "chmod 0755 $DIR ============================="
193
194 test_0c() {
195         $LCTL get_param mdc.*.import | grep "state: FULL" ||
196                 error "import not FULL"
197         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
198                 error "bad target"
199 }
200 run_test 0c "check import proc"
201
202 test_0d() { # LU-3397
203         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
204                 skip "proc exports not supported before 2.10.57"
205
206         local mgs_exp="mgs.MGS.exports"
207         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
208         local exp_client_nid
209         local exp_client_version
210         local exp_val
211         local imp_val
212         local temp_imp=$DIR/$tfile.import
213         local temp_exp=$DIR/$tfile.export
214
215         # save mgc import file to $temp_imp
216         $LCTL get_param mgc.*.import | tee $temp_imp
217         # Check if client uuid is found in MGS export
218         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
219                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
220                         $client_uuid ] &&
221                         break;
222         done
223         # save mgs export file to $temp_exp
224         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
225
226         # Compare the value of field "connect_flags"
227         imp_val=$(grep "connect_flags" $temp_imp)
228         exp_val=$(grep "connect_flags" $temp_exp)
229         [ "$exp_val" == "$imp_val" ] ||
230                 error "export flags '$exp_val' != import flags '$imp_val'"
231
232         # Compare client versions.  Only compare top-3 fields for compatibility
233         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
234         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
235         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
236         [ "$exp_val" == "$imp_val" ] ||
237                 error "exp version '$exp_client_version'($exp_val) != " \
238                         "'$(lustre_build_version client)'($imp_val)"
239 }
240 run_test 0d "check export proc ============================="
241
242 test_0e() { # LU-13417
243         (( $MDSCOUNT > 1 )) ||
244                 skip "We need at least 2 MDTs for this test"
245
246         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
247                 skip "Need server version at least 2.14.51"
248
249         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
250         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
251
252         [ $default_lmv_count -eq 1 ] ||
253                 error "$MOUNT default stripe count $default_lmv_count"
254
255         [ $default_lmv_index -eq -1 ] ||
256                 error "$MOUNT default stripe index $default_lmv_index"
257
258         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
259         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
260
261         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
262         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
263
264         [ $mdt_index1 -eq $mdt_index2 ] &&
265                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
266
267         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
268 }
269 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
270
271 test_0f() { # LU-17471
272         (( $MDS1_VERSION < $(version_code 2.17.53) )) ||
273                 skip "MDS >= 2.17.53 removes /proc/.../brw_stats symlink"
274         (( $MDS1_VERSION < $(version_code 2.14.55-100-g8a84c7f9c7) ||
275            $MDS1_VERSION > $(version_code 2.15.60-25) )) ||
276                 skip "MDS was missing /proc/.../brw_stats value"
277
278         local path="lustre/osd-$FSTYPE/$FSNAME-MDT0000/brw_stats"
279         local out_proc=$(do_facet mds1 grep snapshot_time /proc/fs/$path)
280
281         [[ -n "$out_proc" ]] || error "brw_stats /proc/fs/$path not found"
282 }
283 run_test 0f "Symlink to /sys/kernel/debug/*/*/brw_stats should work properly"
284
285 test_1() {
286         test_mkdir $DIR/$tdir
287         test_mkdir $DIR/$tdir/d2
288         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
289         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
290         rmdir $DIR/$tdir/d2
291         rmdir $DIR/$tdir
292         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
293 }
294 run_test 1 "mkdir; remkdir; rmdir"
295
296 test_2() {
297         test_mkdir $DIR/$tdir
298         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
299         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
300         rm -r $DIR/$tdir
301         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
302 }
303 run_test 2 "mkdir; touch; rmdir; check file"
304
305 test_3() {
306         test_mkdir $DIR/$tdir
307         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
308         touch $DIR/$tdir/$tfile
309         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
310         rm -r $DIR/$tdir
311         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
312 }
313 run_test 3 "mkdir; touch; rmdir; check dir"
314
315 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
316 test_4() {
317         test_mkdir -i 1 $DIR/$tdir
318
319         touch $DIR/$tdir/$tfile ||
320                 error "Create file under remote directory failed"
321
322         rmdir $DIR/$tdir &&
323                 error "Expect error removing in-use dir $DIR/$tdir"
324
325         test -d $DIR/$tdir || error "Remote directory disappeared"
326
327         rm -rf $DIR/$tdir || error "remove remote dir error"
328 }
329 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
330
331 test_5() {
332         test_mkdir $DIR/$tdir
333         test_mkdir $DIR/$tdir/d2
334         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
335         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
336         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
337 }
338 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
339
340 test_6a() {
341         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
342         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
343         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
344                 error "$tfile does not have perm 0666 or UID $UID"
345         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
346         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
347                 error "$tfile should be 0666 and owned by UID $UID"
348 }
349 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
350
351 test_6c() {
352         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
353
354         touch $DIR/$tfile
355         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
356         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
357                 error "$tfile should be owned by UID $RUNAS_ID"
358         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
359         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
360                 error "$tfile should be owned by UID $RUNAS_ID"
361 }
362 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
363
364 test_6e() {
365         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
366
367         touch $DIR/$tfile
368         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
369         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
370                 error "$tfile should be owned by GID $UID"
371         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
372         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
373                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
374 }
375 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
376
377 test_6g() {
378         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
379
380         test_mkdir $DIR/$tdir
381         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
382         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
383         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
384         test_mkdir $DIR/$tdir/d/subdir
385         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
386                 error "$tdir/d/subdir should be GID $RUNAS_GID"
387         if [[ $MDSCOUNT -gt 1 ]]; then
388                 # check remote dir sgid inherite
389                 $LFS mkdir -i 0 $DIR/$tdir.local ||
390                         error "mkdir $tdir.local failed"
391                 chmod g+s $DIR/$tdir.local ||
392                         error "chmod $tdir.local failed"
393                 chgrp $RUNAS_GID $DIR/$tdir.local ||
394                         error "chgrp $tdir.local failed"
395                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
396                         error "mkdir $tdir.remote failed"
397                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
398                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
399                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
400                         error "$tdir.remote should be mode 02755"
401         fi
402 }
403 run_test 6g "verify new dir in sgid dir inherits group"
404
405 test_6h() { # bug 7331
406         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
407
408         touch $DIR/$tfile || error "touch failed"
409         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
410         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
411                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
412         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
413                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
414 }
415 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
416
417 test_7a() {
418         test_mkdir $DIR/$tdir
419         $MCREATE $DIR/$tdir/$tfile
420         chmod 0666 $DIR/$tdir/$tfile
421         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
422                 error "$tdir/$tfile should be mode 0666"
423 }
424 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
425
426 test_7b() {
427         if [ ! -d $DIR/$tdir ]; then
428                 test_mkdir $DIR/$tdir
429         fi
430         $MCREATE $DIR/$tdir/$tfile
431         echo -n foo > $DIR/$tdir/$tfile
432         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
433         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
434 }
435 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
436
437 test_8() {
438         test_mkdir $DIR/$tdir
439         touch $DIR/$tdir/$tfile
440         chmod 0666 $DIR/$tdir/$tfile
441         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
442                 error "$tfile mode not 0666"
443 }
444 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
445
446 test_9() {
447         test_mkdir $DIR/$tdir
448         test_mkdir $DIR/$tdir/d2
449         test_mkdir $DIR/$tdir/d2/d3
450         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
451 }
452 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
453
454 test_10() {
455         test_mkdir $DIR/$tdir
456         test_mkdir $DIR/$tdir/d2
457         touch $DIR/$tdir/d2/$tfile
458         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
459                 error "$tdir/d2/$tfile not a file"
460 }
461 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
462
463 test_11() {
464         test_mkdir $DIR/$tdir
465         test_mkdir $DIR/$tdir/d2
466         chmod 0666 $DIR/$tdir/d2
467         chmod 0705 $DIR/$tdir/d2
468         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
469                 error "$tdir/d2 mode not 0705"
470 }
471 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
472
473 test_12() {
474         test_mkdir $DIR/$tdir
475         touch $DIR/$tdir/$tfile
476         chmod 0666 $DIR/$tdir/$tfile
477         chmod 0654 $DIR/$tdir/$tfile
478         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
479                 error "$tdir/d2 mode not 0654"
480 }
481 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
482
483 test_13() {
484         test_mkdir $DIR/$tdir
485         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
486         >  $DIR/$tdir/$tfile
487         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
488                 error "$tdir/$tfile size not 0 after truncate"
489 }
490 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
491
492 test_14() {
493         test_mkdir $DIR/$tdir
494         touch $DIR/$tdir/$tfile
495         rm $DIR/$tdir/$tfile
496         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
497 }
498 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
499
500 test_15() {
501         test_mkdir $DIR/$tdir
502         touch $DIR/$tdir/$tfile
503         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
504         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
505                 error "$tdir/${tfile_2} not a file after rename"
506         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
507 }
508 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
509
510 test_16() {
511         test_mkdir $DIR/$tdir
512         touch $DIR/$tdir/$tfile
513         rm -rf $DIR/$tdir/$tfile
514         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
515 }
516 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
517
518 test_17a() {
519         test_mkdir $DIR/$tdir
520         touch $DIR/$tdir/$tfile
521         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
522         ls -l $DIR/$tdir
523         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
524                 error "$tdir/l-exist not a symlink"
525         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
526                 error "$tdir/l-exist not referencing a file"
527         rm -f $DIR/$tdir/l-exist
528         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
529 }
530 run_test 17a "symlinks: create, remove (real)"
531
532 test_17b() {
533         test_mkdir $DIR/$tdir
534         ln -s no-such-file $DIR/$tdir/l-dangle
535         ls -l $DIR/$tdir
536         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
537                 error "$tdir/l-dangle not referencing no-such-file"
538         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
539                 error "$tdir/l-dangle not referencing non-existent file"
540         rm -f $DIR/$tdir/l-dangle
541         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
542 }
543 run_test 17b "symlinks: create, remove (dangling)"
544
545 test_17c() { # bug 3440 - don't save failed open RPC for replay
546         test_mkdir $DIR/$tdir
547         ln -s foo $DIR/$tdir/$tfile
548         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
549 }
550 run_test 17c "symlinks: open dangling (should return error)"
551
552 test_17d() {
553         test_mkdir $DIR/$tdir
554         ln -s foo $DIR/$tdir/$tfile
555         touch $DIR/$tdir/$tfile || error "creating to new symlink"
556 }
557 run_test 17d "symlinks: create dangling"
558
559 test_17e() {
560         test_mkdir $DIR/$tdir
561         local foo=$DIR/$tdir/$tfile
562         ln -s $foo $foo || error "create symlink failed"
563         ls -l $foo || error "ls -l failed"
564         ls $foo && error "ls not failed" || true
565 }
566 run_test 17e "symlinks: create recursive symlink (should return error)"
567
568 test_17f() {
569         test_mkdir $DIR/$tdir
570         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
571         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
572         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
573         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
574         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
575         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
576         ls -l  $DIR/$tdir
577 }
578 run_test 17f "symlinks: long and very long symlink name"
579
580 # str_repeat(S, N) generate a string that is string S repeated N times
581 str_repeat() {
582         local s=$1
583         local n=$2
584         local ret=''
585         while [ $((n -= 1)) -ge 0 ]; do
586                 ret=$ret$s
587         done
588         echo $ret
589 }
590
591 # Long symlinks and LU-2241
592 test_17g() {
593         test_mkdir $DIR/$tdir
594         local TESTS="59 60 61 4094 4095"
595
596         # Fix for inode size boundary in 2.1.4
597         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
598                 TESTS="4094 4095"
599
600         # Patch not applied to 2.2 or 2.3 branches
601         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
602         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
603                 TESTS="4094 4095"
604
605         for i in $TESTS; do
606                 local SYMNAME=$(str_repeat 'x' $i)
607                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
608                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
609         done
610 }
611 run_test 17g "symlinks: really long symlink name and inode boundaries"
612
613 test_17h() { #bug 17378
614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
615         remote_mds_nodsh && skip "remote MDS with nodsh"
616
617         local mdt_idx
618
619         test_mkdir $DIR/$tdir
620         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
621         $LFS setstripe -c -1 $DIR/$tdir
622         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
623         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
624         touch $DIR/$tdir/$tfile || true
625 }
626 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
627
628 test_17i() { #bug 20018
629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
630         remote_mds_nodsh && skip "remote MDS with nodsh"
631
632         local foo=$DIR/$tdir/$tfile
633         local mdt_idx
634
635         test_mkdir -c1 $DIR/$tdir
636         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
637         ln -s $foo $foo || error "create symlink failed"
638 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
639         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
640         ls -l $foo && error "error not detected"
641         return 0
642 }
643 run_test 17i "don't panic on short symlink (should return error)"
644
645 test_17k() { #bug 22301
646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
647         [[ -z "$(which rsync 2>/dev/null)" ]] &&
648                 skip "no rsync command"
649         rsync --help | grep -q xattr ||
650                 skip_env "$(rsync --version | head -n1) does not support xattrs"
651         test_mkdir $DIR/$tdir
652         test_mkdir $DIR/$tdir.new
653         touch $DIR/$tdir/$tfile
654         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
655         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
656                 error "rsync failed with xattrs enabled"
657 }
658 run_test 17k "symlinks: rsync with xattrs enabled"
659
660 test_17l() { # LU-279
661         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
662                 skip "no getfattr command"
663
664         test_mkdir $DIR/$tdir
665         touch $DIR/$tdir/$tfile
666         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
667         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
668                 # -h to not follow symlinks. -m '' to list all the xattrs.
669                 # grep to remove first line: '# file: $path'.
670                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
671                 do
672                         lgetxattr_size_check $path $xattr ||
673                                 error "lgetxattr_size_check $path $xattr failed"
674                 done
675         done
676 }
677 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
678
679 # LU-1540
680 test_17m() {
681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
683         remote_mds_nodsh && skip "remote MDS with nodsh"
684         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
685         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
686                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
687
688         local short_sym="0123456789"
689         local wdir=$DIR/$tdir
690         local i
691
692         test_mkdir $wdir
693         long_sym=$short_sym
694         # create a long symlink file
695         for ((i = 0; i < 4; ++i)); do
696                 long_sym=${long_sym}${long_sym}
697         done
698
699         echo "create 512 short and long symlink files under $wdir"
700         for ((i = 0; i < 256; ++i)); do
701                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
702                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
703         done
704
705         echo "erase them"
706         rm -f $wdir/*
707         sync
708         wait_delete_completed
709
710         echo "recreate the 512 symlink files with a shorter string"
711         for ((i = 0; i < 512; ++i)); do
712                 # rewrite the symlink file with a shorter string
713                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
714                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
715         done
716
717         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
718
719         echo "stop and checking mds${mds_index}:"
720         # e2fsck should not return error
721         stop mds${mds_index}
722         local devname=$(mdsdevname $mds_index)
723         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
724         rc=$?
725
726         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
727                 error "start mds${mds_index} failed"
728         df $MOUNT > /dev/null 2>&1
729         [ $rc -eq 0 ] ||
730                 error "e2fsck detected error for short/long symlink: rc=$rc"
731         rm -f $wdir/*
732 }
733 run_test 17m "run e2fsck against MDT which contains short/long symlink"
734
735 check_fs_consistency_17n() {
736         local mdt_index
737         local rc=0
738
739         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
740         # so it only check MDT1/MDT2 instead of all of MDTs.
741         for mdt_index in 1 2; do
742                 # e2fsck should not return error
743                 stop mds${mdt_index}
744                 local devname=$(mdsdevname $mdt_index)
745                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
746                         rc=$((rc + $?))
747
748                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
749                         error "mount mds$mdt_index failed"
750                 df $MOUNT > /dev/null 2>&1
751         done
752         return $rc
753 }
754
755 test_17n() {
756         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
758         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
759         remote_mds_nodsh && skip "remote MDS with nodsh"
760         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
761         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
762                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
763
764         local i
765
766         test_mkdir $DIR/$tdir
767         for ((i=0; i<10; i++)); do
768                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
769                         error "create remote dir error $i"
770                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
771                         error "create files under remote dir failed $i"
772         done
773
774         check_fs_consistency_17n ||
775                 error "e2fsck report error after create files under remote dir"
776
777         for ((i = 0; i < 10; i++)); do
778                 rm -rf $DIR/$tdir/remote_dir_${i} ||
779                         error "destroy remote dir error $i"
780         done
781
782         check_fs_consistency_17n ||
783                 error "e2fsck report error after unlink files under remote dir"
784
785         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
786                 skip "lustre < 2.4.50 does not support migrate mv"
787
788         for ((i = 0; i < 10; i++)); do
789                 mkdir -p $DIR/$tdir/remote_dir_${i}
790                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
791                         error "create files under remote dir failed $i"
792                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
793                         error "migrate remote dir error $i"
794         done
795         check_fs_consistency_17n || error "e2fsck report error after migration"
796
797         for ((i = 0; i < 10; i++)); do
798                 rm -rf $DIR/$tdir/remote_dir_${i} ||
799                         error "destroy remote dir error $i"
800         done
801
802         check_fs_consistency_17n || error "e2fsck report error after unlink"
803 }
804 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
805
806 test_17o() {
807         remote_mds_nodsh && skip "remote MDS with nodsh"
808         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
809                 skip "Need MDS version at least 2.3.64"
810
811         local wdir=$DIR/${tdir}o
812         local mdt_index
813         local rc=0
814
815         test_mkdir $wdir
816         touch $wdir/$tfile
817         mdt_index=$($LFS getstripe -m $wdir/$tfile)
818         mdt_index=$((mdt_index + 1))
819
820         cancel_lru_locks mdc
821         #fail mds will wait the failover finish then set
822         #following fail_loc to avoid interfer the recovery process.
823         fail mds${mdt_index}
824
825         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
826         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
827         ls -l $wdir/$tfile && rc=1
828         do_facet mds${mdt_index} lctl set_param fail_loc=0
829         [[ $rc -eq 0 ]] || error "stat file should fail"
830 }
831 run_test 17o "stat file with incompat LMA feature"
832
833 test_18() {
834         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
835         ls $DIR || error "Failed to ls $DIR: $?"
836 }
837 run_test 18 "touch .../f ; ls ... =============================="
838
839 test_19a() {
840         touch $DIR/$tfile
841         ls -l $DIR
842         rm $DIR/$tfile
843         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
844 }
845 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
846
847 test_19b() {
848         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
849 }
850 run_test 19b "ls -l .../f19 (should return error) =============="
851
852 test_19c() {
853         [ $RUNAS_ID -eq $UID ] &&
854                 skip_env "RUNAS_ID = UID = $UID -- skipping"
855
856         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
857 }
858 run_test 19c "$RUNAS touch .../f19 (should return error) =="
859
860 test_19d() {
861         cat $DIR/f19 && error || true
862 }
863 run_test 19d "cat .../f19 (should return error) =============="
864
865 test_20() {
866         touch $DIR/$tfile
867         rm $DIR/$tfile
868         touch $DIR/$tfile
869         rm $DIR/$tfile
870         touch $DIR/$tfile
871         rm $DIR/$tfile
872         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
873 }
874 run_test 20 "touch .../f ; ls -l ..."
875
876 test_21() {
877         test_mkdir $DIR/$tdir
878         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
879         ln -s dangle $DIR/$tdir/link
880         echo foo >> $DIR/$tdir/link
881         cat $DIR/$tdir/dangle
882         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
883         $CHECKSTAT -f -t file $DIR/$tdir/link ||
884                 error "$tdir/link not linked to a file"
885 }
886 run_test 21 "write to dangling link"
887
888 test_22() {
889         local wdir=$DIR/$tdir
890         test_mkdir $wdir
891         chown $RUNAS_ID:$RUNAS_GID $wdir
892         (cd $wdir || error "cd $wdir failed";
893                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
894                 $RUNAS tar xf -)
895         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
896         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
897         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
898                 error "checkstat -u failed"
899 }
900 run_test 22 "unpack tar archive as non-root user"
901
902 # was test_23
903 test_23a() {
904         test_mkdir $DIR/$tdir
905         local file=$DIR/$tdir/$tfile
906
907         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
908         openfile -f O_CREAT:O_EXCL $file &&
909                 error "$file recreate succeeded" || true
910 }
911 run_test 23a "O_CREAT|O_EXCL in subdir"
912
913 test_23b() { # bug 18988
914         test_mkdir $DIR/$tdir
915         local file=$DIR/$tdir/$tfile
916
917         rm -f $file
918         echo foo > $file || error "write filed"
919         echo bar >> $file || error "append filed"
920         $CHECKSTAT -s 8 $file || error "wrong size"
921         rm $file
922 }
923 run_test 23b "O_APPEND check"
924
925 # LU-9409, size with O_APPEND and tiny writes
926 test_23c() {
927         local file=$DIR/$tfile
928
929         # single dd
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
931         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
932         rm -f $file
933
934         # racing tiny writes
935         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
937         wait
938         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
939         rm -f $file
940
941         #racing tiny & normal writes
942         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
944         wait
945         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
946         rm -f $file
947
948         #racing tiny & normal writes 2, ugly numbers
949         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
950         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
951         wait
952         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
953         rm -f $file
954 }
955 run_test 23c "O_APPEND size checks for tiny writes"
956
957 # LU-11069 file offset is correct after appending writes
958 test_23d() {
959         local file=$DIR/$tfile
960         local offset
961
962         echo CentaurHauls > $file
963         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
964         if ((offset != 26)); then
965                 error "wrong offset, expected 26, got '$offset'"
966         fi
967 }
968 run_test 23d "file offset is correct after appending writes"
969
970 # rename sanity
971 test_24a() {
972         echo '-- same directory rename'
973         test_mkdir $DIR/$tdir
974         touch $DIR/$tdir/$tfile.1
975         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
976         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
977 }
978 run_test 24a "rename file to non-existent target"
979
980 test_24b() {
981         test_mkdir $DIR/$tdir
982         touch $DIR/$tdir/$tfile.{1,2}
983         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
984         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
985         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
986 }
987 run_test 24b "rename file to existing target"
988
989 test_24c() {
990         test_mkdir $DIR/$tdir
991         test_mkdir $DIR/$tdir/d$testnum.1
992         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
993         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
994         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
995 }
996 run_test 24c "rename directory to non-existent target"
997
998 test_24d() {
999         test_mkdir -c1 $DIR/$tdir
1000         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1001         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1002         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1003         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1004         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1005 }
1006 run_test 24d "rename directory to existing target"
1007
1008 test_24e() {
1009         echo '-- cross directory renames --'
1010         test_mkdir $DIR/R5a
1011         test_mkdir $DIR/R5b
1012         touch $DIR/R5a/f
1013         mv $DIR/R5a/f $DIR/R5b/g
1014         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1015         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1016 }
1017 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1018
1019 test_24f() {
1020         test_mkdir $DIR/R6a
1021         test_mkdir $DIR/R6b
1022         touch $DIR/R6a/f $DIR/R6b/g
1023         mv $DIR/R6a/f $DIR/R6b/g
1024         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1025         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1026 }
1027 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1028
1029 test_24g() {
1030         test_mkdir $DIR/R7a
1031         test_mkdir $DIR/R7b
1032         test_mkdir $DIR/R7a/d
1033         mv $DIR/R7a/d $DIR/R7b/e
1034         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1035         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1036 }
1037 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1038
1039 test_24h() {
1040         test_mkdir -c1 $DIR/R8a
1041         test_mkdir -c1 $DIR/R8b
1042         test_mkdir -c1 $DIR/R8a/d
1043         test_mkdir -c1 $DIR/R8b/e
1044         mrename $DIR/R8a/d $DIR/R8b/e
1045         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1046         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1047 }
1048 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1049
1050 test_24i() {
1051         echo "-- rename error cases"
1052         test_mkdir $DIR/R9
1053         test_mkdir $DIR/R9/a
1054         touch $DIR/R9/f
1055         mrename $DIR/R9/f $DIR/R9/a
1056         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1057         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1058         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1059 }
1060 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1061
1062 test_24j() {
1063         test_mkdir $DIR/R10
1064         mrename $DIR/R10/f $DIR/R10/g
1065         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1066         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1067         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1068 }
1069 run_test 24j "source does not exist ============================"
1070
1071 test_24k() {
1072         test_mkdir $DIR/R11a
1073         test_mkdir $DIR/R11a/d
1074         touch $DIR/R11a/f
1075         mv $DIR/R11a/f $DIR/R11a/d
1076         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1077         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1078 }
1079 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1080
1081 # bug 2429 - rename foo foo foo creates invalid file
1082 test_24l() {
1083         f="$DIR/f24l"
1084         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1085 }
1086 run_test 24l "Renaming a file to itself ========================"
1087
1088 test_24m() {
1089         f="$DIR/f24m"
1090         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1091         # on ext3 this does not remove either the source or target files
1092         # though the "expected" operation would be to remove the source
1093         $CHECKSTAT -t file ${f} || error "${f} missing"
1094         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1095 }
1096 run_test 24m "Renaming a file to a hard link to itself ========="
1097
1098 test_24n() {
1099     f="$DIR/f24n"
1100     # this stats the old file after it was renamed, so it should fail
1101     touch ${f}
1102     $CHECKSTAT ${f} || error "${f} missing"
1103     mv ${f} ${f}.rename
1104     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1105     $CHECKSTAT -a ${f} || error "${f} exists"
1106 }
1107 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1108
1109 test_24o() {
1110         test_mkdir $DIR/$tdir
1111         rename_many -s random -v -n 10 $DIR/$tdir
1112 }
1113 run_test 24o "rename of files during htree split"
1114
1115 test_24p() {
1116         test_mkdir $DIR/R12a
1117         test_mkdir $DIR/R12b
1118         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1119         mrename $DIR/R12a $DIR/R12b
1120         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1121         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1122         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1123         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1124 }
1125 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1126
1127 cleanup_multiop_pause() {
1128         trap 0
1129         kill -USR1 $MULTIPID
1130 }
1131
1132 test_24q() {
1133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1134
1135         test_mkdir $DIR/R13a
1136         test_mkdir $DIR/R13b
1137         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1138         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1139         MULTIPID=$!
1140
1141         trap cleanup_multiop_pause EXIT
1142         mrename $DIR/R13a $DIR/R13b
1143         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1144         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1145         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1146         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1147         cleanup_multiop_pause
1148         wait $MULTIPID || error "multiop close failed"
1149 }
1150 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1151
1152 test_24r() { #bug 3789
1153         test_mkdir $DIR/R14a
1154         test_mkdir $DIR/R14a/b
1155         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1156         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1157         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1158 }
1159 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1160
1161 test_24s() {
1162         test_mkdir $DIR/R15a
1163         test_mkdir $DIR/R15a/b
1164         test_mkdir $DIR/R15a/b/c
1165         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1166         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1167         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1168 }
1169 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1170
1171 test_24t() {
1172         test_mkdir $DIR/R16a
1173         test_mkdir $DIR/R16a/b
1174         test_mkdir $DIR/R16a/b/c
1175         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1176         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1177         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1178 }
1179 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1180
1181 test_24u() { # bug12192
1182         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1183         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1184 }
1185 run_test 24u "create stripe file"
1186
1187 simple_cleanup_common() {
1188         local createmany=$1
1189         local rc=0
1190
1191         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1192
1193         local start=$SECONDS
1194
1195         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1196         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1197         rc=$?
1198         wait_delete_completed
1199         echo "cleanup time $((SECONDS - start))"
1200         return $rc
1201 }
1202
1203 max_pages_per_rpc() {
1204         local mdtname="$(printf "MDT%04x" ${1:-0})"
1205         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1206 }
1207
1208 test_24v() {
1209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1210
1211         local nrfiles=${COUNT:-100000}
1212         local fname="$DIR/$tdir/$tfile"
1213
1214         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1215         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1216
1217         test_mkdir "$(dirname $fname)"
1218         # assume MDT0000 has the fewest inodes
1219         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1220         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1221         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1222
1223         stack_trap "simple_cleanup_common $nrfiles"
1224
1225         createmany -m "$fname" $nrfiles
1226
1227         cancel_lru_locks mdc
1228         lctl set_param mdc.*.stats clear
1229
1230         # was previously test_24D: LU-6101
1231         # readdir() returns correct number of entries after cursor reload
1232         local num_ls=$(ls $DIR/$tdir | wc -l)
1233         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1234         local num_all=$(ls -a $DIR/$tdir | wc -l)
1235         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1236                 [ $num_all -ne $((nrfiles + 2)) ]; then
1237                         error "Expected $nrfiles files, got $num_ls " \
1238                                 "($num_uniq unique $num_all .&..)"
1239         fi
1240         # LU-5 large readdir
1241         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1242         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1243         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1244         # take into account of overhead in lu_dirpage header and end mark in
1245         # each page, plus one in rpc_num calculation.
1246         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1247         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1248         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1249         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1250         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1251         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1252         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1253         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1254                 error "large readdir doesn't take effect: " \
1255                       "$mds_readpage should be about $rpc_max"
1256 }
1257 run_test 24v "list large directory (test hash collision, b=17560)"
1258
1259 test_24w() { # bug21506
1260         SZ1=234852
1261         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1262         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1263         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1264         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1265         [[ "$SZ1" -eq "$SZ2" ]] ||
1266                 error "Error reading at the end of the file $tfile"
1267 }
1268 run_test 24w "Reading a file larger than 4Gb"
1269
1270 test_24x() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1273         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1274                 skip "Need MDS version at least 2.7.56"
1275
1276         local MDTIDX=1
1277         local remote_dir=$DIR/$tdir/remote_dir
1278
1279         test_mkdir $DIR/$tdir
1280         $LFS mkdir -i $MDTIDX $remote_dir ||
1281                 error "create remote directory failed"
1282
1283         test_mkdir $DIR/$tdir/src_dir
1284         touch $DIR/$tdir/src_file
1285         test_mkdir $remote_dir/tgt_dir
1286         touch $remote_dir/tgt_file
1287
1288         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1289                 error "rename dir cross MDT failed!"
1290
1291         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1292                 error "rename file cross MDT failed!"
1293
1294         touch $DIR/$tdir/ln_file
1295         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1296                 error "ln file cross MDT failed"
1297
1298         rm -rf $DIR/$tdir || error "Can not delete directories"
1299 }
1300 run_test 24x "cross MDT rename/link"
1301
1302 test_24y() {
1303         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1305
1306         local remote_dir=$DIR/$tdir/remote_dir
1307         local mdtidx=1
1308
1309         test_mkdir $DIR/$tdir
1310         $LFS mkdir -i $mdtidx $remote_dir ||
1311                 error "create remote directory failed"
1312
1313         test_mkdir $remote_dir/src_dir
1314         touch $remote_dir/src_file
1315         test_mkdir $remote_dir/tgt_dir
1316         touch $remote_dir/tgt_file
1317
1318         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1319                 error "rename subdir in the same remote dir failed!"
1320
1321         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1322                 error "rename files in the same remote dir failed!"
1323
1324         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1325                 error "link files in the same remote dir failed!"
1326
1327         rm -rf $DIR/$tdir || error "Can not delete directories"
1328 }
1329 run_test 24y "rename/link on the same dir should succeed"
1330
1331 test_24z() {
1332         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1333         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1334                 skip "Need MDS version at least 2.12.51"
1335
1336         local index
1337
1338         for index in 0 1; do
1339                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1340                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1341         done
1342
1343         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1344
1345         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1346         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1347
1348         local mdts=$(comma_list $(mdts_nodes))
1349
1350         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1351         stack_trap "do_nodes $mdts $LCTL \
1352                 set_param mdt.*.enable_remote_rename=1" EXIT
1353
1354         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1355
1356         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1357         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1358 }
1359 run_test 24z "cross-MDT rename is done as cp"
1360
1361 test_24A() { # LU-3182
1362         local NFILES=5000
1363
1364         test_mkdir $DIR/$tdir
1365         stack_trap "simple_cleanup_common $NFILES"
1366         createmany -m $DIR/$tdir/$tfile $NFILES
1367         local t=$(ls $DIR/$tdir | wc -l)
1368         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1369         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1370
1371         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1372                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1373 }
1374 run_test 24A "readdir() returns correct number of entries."
1375
1376 test_24B() { # LU-4805
1377         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1378
1379         local count
1380
1381         test_mkdir $DIR/$tdir
1382         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1383                 error "create striped dir failed"
1384
1385         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1386         [ $count -eq 2 ] || error "Expected 2, got $count"
1387
1388         touch $DIR/$tdir/striped_dir/a
1389
1390         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1391         [ $count -eq 3 ] || error "Expected 3, got $count"
1392
1393         touch $DIR/$tdir/striped_dir/.f
1394
1395         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1396         [ $count -eq 4 ] || error "Expected 4, got $count"
1397
1398         rm -rf $DIR/$tdir || error "Can not delete directories"
1399 }
1400 run_test 24B "readdir for striped dir return correct number of entries"
1401
1402 test_24C() {
1403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1404
1405         mkdir $DIR/$tdir
1406         mkdir $DIR/$tdir/d0
1407         mkdir $DIR/$tdir/d1
1408
1409         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1410                 error "create striped dir failed"
1411
1412         cd $DIR/$tdir/d0/striped_dir
1413
1414         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1415         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1416         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1417
1418         [ "$d0_ino" = "$parent_ino" ] ||
1419                 error ".. wrong, expect $d0_ino, get $parent_ino"
1420
1421         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1422                 error "mv striped dir failed"
1423
1424         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1425
1426         [ "$d1_ino" = "$parent_ino" ] ||
1427                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1428 }
1429 run_test 24C "check .. in striped dir"
1430
1431 test_24E() {
1432         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1434
1435         mkdir -p $DIR/$tdir
1436         mkdir $DIR/$tdir/src_dir
1437         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1438                 error "create remote source failed"
1439
1440         touch $DIR/$tdir/src_dir/src_child/a
1441
1442         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1443                 error "create remote target dir failed"
1444
1445         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1446                 error "create remote target child failed"
1447
1448         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1449                 error "rename dir cross MDT failed!"
1450
1451         find $DIR/$tdir
1452
1453         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1454                 error "src_child still exists after rename"
1455
1456         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1457                 error "missing file(a) after rename"
1458
1459         rm -rf $DIR/$tdir || error "Can not delete directories"
1460 }
1461 run_test 24E "cross MDT rename/link"
1462
1463 test_24F () {
1464         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1465
1466         local repeats=1000
1467         [ "$SLOW" = "no" ] && repeats=100
1468
1469         mkdir -p $DIR/$tdir
1470
1471         echo "$repeats repeats"
1472         for ((i = 0; i < repeats; i++)); do
1473                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1474                 touch $DIR/$tdir/test/a || error "touch fails"
1475                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1476                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1477         done
1478
1479         true
1480 }
1481 run_test 24F "hash order vs readdir (LU-11330)"
1482
1483 test_24G () {
1484         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1485
1486         local ino1
1487         local ino2
1488
1489         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1490         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1491         touch $DIR/$tdir-0/f1 || error "touch f1"
1492         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1493         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1494         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1495         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1496         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1497 }
1498 run_test 24G "migrate symlink in rename"
1499
1500 test_24H() {
1501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1502         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1503                 skip "MDT1 should be on another node"
1504
1505         test_mkdir -i 1 -c 1 $DIR/$tdir
1506 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1507         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1508         touch $DIR/$tdir/$tfile || error "touch failed"
1509 }
1510 run_test 24H "repeat FLD_QUERY rpc"
1511
1512 test_25a() {
1513         echo '== symlink sanity ============================================='
1514
1515         test_mkdir $DIR/d25
1516         ln -s d25 $DIR/s25
1517         touch $DIR/s25/foo ||
1518                 error "File creation in symlinked directory failed"
1519 }
1520 run_test 25a "create file in symlinked directory ==============="
1521
1522 test_25b() {
1523         [ ! -d $DIR/d25 ] && test_25a
1524         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1525 }
1526 run_test 25b "lookup file in symlinked directory ==============="
1527
1528 test_26a() {
1529         test_mkdir $DIR/d26
1530         test_mkdir $DIR/d26/d26-2
1531         ln -s d26/d26-2 $DIR/s26
1532         touch $DIR/s26/foo || error "File creation failed"
1533 }
1534 run_test 26a "multiple component symlink ======================="
1535
1536 test_26b() {
1537         test_mkdir -p $DIR/$tdir/d26-2
1538         ln -s $tdir/d26-2/foo $DIR/s26-2
1539         touch $DIR/s26-2 || error "File creation failed"
1540 }
1541 run_test 26b "multiple component symlink at end of lookup ======"
1542
1543 test_26c() {
1544         test_mkdir $DIR/d26.2
1545         touch $DIR/d26.2/foo
1546         ln -s d26.2 $DIR/s26.2-1
1547         ln -s s26.2-1 $DIR/s26.2-2
1548         ln -s s26.2-2 $DIR/s26.2-3
1549         chmod 0666 $DIR/s26.2-3/foo
1550 }
1551 run_test 26c "chain of symlinks"
1552
1553 # recursive symlinks (bug 439)
1554 test_26d() {
1555         ln -s d26-3/foo $DIR/d26-3
1556 }
1557 run_test 26d "create multiple component recursive symlink"
1558
1559 test_26e() {
1560         [ ! -h $DIR/d26-3 ] && test_26d
1561         rm $DIR/d26-3
1562 }
1563 run_test 26e "unlink multiple component recursive symlink"
1564
1565 # recursive symlinks (bug 7022)
1566 test_26f() {
1567         test_mkdir $DIR/$tdir
1568         test_mkdir $DIR/$tdir/$tfile
1569         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1570         test_mkdir -p lndir/bar1
1571         test_mkdir $DIR/$tdir/$tfile/$tfile
1572         cd $tfile                || error "cd $tfile failed"
1573         ln -s .. dotdot          || error "ln dotdot failed"
1574         ln -s dotdot/lndir lndir || error "ln lndir failed"
1575         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1576         output=`ls $tfile/$tfile/lndir/bar1`
1577         [ "$output" = bar1 ] && error "unexpected output"
1578         rm -r $tfile             || error "rm $tfile failed"
1579         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1580 }
1581 run_test 26f "rm -r of a directory which has recursive symlink"
1582
1583 test_27a() {
1584         test_mkdir $DIR/$tdir
1585         $LFS getstripe $DIR/$tdir
1586         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1587         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1588         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1589 }
1590 run_test 27a "one stripe file"
1591
1592 test_27b() {
1593         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1594
1595         test_mkdir $DIR/$tdir
1596         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1597         $LFS getstripe -c $DIR/$tdir/$tfile
1598         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1599                 error "two-stripe file doesn't have two stripes"
1600
1601         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1602 }
1603 run_test 27b "create and write to two stripe file"
1604
1605 # 27c family tests specific striping, setstripe -o
1606 test_27ca() {
1607         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1608         test_mkdir -p $DIR/$tdir
1609         local osts="1"
1610
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1612         $LFS getstripe -i $DIR/$tdir/$tfile
1613         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1614                 error "stripe not on specified OST"
1615
1616         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1617 }
1618 run_test 27ca "one stripe on specified OST"
1619
1620 test_27cb() {
1621         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1622         test_mkdir -p $DIR/$tdir
1623         local osts="1,0"
1624         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1625         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1626         echo "$getstripe"
1627
1628         # Strip getstripe output to a space separated list of OSTs
1629         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1630                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1631         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1632                 error "stripes not on specified OSTs"
1633
1634         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1635 }
1636 run_test 27cb "two stripes on specified OSTs"
1637
1638 test_27cc() {
1639         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1640         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1641                 skip "server does not support overstriping"
1642
1643         test_mkdir -p $DIR/$tdir
1644         local osts="0,0"
1645         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1646         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1647         echo "$getstripe"
1648
1649         # Strip getstripe output to a space separated list of OSTs
1650         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1651                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1652         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1653                 error "stripes not on specified OSTs"
1654
1655         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1656 }
1657 run_test 27cc "two stripes on the same OST"
1658
1659 test_27cd() {
1660         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1661         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1662                 skip "server does not support overstriping"
1663         test_mkdir -p $DIR/$tdir
1664         local osts="0,1,1,0"
1665         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1666         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1667         echo "$getstripe"
1668
1669         # Strip getstripe output to a space separated list of OSTs
1670         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1671                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1672         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1673                 error "stripes not on specified OSTs"
1674
1675         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1676 }
1677 run_test 27cd "four stripes on two OSTs"
1678
1679 test_27ce() {
1680         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1681                 skip_env "too many osts, skipping"
1682         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1683                 skip "server does not support overstriping"
1684         # We do one more stripe than we have OSTs
1685         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1686                 skip_env "ea_inode feature disabled"
1687
1688         test_mkdir -p $DIR/$tdir
1689         local osts=""
1690         for i in $(seq 0 $OSTCOUNT);
1691         do
1692                 osts=$osts"0"
1693                 if [ $i -ne $OSTCOUNT ]; then
1694                         osts=$osts","
1695                 fi
1696         done
1697         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1698         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1699         echo "$getstripe"
1700
1701         # Strip getstripe output to a space separated list of OSTs
1702         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1703                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1704         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1705                 error "stripes not on specified OSTs"
1706
1707         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1708 }
1709 run_test 27ce "more stripes than OSTs with -o"
1710
1711 test_27cf() {
1712         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1713         local pid=0
1714
1715         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1716         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1717         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1718         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1719                 error "failed to set $osp_proc=0"
1720
1721         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1722         pid=$!
1723         sleep 1
1724         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1725         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1726                 error "failed to set $osp_proc=1"
1727         wait $pid
1728         [[ $pid -ne 0 ]] ||
1729                 error "should return error due to $osp_proc=0"
1730 }
1731 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1732
1733 test_27cg() {
1734         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1735                 skip "server does not support overstriping"
1736         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1737         large_xattr_enabled || skip_env "ea_inode feature disabled"
1738
1739         local osts="0"
1740
1741         for ((i=1;i<1000;i++)); do
1742                 osts+=",$((i % OSTCOUNT))"
1743         done
1744
1745         local mdts=$(comma_list $(mdts_nodes))
1746         local before=$(do_nodes $mdts \
1747                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1748                 awk '/many credits/{print $3}' |
1749                 calc_sum)
1750
1751         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1752         $LFS getstripe $DIR/$tfile | grep stripe
1753
1754         rm -f $DIR/$tfile || error "can't unlink"
1755
1756         after=$(do_nodes $mdts \
1757                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1758                 awk '/many credits/{print $3}' |
1759                 calc_sum)
1760
1761         (( before == after )) ||
1762                 error "too many credits happened: $after > $before"
1763 }
1764 run_test 27cg "1000 shouldn't cause too many credits"
1765
1766 test_27d() {
1767         test_mkdir $DIR/$tdir
1768         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1769                 error "setstripe failed"
1770         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1771         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1772 }
1773 run_test 27d "create file with default settings"
1774
1775 test_27e() {
1776         # LU-5839 adds check for existed layout before setting it
1777         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1778                 skip "Need MDS version at least 2.7.56"
1779
1780         test_mkdir $DIR/$tdir
1781         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1782         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1783         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1784 }
1785 run_test 27e "setstripe existing file (should return error)"
1786
1787 test_27f() {
1788         test_mkdir $DIR/$tdir
1789         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1790                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1791         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1792                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1793         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1794         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1795 }
1796 run_test 27f "setstripe with bad stripe size (should return error)"
1797
1798 test_27g() {
1799         test_mkdir $DIR/$tdir
1800         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1801         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1802                 error "$DIR/$tdir/$tfile has object"
1803 }
1804 run_test 27g "$LFS getstripe with no objects"
1805
1806 test_27ga() {
1807         test_mkdir $DIR/$tdir
1808         touch $DIR/$tdir/$tfile || error "touch failed"
1809         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1810         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1811         local rc=$?
1812         (( rc == 2 )) || error "getstripe did not return ENOENT"
1813
1814         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1815                         2>&1 > /dev/null)
1816         [[ $err_msg =~ "typo" ]] ||
1817                 error "expected message with correct filename, got '$err_msg'"
1818 }
1819 run_test 27ga "$LFS getstripe with missing file (should return error)"
1820
1821 test_27i() {
1822         test_mkdir $DIR/$tdir
1823         touch $DIR/$tdir/$tfile || error "touch failed"
1824         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1825                 error "missing objects"
1826 }
1827 run_test 27i "$LFS getstripe with some objects"
1828
1829 test_27j() {
1830         test_mkdir $DIR/$tdir
1831         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1832                 error "setstripe failed" || true
1833 }
1834 run_test 27j "setstripe with bad stripe offset (should return error)"
1835
1836 test_27k() { # bug 2844
1837         test_mkdir $DIR/$tdir
1838         local file=$DIR/$tdir/$tfile
1839         local ll_max_blksize=$((4 * 1024 * 1024))
1840         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1841         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1842         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1843         dd if=/dev/zero of=$file bs=4k count=1
1844         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1845         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1846 }
1847 run_test 27k "limit i_blksize for broken user apps"
1848
1849 test_27l() {
1850         mcreate $DIR/$tfile || error "creating file"
1851         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1852                 error "setstripe should have failed" || true
1853 }
1854 run_test 27l "check setstripe permissions (should return error)"
1855
1856 test_27m() {
1857         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1858
1859         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1860                 skip_env "multiple clients -- skipping"
1861
1862         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1863                    head -n1)
1864         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1865                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1866         fi
1867         stack_trap simple_cleanup_common
1868         test_mkdir $DIR/$tdir
1869         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1870         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1871                 error "dd should fill OST0"
1872         i=2
1873         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1874                 i=$((i + 1))
1875                 [ $i -gt 256 ] && break
1876         done
1877         i=$((i + 1))
1878         touch $DIR/$tdir/$tfile.$i
1879         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1880             awk '{print $1}'| grep -w "0") ] &&
1881                 error "OST0 was full but new created file still use it"
1882         i=$((i + 1))
1883         touch $DIR/$tdir/$tfile.$i
1884         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1885             awk '{print $1}'| grep -w "0") ] &&
1886                 error "OST0 was full but new created file still use it" || true
1887 }
1888 run_test 27m "create file while OST0 was full"
1889
1890 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1891 # if the OST isn't full anymore.
1892 reset_enospc() {
1893         local ostidx=${1:-""}
1894         local delay
1895         local ready
1896         local get_prealloc
1897
1898         local list=$(comma_list $(osts_nodes))
1899         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1900
1901         do_nodes $list lctl set_param fail_loc=0
1902         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1903         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1904                 awk '{print $1 * 2;exit;}')
1905         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1906                         grep -v \"^0$\""
1907         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1908 }
1909
1910 test_27n() {
1911         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1913         remote_mds_nodsh && skip "remote MDS with nodsh"
1914         remote_ost_nodsh && skip "remote OST with nodsh"
1915
1916         reset_enospc
1917         rm -f $DIR/$tdir/$tfile
1918         exhaust_precreations 0 0x80000215
1919         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1920         touch $DIR/$tdir/$tfile || error "touch failed"
1921         $LFS getstripe $DIR/$tdir/$tfile
1922         reset_enospc
1923 }
1924 run_test 27n "create file with some full OSTs"
1925
1926 test_27o() {
1927         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1929         remote_mds_nodsh && skip "remote MDS with nodsh"
1930         remote_ost_nodsh && skip "remote OST with nodsh"
1931
1932         reset_enospc
1933         rm -f $DIR/$tdir/$tfile
1934         exhaust_all_precreations 0x215
1935
1936         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1937
1938         reset_enospc
1939         rm -rf $DIR/$tdir/*
1940 }
1941 run_test 27o "create file with all full OSTs (should error)"
1942
1943 function create_and_checktime() {
1944         local fname=$1
1945         local loops=$2
1946         local i
1947
1948         for ((i=0; i < $loops; i++)); do
1949                 local start=$SECONDS
1950                 multiop $fname-$i Oc
1951                 ((SECONDS-start < TIMEOUT)) ||
1952                         error "creation took " $((SECONDS-$start)) && return 1
1953         done
1954 }
1955
1956 test_27oo() {
1957         local mdts=$(comma_list $(mdts_nodes))
1958
1959         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1960                 skip "Need MDS version at least 2.13.57"
1961
1962         local f0=$DIR/${tfile}-0
1963         local f1=$DIR/${tfile}-1
1964
1965         wait_delete_completed
1966
1967         # refill precreated objects
1968         $LFS setstripe -i0 -c1 $f0
1969
1970         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1971         # force QoS allocation policy
1972         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1973         stack_trap "do_nodes $mdts $LCTL set_param \
1974                 lov.*.qos_threshold_rr=$saved" EXIT
1975         sleep_maxage
1976
1977         # one OST is unavailable, but still have few objects preallocated
1978         stop ost1
1979         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1980                 rm -rf $f1 $DIR/$tdir*" EXIT
1981
1982         for ((i=0; i < 7; i++)); do
1983                 mkdir $DIR/$tdir$i || error "can't create dir"
1984                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1985                         error "can't set striping"
1986         done
1987         for ((i=0; i < 7; i++)); do
1988                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1989         done
1990         wait
1991 }
1992 run_test 27oo "don't let few threads to reserve too many objects"
1993
1994 test_27p() {
1995         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1997         remote_mds_nodsh && skip "remote MDS with nodsh"
1998         remote_ost_nodsh && skip "remote OST with nodsh"
1999
2000         reset_enospc
2001         rm -f $DIR/$tdir/$tfile
2002         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
2003
2004         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2005         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2006         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2007
2008         exhaust_precreations 0 0x80000215
2009         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2010         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2011         $LFS getstripe $DIR/$tdir/$tfile
2012
2013         reset_enospc
2014 }
2015 run_test 27p "append to a truncated file with some full OSTs"
2016
2017 test_27q() {
2018         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2020         remote_mds_nodsh && skip "remote MDS with nodsh"
2021         remote_ost_nodsh && skip "remote OST with nodsh"
2022
2023         reset_enospc
2024         rm -f $DIR/$tdir/$tfile
2025
2026         mkdir_on_mdt0 $DIR/$tdir
2027         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2028         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2029                 error "truncate $DIR/$tdir/$tfile failed"
2030         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2031
2032         exhaust_all_precreations 0x215
2033
2034         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2035         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2036
2037         reset_enospc
2038 }
2039 run_test 27q "append to truncated file with all OSTs full (should error)"
2040
2041 test_27r() {
2042         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2044         remote_mds_nodsh && skip "remote MDS with nodsh"
2045         remote_ost_nodsh && skip "remote OST with nodsh"
2046
2047         reset_enospc
2048         rm -f $DIR/$tdir/$tfile
2049         exhaust_precreations 0 0x80000215
2050
2051         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2052
2053         reset_enospc
2054 }
2055 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2056
2057 test_27s() { # bug 10725
2058         test_mkdir $DIR/$tdir
2059         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2060         local stripe_count=0
2061         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2062         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2063                 error "stripe width >= 2^32 succeeded" || true
2064
2065 }
2066 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2067
2068 test_27t() { # bug 10864
2069         WDIR=$(pwd)
2070         WLFS=$(which lfs)
2071         cd $DIR
2072         touch $tfile
2073         $WLFS getstripe $tfile
2074         cd $WDIR
2075 }
2076 run_test 27t "check that utils parse path correctly"
2077
2078 test_27u() { # bug 4900
2079         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2080         remote_mds_nodsh && skip "remote MDS with nodsh"
2081
2082         local index
2083         local list=$(comma_list $(mdts_nodes))
2084
2085 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2086         do_nodes $list $LCTL set_param fail_loc=0x139
2087         test_mkdir -p $DIR/$tdir
2088         stack_trap "simple_cleanup_common 1000"
2089         createmany -o $DIR/$tdir/$tfile 1000
2090         do_nodes $list $LCTL set_param fail_loc=0
2091
2092         TLOG=$TMP/$tfile.getstripe
2093         $LFS getstripe $DIR/$tdir > $TLOG
2094         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2095         [[ $OBJS -gt 0 ]] &&
2096                 error "$OBJS objects created on OST-0. See $TLOG" ||
2097                 rm -f $TLOG
2098 }
2099 run_test 27u "skip object creation on OSC w/o objects"
2100
2101 test_27v() { # bug 4900
2102         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2104         remote_mds_nodsh && skip "remote MDS with nodsh"
2105         remote_ost_nodsh && skip "remote OST with nodsh"
2106
2107         exhaust_all_precreations 0x215
2108         reset_enospc
2109
2110         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2111
2112         touch $DIR/$tdir/$tfile
2113         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2114         # all except ost1
2115         for (( i=1; i < OSTCOUNT; i++ )); do
2116                 do_facet ost$i lctl set_param fail_loc=0x705
2117         done
2118         local START=`date +%s`
2119         createmany -o $DIR/$tdir/$tfile 32
2120
2121         local FINISH=`date +%s`
2122         local TIMEOUT=`lctl get_param -n timeout`
2123         local PROCESS=$((FINISH - START))
2124         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2125                error "$FINISH - $START >= $TIMEOUT / 2"
2126         sleep $((TIMEOUT / 2 - PROCESS))
2127         reset_enospc
2128 }
2129 run_test 27v "skip object creation on slow OST"
2130
2131 test_27w() { # bug 10997
2132         test_mkdir $DIR/$tdir
2133         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2134         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2135                 error "stripe size $size != 65536" || true
2136         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2137                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2138 }
2139 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2140
2141 test_27wa() {
2142         [[ $OSTCOUNT -lt 2 ]] &&
2143                 skip_env "skipping multiple stripe count/offset test"
2144
2145         test_mkdir $DIR/$tdir
2146         for i in $(seq 1 $OSTCOUNT); do
2147                 offset=$((i - 1))
2148                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2149                         error "setstripe -c $i -i $offset failed"
2150                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2151                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2152                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2153                 [ $index -ne $offset ] &&
2154                         error "stripe offset $index != $offset" || true
2155         done
2156 }
2157 run_test 27wa "check $LFS setstripe -c -i options"
2158
2159 test_27x() {
2160         remote_ost_nodsh && skip "remote OST with nodsh"
2161         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2163
2164         OFFSET=$(($OSTCOUNT - 1))
2165         OSTIDX=0
2166         local OST=$(ostname_from_index $OSTIDX)
2167
2168         test_mkdir $DIR/$tdir
2169         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2170         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2171         sleep_maxage
2172         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2173         for i in $(seq 0 $OFFSET); do
2174                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2175                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2176                 error "OST0 was degraded but new created file still use it"
2177         done
2178         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2179 }
2180 run_test 27x "create files while OST0 is degraded"
2181
2182 test_27y() {
2183         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2184         remote_mds_nodsh && skip "remote MDS with nodsh"
2185         remote_ost_nodsh && skip "remote OST with nodsh"
2186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2187
2188         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2189         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2190                 osp.$mdtosc.prealloc_last_id)
2191         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2192                 osp.$mdtosc.prealloc_next_id)
2193         local fcount=$((last_id - next_id))
2194         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2195         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2196
2197         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2198                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2199         local OST_DEACTIVE_IDX=-1
2200         local OSC
2201         local OSTIDX
2202         local OST
2203
2204         for OSC in $MDS_OSCS; do
2205                 OST=$(osc_to_ost $OSC)
2206                 OSTIDX=$(index_from_ostuuid $OST)
2207                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2208                         OST_DEACTIVE_IDX=$OSTIDX
2209                 fi
2210                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2211                         echo $OSC "is Deactivated:"
2212                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2213                 fi
2214         done
2215
2216         OSTIDX=$(index_from_ostuuid $OST)
2217         test_mkdir $DIR/$tdir
2218         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2219
2220         for OSC in $MDS_OSCS; do
2221                 OST=$(osc_to_ost $OSC)
2222                 OSTIDX=$(index_from_ostuuid $OST)
2223                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2224                         echo $OST "is degraded:"
2225                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2226                                                 obdfilter.$OST.degraded=1
2227                 fi
2228         done
2229
2230         sleep_maxage
2231         createmany -o $DIR/$tdir/$tfile $fcount
2232
2233         for OSC in $MDS_OSCS; do
2234                 OST=$(osc_to_ost $OSC)
2235                 OSTIDX=$(index_from_ostuuid $OST)
2236                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2237                         echo $OST "is recovered from degraded:"
2238                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2239                                                 obdfilter.$OST.degraded=0
2240                 else
2241                         do_facet $SINGLEMDS lctl --device %$OSC activate
2242                 fi
2243         done
2244
2245         # all osp devices get activated, hence -1 stripe count restored
2246         local stripe_count=0
2247
2248         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2249         # devices get activated.
2250         sleep_maxage
2251         $LFS setstripe -c -1 $DIR/$tfile
2252         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2253         rm -f $DIR/$tfile
2254         [ $stripe_count -ne $OSTCOUNT ] &&
2255                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2256         return 0
2257 }
2258 run_test 27y "create files while OST0 is degraded and the rest inactive"
2259
2260 check_seq_oid()
2261 {
2262         log "check file $1"
2263
2264         lmm_count=$($LFS getstripe -c $1)
2265         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2266         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2267
2268         local old_ifs="$IFS"
2269         IFS=$'[:]'
2270         fid=($($LFS path2fid $1))
2271         IFS="$old_ifs"
2272
2273         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2274         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2275
2276         # compare lmm_seq and lu_fid->f_seq
2277         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2278         # compare lmm_object_id and lu_fid->oid
2279         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2280
2281         # check the trusted.fid attribute of the OST objects of the file
2282         local have_obdidx=false
2283         local stripe_nr=0
2284         $LFS getstripe $1 | while read obdidx oid hex seq; do
2285                 # skip lines up to and including "obdidx"
2286                 [ -z "$obdidx" ] && break
2287                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2288                 $have_obdidx || continue
2289
2290                 local ost=$((obdidx + 1))
2291                 local dev=$(ostdevname $ost)
2292                 local oid_hex
2293
2294                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2295
2296                 seq=$(echo $seq | sed -e "s/^0x//g")
2297                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2298                         oid_hex=$(echo $oid)
2299                 else
2300                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2301                 fi
2302                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2303
2304                 local ff=""
2305                 #
2306                 # Don't unmount/remount the OSTs if we don't need to do that.
2307                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2308                 # update too, until that use mount/ll_decode_filter_fid/mount.
2309                 # Re-enable when debugfs will understand new filter_fid.
2310                 #
2311                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2312                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2313                                 $dev 2>/dev/null" | grep "parent=")
2314                 fi
2315                 if [ -z "$ff" ]; then
2316                         stop ost$ost
2317                         mount_fstype ost$ost
2318                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2319                                 $(facet_mntpt ost$ost)/$obj_file)
2320                         unmount_fstype ost$ost
2321                         start ost$ost $dev $OST_MOUNT_OPTS
2322                         clients_up
2323                 fi
2324
2325                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2326
2327                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2328
2329                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2330                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2331                 #
2332                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2333                 #       stripe_size=1048576 component_id=1 component_start=0 \
2334                 #       component_end=33554432
2335                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2336                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2337                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2338                 local ff_pstripe
2339                 if grep -q 'stripe=' <<<$ff; then
2340                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2341                 else
2342                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2343                         # into f_ver in this case.  See comment on ff_parent.
2344                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2345                 fi
2346
2347                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2348                 [ $ff_pseq = $lmm_seq ] ||
2349                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2350                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2351                 [ $ff_poid = $lmm_oid ] ||
2352                         error "FF parent OID $ff_poid != $lmm_oid"
2353                 (($ff_pstripe == $stripe_nr)) ||
2354                         error "FF stripe $ff_pstripe != $stripe_nr"
2355
2356                 stripe_nr=$((stripe_nr + 1))
2357                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2358                         continue
2359                 if grep -q 'stripe_count=' <<<$ff; then
2360                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2361                                             -e 's/ .*//' <<<$ff)
2362                         [ $lmm_count = $ff_scnt ] ||
2363                                 error "FF stripe count $lmm_count != $ff_scnt"
2364                 fi
2365         done
2366 }
2367
2368 test_27z() {
2369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2370         remote_ost_nodsh && skip "remote OST with nodsh"
2371
2372         test_mkdir $DIR/$tdir
2373         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2374                 { error "setstripe -c -1 failed"; return 1; }
2375         # We need to send a write to every object to get parent FID info set.
2376         # This _should_ also work for setattr, but does not currently.
2377         # touch $DIR/$tdir/$tfile-1 ||
2378         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2379                 { error "dd $tfile-1 failed"; return 2; }
2380         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2381                 { error "setstripe -c -1 failed"; return 3; }
2382         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2383                 { error "dd $tfile-2 failed"; return 4; }
2384
2385         # make sure write RPCs have been sent to OSTs
2386         sync; sleep 5; sync
2387
2388         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2389         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2390 }
2391 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2392
2393 test_27A() { # b=19102
2394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2395
2396         save_layout_restore_at_exit $MOUNT
2397         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2398         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2399                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2400         local default_size=$($LFS getstripe -S $MOUNT)
2401         local default_offset=$($LFS getstripe -i $MOUNT)
2402         local dsize=$(do_facet $SINGLEMDS \
2403                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2404         [ $default_size -eq $dsize ] ||
2405                 error "stripe size $default_size != $dsize"
2406         [ $default_offset -eq -1 ] ||
2407                 error "stripe offset $default_offset != -1"
2408 }
2409 run_test 27A "check filesystem-wide default LOV EA values"
2410
2411 test_27B() { # LU-2523
2412         test_mkdir $DIR/$tdir
2413         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2414         touch $DIR/$tdir/f0
2415         # open f1 with O_LOV_DELAY_CREATE
2416         # rename f0 onto f1
2417         # call setstripe ioctl on open file descriptor for f1
2418         # close
2419         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2420                 $DIR/$tdir/f0
2421
2422         rm -f $DIR/$tdir/f1
2423         # open f1 with O_LOV_DELAY_CREATE
2424         # unlink f1
2425         # call setstripe ioctl on open file descriptor for f1
2426         # close
2427         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2428
2429         # Allow multiop to fail in imitation of NFS's busted semantics.
2430         true
2431 }
2432 run_test 27B "call setstripe on open unlinked file/rename victim"
2433
2434 # 27C family tests full striping and overstriping
2435 test_27Ca() { #LU-2871
2436         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2437
2438         declare -a ost_idx
2439         local index
2440         local found
2441         local i
2442         local j
2443
2444         test_mkdir $DIR/$tdir
2445         cd $DIR/$tdir
2446         for i in $(seq 0 $((OSTCOUNT - 1))); do
2447                 # set stripe across all OSTs starting from OST$i
2448                 $LFS setstripe -i $i -c -1 $tfile$i
2449                 # get striping information
2450                 ost_idx=($($LFS getstripe $tfile$i |
2451                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2452                 echo "OST Index: ${ost_idx[*]}"
2453
2454                 # check the layout
2455                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2456                         error "${#ost_idx[@]} != $OSTCOUNT"
2457
2458                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2459                         found=0
2460                         for j in "${ost_idx[@]}"; do
2461                                 if [ $index -eq $j ]; then
2462                                         found=1
2463                                         break
2464                                 fi
2465                         done
2466                         [ $found = 1 ] ||
2467                                 error "Can not find $index in ${ost_idx[*]}"
2468                 done
2469         done
2470 }
2471 run_test 27Ca "check full striping across all OSTs"
2472
2473 test_27Cb() {
2474         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2475                 skip "server does not support overstriping"
2476         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2477                 skip_env "too many osts, skipping"
2478
2479         test_mkdir -p $DIR/$tdir
2480         local setcount=$(($OSTCOUNT * 2))
2481         [ $setcount -lt 160 ] || large_xattr_enabled ||
2482                 skip_env "ea_inode feature disabled"
2483
2484         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2485                 error "setstripe failed"
2486
2487         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2488         [ $count -eq $setcount ] ||
2489                 error "stripe count $count, should be $setcount"
2490
2491         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2492                 error "overstriped should be set in pattern"
2493
2494         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2495                 error "dd failed"
2496 }
2497 run_test 27Cb "more stripes than OSTs with -C"
2498
2499 test_27Cc() {
2500         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2501                 skip "server does not support overstriping"
2502         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2503
2504         test_mkdir -p $DIR/$tdir
2505         local setcount=$(($OSTCOUNT - 1))
2506
2507         [ $setcount -lt 160 ] || large_xattr_enabled ||
2508                 skip_env "ea_inode feature disabled"
2509
2510         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2511                 error "setstripe failed"
2512
2513         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2514         [ $count -eq $setcount ] ||
2515                 error "stripe count $count, should be $setcount"
2516
2517         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2518                 error "overstriped should not be set in pattern"
2519
2520         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2521                 error "dd failed"
2522 }
2523 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2524
2525 test_27Cd() {
2526         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2527                 skip "server does not support overstriping"
2528         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2529         large_xattr_enabled || skip_env "ea_inode feature disabled"
2530
2531         force_new_seq_all
2532
2533         test_mkdir -p $DIR/$tdir
2534         local setcount=$LOV_MAX_STRIPE_COUNT
2535
2536         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2537                 error "setstripe failed"
2538
2539         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2540         [ $count -eq $setcount ] ||
2541                 error "stripe count $count, should be $setcount"
2542
2543         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2544                 error "overstriped should be set in pattern"
2545
2546         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2547                 error "dd failed"
2548
2549         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2550 }
2551 run_test 27Cd "test maximum stripe count"
2552
2553 test_27Ce() {
2554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2555                 skip "server does not support overstriping"
2556         test_mkdir -p $DIR/$tdir
2557
2558         pool_add $TESTNAME || error "Pool creation failed"
2559         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2560
2561         local setcount=8
2562
2563         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2564                 error "setstripe failed"
2565
2566         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2567         [ $count -eq $setcount ] ||
2568                 error "stripe count $count, should be $setcount"
2569
2570         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2571                 error "overstriped should be set in pattern"
2572
2573         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2574                 error "dd failed"
2575
2576         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2577 }
2578 run_test 27Ce "test pool with overstriping"
2579
2580 test_27Cf() {
2581         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2582                 skip "server does not support overstriping"
2583         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2584                 skip_env "too many osts, skipping"
2585
2586         test_mkdir -p $DIR/$tdir
2587
2588         local setcount=$(($OSTCOUNT * 2))
2589         [ $setcount -lt 160 ] || large_xattr_enabled ||
2590                 skip_env "ea_inode feature disabled"
2591
2592         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2593                 error "setstripe failed"
2594
2595         echo 1 > $DIR/$tdir/$tfile
2596
2597         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2598         [ $count -eq $setcount ] ||
2599                 error "stripe count $count, should be $setcount"
2600
2601         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2602                 error "overstriped should be set in pattern"
2603
2604         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2605                 error "dd failed"
2606
2607         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2608 }
2609 run_test 27Cf "test default inheritance with overstriping"
2610
2611 test_27Cg() {
2612         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2613                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2614
2615         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2616         (( $? != 0 )) || error "must be an error for not existent OST#"
2617 }
2618 run_test 27Cg "test setstripe with wrong OST idx"
2619
2620 test_27Ci() {
2621         local tf=$DIR/$tfile
2622
2623         stack_trap "rm -f $DIR/$tfile"
2624
2625         $LFS setstripe -E1M $tf || error "create $tf failed"
2626         $LFS setstripe -Eeof --component-add -C 100 $tf ||
2627                 error "add component failed"
2628
2629         $LFS getstripe -I2 $tf | awk '/lmm_pattern/ { print $2 }' |
2630                 grep "overstriped" || {
2631                 $LFS getstripe $tf
2632                 echo "lose overstriping setting"
2633         }
2634         sc=$($LFS getstripe -I2 --stripe-count $tf)
2635         (( $sc == 100 )) || {
2636                 $LFS getstripe $tf
2637                 echo "lose overstriping setting"
2638         }
2639
2640         stack_trap "rm -f $tf"
2641         dd if=/dev/zero of=$tf bs=1M count=10 || error "write $tf"
2642         sc=$($LFS getstripe -I2 --stripe-count $tf)
2643         (( $sc == 100 )) || {
2644                 $LFS getstripe $tf
2645                 echo "lose overstriping setting after instantiation"
2646         }
2647 }
2648 run_test 27Ci "add an overstriping component"
2649
2650 test_27D() {
2651         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2652         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2653         remote_mds_nodsh && skip "remote MDS with nodsh"
2654
2655         local POOL=${POOL:-testpool}
2656         local first_ost=0
2657         local last_ost=$(($OSTCOUNT - 1))
2658         local ost_step=1
2659         local ost_list=$(seq $first_ost $ost_step $last_ost)
2660         local ost_range="$first_ost $last_ost $ost_step"
2661
2662         test_mkdir $DIR/$tdir
2663         pool_add $POOL || error "pool_add failed"
2664         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2665
2666         local skip27D
2667         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2668                 skip27D+="-s 29"
2669         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2670                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2671                         skip27D+=" -s 30,31"
2672         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2673           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2674                 skip27D+=" -s 32,33"
2675         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2676                 skip27D+=" -s 34"
2677         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2678                 error "llapi_layout_test failed"
2679
2680         destroy_test_pools || error "destroy test pools failed"
2681 }
2682 run_test 27D "validate llapi_layout API"
2683
2684 # Verify that default_easize is increased from its initial value after
2685 # accessing a widely striped file.
2686 test_27E() {
2687         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2688         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2689                 skip "client does not have LU-3338 fix"
2690
2691         # 72 bytes is the minimum space required to store striping
2692         # information for a file striped across one OST:
2693         # (sizeof(struct lov_user_md_v3) +
2694         #  sizeof(struct lov_user_ost_data_v1))
2695         local min_easize=72
2696         $LCTL set_param -n llite.*.default_easize $min_easize ||
2697                 error "lctl set_param failed"
2698         local easize=$($LCTL get_param -n llite.*.default_easize)
2699
2700         [ $easize -eq $min_easize ] ||
2701                 error "failed to set default_easize"
2702
2703         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2704                 error "setstripe failed"
2705         # In order to ensure stat() call actually talks to MDS we need to
2706         # do something drastic to this file to shake off all lock, e.g.
2707         # rename it (kills lookup lock forcing cache cleaning)
2708         mv $DIR/$tfile $DIR/${tfile}-1
2709         ls -l $DIR/${tfile}-1
2710         rm $DIR/${tfile}-1
2711
2712         easize=$($LCTL get_param -n llite.*.default_easize)
2713
2714         [ $easize -gt $min_easize ] ||
2715                 error "default_easize not updated"
2716 }
2717 run_test 27E "check that default extended attribute size properly increases"
2718
2719 test_27F() { # LU-5346/LU-7975
2720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2721         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2722         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2723                 skip "Need MDS version at least 2.8.51"
2724         remote_ost_nodsh && skip "remote OST with nodsh"
2725
2726         test_mkdir $DIR/$tdir
2727         rm -f $DIR/$tdir/f0
2728         $LFS setstripe -c 2 $DIR/$tdir
2729
2730         # stop all OSTs to reproduce situation for LU-7975 ticket
2731         for num in $(seq $OSTCOUNT); do
2732                 stop ost$num
2733         done
2734
2735         # open/create f0 with O_LOV_DELAY_CREATE
2736         # truncate f0 to a non-0 size
2737         # close
2738         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2739
2740         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2741         # open/write it again to force delayed layout creation
2742         cat /etc/hosts > $DIR/$tdir/f0 &
2743         catpid=$!
2744
2745         # restart OSTs
2746         for num in $(seq $OSTCOUNT); do
2747                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2748                         error "ost$num failed to start"
2749         done
2750
2751         wait $catpid || error "cat failed"
2752
2753         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2754         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2755                 error "wrong stripecount"
2756
2757 }
2758 run_test 27F "Client resend delayed layout creation with non-zero size"
2759
2760 test_27G() { #LU-10629
2761         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2762                 skip "Need MDS version at least 2.11.51"
2763         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2764         remote_mds_nodsh && skip "remote MDS with nodsh"
2765         local POOL=${POOL:-testpool}
2766         local ostrange="0 0 1"
2767
2768         test_mkdir $DIR/$tdir
2769         touch $DIR/$tdir/$tfile.nopool
2770         pool_add $POOL || error "pool_add failed"
2771         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2772         $LFS setstripe -p $POOL $DIR/$tdir
2773
2774         local pool=$($LFS getstripe -p $DIR/$tdir)
2775
2776         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2777         touch $DIR/$tdir/$tfile.default
2778         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2779         $LFS find $DIR/$tdir -type f --pool $POOL
2780         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2781         [[ "$found" == "2" ]] ||
2782                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2783
2784         $LFS setstripe -d $DIR/$tdir
2785
2786         pool=$($LFS getstripe -p -d $DIR/$tdir)
2787
2788         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2789 }
2790 run_test 27G "Clear OST pool from stripe"
2791
2792 test_27H() {
2793         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2794                 skip "Need MDS version newer than 2.11.54"
2795         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2796         test_mkdir $DIR/$tdir
2797         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2798         touch $DIR/$tdir/$tfile
2799         $LFS getstripe -c $DIR/$tdir/$tfile
2800         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2801                 error "two-stripe file doesn't have two stripes"
2802
2803         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2804         $LFS getstripe -y $DIR/$tdir/$tfile
2805         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2806              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2807                 error "expected l_ost_idx: [02]$ not matched"
2808
2809         # make sure ost list has been cleared
2810         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2811         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2812                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2813         touch $DIR/$tdir/f3
2814         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2815 }
2816 run_test 27H "Set specific OSTs stripe"
2817
2818 test_27I() {
2819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2820         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2821         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2822                 skip "Need MDS version newer than 2.12.52"
2823         local pool=$TESTNAME
2824         local ostrange="1 1 1"
2825
2826         save_layout_restore_at_exit $MOUNT
2827         $LFS setstripe -c 2 -i 0 $MOUNT
2828         pool_add $pool || error "pool_add failed"
2829         pool_add_targets $pool $ostrange ||
2830                 error "pool_add_targets failed"
2831         test_mkdir $DIR/$tdir
2832         $LFS setstripe -p $pool $DIR/$tdir
2833         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2834         $LFS getstripe $DIR/$tdir/$tfile
2835 }
2836 run_test 27I "check that root dir striping does not break parent dir one"
2837
2838 test_27J() {
2839         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2840                 skip "Need MDS version newer than 2.12.51"
2841
2842         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2843         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2844         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2845            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2846                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2847
2848         test_mkdir $DIR/$tdir
2849         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2850         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2851
2852         # create foreign file (raw way)
2853         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2854                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2855
2856         ! $LFS setstripe --foreign --flags foo \
2857                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2858                         error "creating $tfile with '--flags foo' should fail"
2859
2860         ! $LFS setstripe --foreign --flags 0xffffffff \
2861                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2862                         error "creating $tfile w/ 0xffffffff flags should fail"
2863
2864         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2865                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2866
2867         # verify foreign file (raw way)
2868         parse_foreign_file -f $DIR/$tdir/$tfile |
2869                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2870                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2871         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2872                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2873         parse_foreign_file -f $DIR/$tdir/$tfile |
2874                 grep "lov_foreign_size: 73" ||
2875                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2876         parse_foreign_file -f $DIR/$tdir/$tfile |
2877                 grep "lov_foreign_type: 1" ||
2878                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2879         parse_foreign_file -f $DIR/$tdir/$tfile |
2880                 grep "lov_foreign_flags: 0x0000DA08" ||
2881                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2882         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2883                 grep "lov_foreign_value: 0x" |
2884                 sed -e 's/lov_foreign_value: 0x//')
2885         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2886         [[ $lov = ${lov2// /} ]] ||
2887                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2888
2889         # create foreign file (lfs + API)
2890         $LFS setstripe --foreign=none --flags 0xda08 \
2891                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2892                 error "$DIR/$tdir/${tfile}2: create failed"
2893
2894         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2895                 grep "lfm_magic:.*0x0BD70BD0" ||
2896                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2897         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2898         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2899                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2900         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2901                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2902         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2903                 grep "lfm_flags:.*0x0000DA08" ||
2904                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2905         $LFS getstripe $DIR/$tdir/${tfile}2 |
2906                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2907                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2908
2909         # modify striping should fail
2910         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2911                 error "$DIR/$tdir/$tfile: setstripe should fail"
2912         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2913                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2914
2915         # R/W should fail
2916         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2917         cat $DIR/$tdir/${tfile}2 &&
2918                 error "$DIR/$tdir/${tfile}2: read should fail"
2919         cat /etc/passwd > $DIR/$tdir/$tfile &&
2920                 error "$DIR/$tdir/$tfile: write should fail"
2921         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2922                 error "$DIR/$tdir/${tfile}2: write should fail"
2923
2924         # chmod should work
2925         chmod 222 $DIR/$tdir/$tfile ||
2926                 error "$DIR/$tdir/$tfile: chmod failed"
2927         chmod 222 $DIR/$tdir/${tfile}2 ||
2928                 error "$DIR/$tdir/${tfile}2: chmod failed"
2929
2930         # chown should work
2931         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2932                 error "$DIR/$tdir/$tfile: chown failed"
2933         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2934                 error "$DIR/$tdir/${tfile}2: chown failed"
2935
2936         # rename should work
2937         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2938                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2939         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2940                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2941
2942         #remove foreign file
2943         rm $DIR/$tdir/${tfile}.new ||
2944                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2945         rm $DIR/$tdir/${tfile}2.new ||
2946                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2947 }
2948 run_test 27J "basic ops on file with foreign LOV"
2949
2950 test_27K() {
2951         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2952                 skip "Need MDS version newer than 2.12.49"
2953
2954         test_mkdir $DIR/$tdir
2955         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2956         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2957
2958         # create foreign dir (raw way)
2959         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2960                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2961
2962         ! $LFS setdirstripe --foreign --flags foo \
2963                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2964                         error "creating $tdir with '--flags foo' should fail"
2965
2966         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2967                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2968                         error "creating $tdir w/ 0xffffffff flags should fail"
2969
2970         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2971                 error "create_foreign_dir FAILED"
2972
2973         # verify foreign dir (raw way)
2974         parse_foreign_dir -d $DIR/$tdir/$tdir |
2975                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2976                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2977         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2978                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2979         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2980                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2981         parse_foreign_dir -d $DIR/$tdir/$tdir |
2982                 grep "lmv_foreign_flags: 55813$" ||
2983                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2984         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2985                 grep "lmv_foreign_value: 0x" |
2986                 sed 's/lmv_foreign_value: 0x//')
2987         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2988                 sed 's/ //g')
2989         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2990
2991         # create foreign dir (lfs + API)
2992         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2993                 $DIR/$tdir/${tdir}2 ||
2994                 error "$DIR/$tdir/${tdir}2: create failed"
2995
2996         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2997
2998         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2999                 grep "lfm_magic:.*0x0CD50CD0" ||
3000                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
3001         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
3002         # - sizeof(lfm_type) - sizeof(lfm_flags)
3003         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
3004                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
3005         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
3006                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
3007         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3008                 grep "lfm_flags:.*0x0000DA05" ||
3009                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
3010         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
3011                 grep "lfm_value.*${uuid1}@${uuid2}" ||
3012                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
3013
3014         # file create in dir should fail
3015         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3016         touch $DIR/$tdir/${tdir}2/$tfile &&
3017                 error "$DIR/${tdir}2: file create should fail"
3018
3019         # chmod should work
3020         chmod 777 $DIR/$tdir/$tdir ||
3021                 error "$DIR/$tdir: chmod failed"
3022         chmod 777 $DIR/$tdir/${tdir}2 ||
3023                 error "$DIR/${tdir}2: chmod failed"
3024
3025         # chown should work
3026         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3027                 error "$DIR/$tdir: chown failed"
3028         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3029                 error "$DIR/${tdir}2: chown failed"
3030
3031         # rename should work
3032         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3033                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3034         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3035                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3036
3037         #remove foreign dir
3038         rmdir $DIR/$tdir/${tdir}.new ||
3039                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3040         rmdir $DIR/$tdir/${tdir}2.new ||
3041                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3042 }
3043 run_test 27K "basic ops on dir with foreign LMV"
3044
3045 test_27L() {
3046         remote_mds_nodsh && skip "remote MDS with nodsh"
3047
3048         local POOL=${POOL:-$TESTNAME}
3049
3050         pool_add $POOL || error "pool_add failed"
3051
3052         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3053                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3054                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3055 }
3056 run_test 27L "lfs pool_list gives correct pool name"
3057
3058 test_27M() {
3059         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3060                 skip "Need MDS version >= than 2.12.57"
3061         remote_mds_nodsh && skip "remote MDS with nodsh"
3062         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3063
3064         # Set default striping on directory
3065         local setcount=4
3066         local stripe_opt
3067         local mdts=$(comma_list $(mdts_nodes))
3068
3069         # if we run against a 2.12 server which lacks overstring support
3070         # then the connect_flag will not report overstriping, even if client
3071         # is 2.14+
3072         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3073                 stripe_opt="-C $setcount"
3074         elif (( $OSTCOUNT >= $setcount )); then
3075                 stripe_opt="-c $setcount"
3076         else
3077                 skip "server does not support overstriping"
3078         fi
3079
3080         test_mkdir $DIR/$tdir
3081
3082         # Validate existing append_* params and ensure restore
3083         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3084         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3085         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3086
3087         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3088         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3089         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3090
3091         $LFS setstripe $stripe_opt $DIR/$tdir
3092
3093         echo 1 > $DIR/$tdir/${tfile}.1
3094         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3095         (( $count == $setcount )) ||
3096                 error "(1) stripe count $count, should be $setcount"
3097
3098         local appendcount=$orig_count
3099         echo 1 >> $DIR/$tdir/${tfile}.2_append
3100         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3101         (( $count == $appendcount )) ||
3102                 error "(2)stripe count $count, should be $appendcount for append"
3103
3104         # Disable O_APPEND striping, verify it works
3105         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3106
3107         # Should now get the default striping, which is 4
3108         setcount=4
3109         echo 1 >> $DIR/$tdir/${tfile}.3_append
3110         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3111         (( $count == $setcount )) ||
3112                 error "(3) stripe count $count, should be $setcount"
3113
3114         # Try changing the stripe count for append files
3115         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3116
3117         # Append striping is now 2 (directory default is still 4)
3118         appendcount=2
3119         echo 1 >> $DIR/$tdir/${tfile}.4_append
3120         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3121         (( $count == $appendcount )) ||
3122                 error "(4) stripe count $count, should be $appendcount for append"
3123
3124         # Test append stripe count of -1
3125         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3126         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3127                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3128                 touch $DIR/$tdir/$tfile.specific.{1..128}
3129         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3130
3131         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3132         appendcount=$OSTCOUNT
3133         echo 1 >> $DIR/$tdir/${tfile}.5
3134         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3135         (( $count == $appendcount )) ||
3136                 error "(5) stripe count $count, should be $appendcount for append"
3137
3138         # Set append striping back to default of 1
3139         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3140
3141         # Try a new default striping, PFL + DOM
3142         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3143
3144         # Create normal DOM file, DOM returns stripe count == 0
3145         setcount=0
3146         touch $DIR/$tdir/${tfile}.6
3147         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3148         (( $count == $setcount )) ||
3149                 error "(6) stripe count $count, should be $setcount"
3150
3151         # Show
3152         appendcount=1
3153         echo 1 >> $DIR/$tdir/${tfile}.7_append
3154         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3155         (( $count == $appendcount )) ||
3156                 error "(7) stripe count $count, should be $appendcount for append"
3157
3158         # Clean up DOM layout
3159         $LFS setstripe -d $DIR/$tdir
3160
3161         save_layout_restore_at_exit $MOUNT
3162         # Now test that append striping works when layout is from root
3163         $LFS setstripe -c 2 $MOUNT
3164         # Make a special directory for this
3165         mkdir $DIR/${tdir}/${tdir}.2
3166
3167         # Verify for normal file
3168         setcount=2
3169         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3170         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3171         (( $count == $setcount )) ||
3172                 error "(8) stripe count $count, should be $setcount"
3173
3174         appendcount=1
3175         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3176         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3177         (( $count == $appendcount )) ||
3178                 error "(9) stripe count $count, should be $appendcount for append"
3179
3180         # Now test O_APPEND striping with pools
3181         pool_add $TESTNAME || error "pool creation failed"
3182         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3183         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3184
3185         echo 1 >> $DIR/$tdir/${tfile}.10_append
3186
3187         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3188         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3189
3190         # Check that count is still correct
3191         appendcount=1
3192         echo 1 >> $DIR/$tdir/${tfile}.11_append
3193         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3194         (( $count == $appendcount )) ||
3195                 error "(11) stripe count $count, should be $appendcount for append"
3196
3197         # Disable O_APPEND stripe count, verify pool works separately
3198         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3199
3200         echo 1 >> $DIR/$tdir/${tfile}.12_append
3201
3202         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3203         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3204
3205         # Remove pool setting, verify it's not applied
3206         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3207
3208         echo 1 >> $DIR/$tdir/${tfile}.13_append
3209
3210         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3211         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3212 }
3213 run_test 27M "test O_APPEND striping"
3214
3215 test_27N() {
3216         combined_mgs_mds && skip "needs separate MGS/MDT"
3217
3218         pool_add $TESTNAME || error "pool_add failed"
3219         do_facet mgs "$LCTL pool_list $FSNAME" |
3220                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3221                 error "lctl pool_list on MGS failed"
3222 }
3223 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3224
3225 clean_foreign_symlink() {
3226         trap 0
3227         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3228         for i in $DIR/$tdir/* ; do
3229                 $LFS unlink_foreign $i || true
3230         done
3231 }
3232
3233 test_27O() {
3234         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3235                 skip "Need MDS version newer than 2.12.51"
3236
3237         test_mkdir $DIR/$tdir
3238         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3239         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3240
3241         trap clean_foreign_symlink EXIT
3242
3243         # enable foreign_symlink behaviour
3244         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3245
3246         # foreign symlink LOV format is a partial path by default
3247
3248         # create foreign file (lfs + API)
3249         $LFS setstripe --foreign=symlink --flags 0xda05 \
3250                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3251                 error "$DIR/$tdir/${tfile}: create failed"
3252
3253         $LFS getstripe -v $DIR/$tdir/${tfile} |
3254                 grep "lfm_magic:.*0x0BD70BD0" ||
3255                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3256         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3257                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3258         $LFS getstripe -v $DIR/$tdir/${tfile} |
3259                 grep "lfm_flags:.*0x0000DA05" ||
3260                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3261         $LFS getstripe $DIR/$tdir/${tfile} |
3262                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3263                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3264
3265         # modify striping should fail
3266         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3267                 error "$DIR/$tdir/$tfile: setstripe should fail"
3268
3269         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3270         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3271         cat /etc/passwd > $DIR/$tdir/$tfile &&
3272                 error "$DIR/$tdir/$tfile: write should fail"
3273
3274         # rename should succeed
3275         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3276                 error "$DIR/$tdir/$tfile: rename has failed"
3277
3278         #remove foreign_symlink file should fail
3279         rm $DIR/$tdir/${tfile}.new &&
3280                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3281
3282         #test fake symlink
3283         mkdir /tmp/${uuid1} ||
3284                 error "/tmp/${uuid1}: mkdir has failed"
3285         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3286                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3287         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3288         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3289                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3290         #read should succeed now
3291         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3292                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3293         #write should succeed now
3294         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3295                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3296         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3297                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3298         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3299                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3300
3301         #check that getstripe still works
3302         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3303                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3304
3305         # chmod should still succeed
3306         chmod 644 $DIR/$tdir/${tfile}.new ||
3307                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3308
3309         # chown should still succeed
3310         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3311                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3312
3313         # rename should still succeed
3314         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3315                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3316
3317         #remove foreign_symlink file should still fail
3318         rm $DIR/$tdir/${tfile} &&
3319                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3320
3321         #use special ioctl() to unlink foreign_symlink file
3322         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3323                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3324
3325 }
3326 run_test 27O "basic ops on foreign file of symlink type"
3327
3328 test_27P() {
3329         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3330                 skip "Need MDS version newer than 2.12.49"
3331
3332         test_mkdir $DIR/$tdir
3333         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3334         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3335
3336         trap clean_foreign_symlink EXIT
3337
3338         # enable foreign_symlink behaviour
3339         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3340
3341         # foreign symlink LMV format is a partial path by default
3342
3343         # create foreign dir (lfs + API)
3344         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3345                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3346                 error "$DIR/$tdir/${tdir}: create failed"
3347
3348         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3349
3350         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3351                 grep "lfm_magic:.*0x0CD50CD0" ||
3352                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3353         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3354                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3355         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3356                 grep "lfm_flags:.*0x0000DA05" ||
3357                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3358         $LFS getdirstripe $DIR/$tdir/${tdir} |
3359                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3360                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3361
3362         # file create in dir should fail
3363         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3364         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3365
3366         # rename should succeed
3367         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3368                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3369
3370         #remove foreign_symlink dir should fail
3371         rmdir $DIR/$tdir/${tdir}.new &&
3372                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3373
3374         #test fake symlink
3375         mkdir -p /tmp/${uuid1}/${uuid2} ||
3376                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3377         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3378                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3379         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3380         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3381                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3382         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3383                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3384
3385         #check that getstripe fails now that foreign_symlink enabled
3386         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3387                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3388
3389         # file create in dir should work now
3390         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3391                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3392         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3393                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3394         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3395                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3396
3397         # chmod should still succeed
3398         chmod 755 $DIR/$tdir/${tdir}.new ||
3399                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3400
3401         # chown should still succeed
3402         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3403                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3404
3405         # rename should still succeed
3406         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3407                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3408
3409         #remove foreign_symlink dir should still fail
3410         rmdir $DIR/$tdir/${tdir} &&
3411                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3412
3413         #use special ioctl() to unlink foreign_symlink file
3414         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3415                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3416
3417         #created file should still exist
3418         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3419                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3420         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3421                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3422 }
3423 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3424
3425 test_27Q() {
3426         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3427         stack_trap "rm -f $TMP/$tfile*"
3428
3429         test_mkdir $DIR/$tdir-1
3430         test_mkdir $DIR/$tdir-2
3431
3432         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3433         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3434
3435         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3436         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3437
3438         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3439         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3440
3441         # Create some bad symlinks and ensure that we don't loop
3442         # forever or something. These should return ELOOP (40) and
3443         # ENOENT (2) but I don't want to test for that because there's
3444         # always some weirdo architecture that needs to ruin
3445         # everything by defining these error numbers differently.
3446
3447         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3448         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3449
3450         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3451         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3452
3453         return 0
3454 }
3455 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3456
3457 test_27R() {
3458         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3459                 skip "need MDS 2.14.55 or later"
3460         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3461
3462         local testdir="$DIR/$tdir"
3463         test_mkdir -p $testdir
3464         stack_trap "rm -rf $testdir"
3465         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3466
3467         local f1="$testdir/f1"
3468         touch $f1 || error "failed to touch $f1"
3469         local count=$($LFS getstripe -c $f1)
3470         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3471
3472         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3473         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3474
3475         local maxcount=$(($OSTCOUNT - 1))
3476         local mdts=$(comma_list $(mdts_nodes))
3477         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3478         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3479
3480         local f2="$testdir/f2"
3481         touch $f2 || error "failed to touch $f2"
3482         local count=$($LFS getstripe -c $f2)
3483         (( $count == $maxcount )) || error "wrong stripe count"
3484 }
3485 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3486
3487 test_27T() {
3488         [ $(facet_host client) == $(facet_host ost1) ] &&
3489                 skip "need ost1 and client on different nodes"
3490
3491 #define OBD_FAIL_OSC_NO_GRANT            0x411
3492         $LCTL set_param fail_loc=0x20000411 fail_val=1
3493 #define OBD_FAIL_OST_ENOSPC              0x215
3494         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3495         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3496         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3497                 error "multiop failed"
3498 }
3499 run_test 27T "no eio on close on partial write due to enosp"
3500
3501 test_27U() {
3502         local dir=$DIR/$tdir
3503         local file=$dir/$tfile
3504         local append_pool=${TESTNAME}-append
3505         local normal_pool=${TESTNAME}-normal
3506         local pool
3507         local stripe_count
3508         local stripe_count2
3509         local mdts=$(comma_list $(mdts_nodes))
3510
3511         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3512                 skip "Need MDS version at least 2.15.51 for append pool feature"
3513
3514         # Validate existing append_* params and ensure restore
3515         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3516         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3517         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3518
3519         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3520         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3521         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3522
3523         pool_add $append_pool || error "pool creation failed"
3524         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3525
3526         pool_add $normal_pool || error "pool creation failed"
3527         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3528
3529         test_mkdir $dir
3530         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3531
3532         echo XXX >> $file.1
3533         $LFS getstripe $file.1
3534
3535         pool=$($LFS getstripe -p $file.1)
3536         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3537
3538         stripe_count2=$($LFS getstripe -c $file.1)
3539         ((stripe_count2 == stripe_count)) ||
3540                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3541
3542         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3543
3544         echo XXX >> $file.2
3545         $LFS getstripe $file.2
3546
3547         pool=$($LFS getstripe -p $file.2)
3548         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3549
3550         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3551
3552         echo XXX >> $file.3
3553         $LFS getstripe $file.3
3554
3555         stripe_count2=$($LFS getstripe -c $file.3)
3556         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3557 }
3558 run_test 27U "append pool and stripe count work with composite default layout"
3559
3560 test_27V() {
3561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3562         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3563
3564         local dir=$DIR/$tdir
3565         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3566         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3567         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3568         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3569         local pid
3570
3571         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3572
3573         do_facet mds1 $LCTL set_param $lod_param=0
3574         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3575
3576         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3577         stack_trap "rm -rf $dir"
3578
3579         # exercise race in LU-16981 with deactivating OST while creating a file
3580         (
3581                 while true; do
3582                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3583                         sleep 0.1
3584                         do_facet mds1 \
3585                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3586                 done
3587         ) &
3588
3589         pid=$!
3590         stack_trap "kill -9 $pid"
3591
3592         # errors here are OK so ignore them (just don't want to crash)
3593         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3594
3595         return 0
3596 }
3597 run_test 27V "creating widely striped file races with deactivating OST"
3598
3599 # createtest also checks that device nodes are created and
3600 # then visible correctly (#2091)
3601 test_28() { # bug 2091
3602         test_mkdir $DIR/d28
3603         $CREATETEST $DIR/d28/ct || error "createtest failed"
3604 }
3605 run_test 28 "create/mknod/mkdir with bad file types ============"
3606
3607 test_29() {
3608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3609
3610         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3611                 disable_opencache
3612                 stack_trap "restore_opencache"
3613         }
3614
3615         sync; sleep 1; sync # flush out any dirty pages from previous tests
3616         cancel_lru_locks
3617         test_mkdir $DIR/d29
3618         touch $DIR/d29/foo
3619         log 'first d29'
3620         ls -l $DIR/d29
3621
3622         local locks_orig=$(total_used_locks mdc)
3623         (( $locks_orig != 0 )) || error "No mdc lock count"
3624
3625         local locks_unused_orig=$(total_unused_locks mdc)
3626
3627         log 'second d29'
3628         ls -l $DIR/d29
3629         log 'done'
3630
3631         local locks_current=$(total_used_locks mdc)
3632
3633         local locks_unused_current=$(total_unused_locks mdc)
3634
3635         if (( $locks_current > $locks_orig )); then
3636                 $LCTL set_param -n ldlm.dump_namespaces ""
3637                 error "CURRENT: $locks_current > $locks_orig"
3638         fi
3639         if (( $locks_unused_current > $locks_unused_orig )); then
3640                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3641         fi
3642 }
3643 run_test 29 "IT_GETATTR regression  ============================"
3644
3645 test_30a() { # was test_30
3646         cp $(which ls) $DIR || cp /bin/ls $DIR
3647         $DIR/ls / || error "Can't execute binary from lustre"
3648         rm $DIR/ls
3649 }
3650 run_test 30a "execute binary from Lustre (execve) =============="
3651
3652 test_30b() {
3653         cp `which ls` $DIR || cp /bin/ls $DIR
3654         chmod go+rx $DIR/ls
3655         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3656         rm $DIR/ls
3657 }
3658 run_test 30b "execute binary from Lustre as non-root ==========="
3659
3660 test_30c() { # b=22376
3661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3662
3663         cp $(which ls) $DIR || cp /bin/ls $DIR
3664         chmod a-rw $DIR/ls
3665         cancel_lru_locks mdc
3666         cancel_lru_locks osc
3667         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3668         rm -f $DIR/ls
3669 }
3670 run_test 30c "execute binary from Lustre without read perms ===="
3671
3672 test_30d() {
3673         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3674
3675         for i in {1..10}; do
3676                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3677                 local PID=$!
3678                 sleep 1
3679                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3680                 wait $PID || error "executing dd from Lustre failed"
3681                 rm -f $DIR/$tfile
3682         done
3683
3684         rm -f $DIR/dd
3685 }
3686 run_test 30d "execute binary from Lustre while clear locks"
3687
3688 test_31a() {
3689         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3690         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3691 }
3692 run_test 31a "open-unlink file =================================="
3693
3694 test_31b() {
3695         touch $DIR/f31 || error "touch $DIR/f31 failed"
3696         ln $DIR/f31 $DIR/f31b || error "ln failed"
3697         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3698         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3699 }
3700 run_test 31b "unlink file with multiple links while open ======="
3701
3702 test_31c() {
3703         touch $DIR/f31 || error "touch $DIR/f31 failed"
3704         ln $DIR/f31 $DIR/f31c || error "ln failed"
3705         multiop_bg_pause $DIR/f31 O_uc ||
3706                 error "multiop_bg_pause for $DIR/f31 failed"
3707         MULTIPID=$!
3708         $MULTIOP $DIR/f31c Ouc
3709         kill -USR1 $MULTIPID
3710         wait $MULTIPID
3711 }
3712 run_test 31c "open-unlink file with multiple links ============="
3713
3714 test_31d() {
3715         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3716         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3717 }
3718 run_test 31d "remove of open directory ========================="
3719
3720 test_31e() { # bug 2904
3721         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3722 }
3723 run_test 31e "remove of open non-empty directory ==============="
3724
3725 test_31f() { # bug 4554
3726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3727
3728         set -vx
3729         test_mkdir $DIR/d31f
3730         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3731         cp /etc/hosts $DIR/d31f
3732         ls -l $DIR/d31f
3733         $LFS getstripe $DIR/d31f/hosts
3734         multiop_bg_pause $DIR/d31f D_c || return 1
3735         MULTIPID=$!
3736
3737         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3738         test_mkdir $DIR/d31f
3739         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3740         cp /etc/hosts $DIR/d31f
3741         ls -l $DIR/d31f
3742         $LFS getstripe $DIR/d31f/hosts
3743         multiop_bg_pause $DIR/d31f D_c || return 1
3744         MULTIPID2=$!
3745
3746         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3747         wait $MULTIPID || error "first opendir $MULTIPID failed"
3748
3749         sleep 6
3750
3751         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3752         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3753         set +vx
3754 }
3755 run_test 31f "remove of open directory with open-unlink file ==="
3756
3757 test_31g() {
3758         echo "-- cross directory link --"
3759         test_mkdir -c1 $DIR/${tdir}ga
3760         test_mkdir -c1 $DIR/${tdir}gb
3761         touch $DIR/${tdir}ga/f
3762         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3763         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3764         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3765         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3766         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3767 }
3768 run_test 31g "cross directory link==============="
3769
3770 test_31h() {
3771         echo "-- cross directory link --"
3772         test_mkdir -c1 $DIR/${tdir}
3773         test_mkdir -c1 $DIR/${tdir}/dir
3774         touch $DIR/${tdir}/f
3775         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3776         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3777         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3778         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3779         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3780 }
3781 run_test 31h "cross directory link under child==============="
3782
3783 test_31i() {
3784         echo "-- cross directory link --"
3785         test_mkdir -c1 $DIR/$tdir
3786         test_mkdir -c1 $DIR/$tdir/dir
3787         touch $DIR/$tdir/dir/f
3788         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3789         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3790         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3791         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3792         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3793 }
3794 run_test 31i "cross directory link under parent==============="
3795
3796 test_31j() {
3797         test_mkdir -c1 -p $DIR/$tdir
3798         test_mkdir -c1 -p $DIR/$tdir/dir1
3799         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3800         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3801         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3802         return 0
3803 }
3804 run_test 31j "link for directory"
3805
3806 test_31k() {
3807         test_mkdir -c1 -p $DIR/$tdir
3808         touch $DIR/$tdir/s
3809         touch $DIR/$tdir/exist
3810         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3811         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3812         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3813         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3814         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3815         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3816         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3817         return 0
3818 }
3819 run_test 31k "link to file: the same, non-existing, dir"
3820
3821 test_31l() {
3822         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3823
3824         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3825         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3826                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3827
3828         touch $DIR/$tfile || error "create failed"
3829         mkdir $DIR/$tdir || error "mkdir failed"
3830         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3831 }
3832 run_test 31l "link to file: target dir has trailing slash"
3833
3834 test_31m() {
3835         mkdir $DIR/d31m
3836         touch $DIR/d31m/s
3837         mkdir $DIR/d31m2
3838         touch $DIR/d31m2/exist
3839         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3840         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3841         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3842         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3843         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3844         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3845         return 0
3846 }
3847 run_test 31m "link to file: the same, non-existing, dir"
3848
3849 test_31n() {
3850         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3851         nlink=$(stat --format=%h $DIR/$tfile)
3852         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3853         local fd=$(free_fd)
3854         local cmd="exec $fd<$DIR/$tfile"
3855         eval $cmd
3856         cmd="exec $fd<&-"
3857         trap "eval $cmd" EXIT
3858         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3859         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3860         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3861         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3862         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3863         eval $cmd
3864 }
3865 run_test 31n "check link count of unlinked file"
3866
3867 link_one() {
3868         local tempfile=$(mktemp $1_XXXXXX)
3869         link $tempfile $1 2> /dev/null &&
3870                 echo "$BASHPID: link $tempfile to $1 succeeded"
3871         unlink $tempfile
3872 }
3873
3874 test_31o() { # LU-2901
3875         test_mkdir $DIR/$tdir
3876         for LOOP in $(seq 100); do
3877                 rm -f $DIR/$tdir/$tfile*
3878                 for THREAD in $(seq 8); do
3879                         link_one $DIR/$tdir/$tfile.$LOOP &
3880                 done
3881                 wait
3882                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3883                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3884                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3885                         break || true
3886         done
3887 }
3888 run_test 31o "duplicate hard links with same filename"
3889
3890 test_31p() {
3891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3892
3893         test_mkdir $DIR/$tdir
3894         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3895         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3896
3897         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3898                 error "open unlink test1 failed"
3899         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3900                 error "open unlink test2 failed"
3901
3902         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3903                 error "test1 still exists"
3904         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3905                 error "test2 still exists"
3906 }
3907 run_test 31p "remove of open striped directory"
3908
3909 test_31q() {
3910         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3911
3912         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3913         index=$($LFS getdirstripe -i $DIR/$tdir)
3914         [ $index -eq 3 ] || error "first stripe index $index != 3"
3915         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3916         [ $index -eq 1 ] || error "second stripe index $index != 1"
3917
3918         # when "-c <stripe_count>" is set, the number of MDTs specified after
3919         # "-i" should equal to the stripe count
3920         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3921 }
3922 run_test 31q "create striped directory on specific MDTs"
3923
3924 #LU-14949
3925 test_31r() {
3926         touch $DIR/$tfile.target
3927         touch $DIR/$tfile.source
3928
3929         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3930         $LCTL set_param fail_loc=0x1419 fail_val=3
3931         cat $DIR/$tfile.target &
3932         CATPID=$!
3933
3934         # Guarantee open is waiting before we get here
3935         sleep 1
3936         mv $DIR/$tfile.source $DIR/$tfile.target
3937
3938         wait $CATPID
3939         RC=$?
3940         if [[ $RC -ne 0 ]]; then
3941                 error "open with cat failed, rc=$RC"
3942         fi
3943 }
3944 run_test 31r "open-rename(replace) race"
3945
3946 cleanup_test32_mount() {
3947         local rc=0
3948         trap 0
3949         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3950         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3951         losetup -d $loopdev || true
3952         rm -rf $DIR/$tdir
3953         return $rc
3954 }
3955
3956 test_32a() {
3957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3958
3959         echo "== more mountpoints and symlinks ================="
3960         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3961         trap cleanup_test32_mount EXIT
3962         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3963         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3964                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3965         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3966                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3967         cleanup_test32_mount
3968 }
3969 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3970
3971 test_32b() {
3972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3973
3974         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3975         trap cleanup_test32_mount EXIT
3976         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3977         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3978                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3979         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3980                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3981         cleanup_test32_mount
3982 }
3983 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3984
3985 test_32c() {
3986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3987
3988         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3989         trap cleanup_test32_mount EXIT
3990         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3991         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3992                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3993         test_mkdir -p $DIR/$tdir/d2/test_dir
3994         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3995                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3996         cleanup_test32_mount
3997 }
3998 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3999
4000 test_32d() {
4001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4002
4003         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4004         trap cleanup_test32_mount EXIT
4005         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4006         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4007                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4008         test_mkdir -p $DIR/$tdir/d2/test_dir
4009         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4010                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
4011         cleanup_test32_mount
4012 }
4013 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
4014
4015 test_32e() {
4016         rm -fr $DIR/$tdir
4017         test_mkdir -p $DIR/$tdir/tmp
4018         local tmp_dir=$DIR/$tdir/tmp
4019         ln -s $DIR/$tdir $tmp_dir/symlink11
4020         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4021         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4022         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4023 }
4024 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4025
4026 test_32f() {
4027         rm -fr $DIR/$tdir
4028         test_mkdir -p $DIR/$tdir/tmp
4029         local tmp_dir=$DIR/$tdir/tmp
4030         ln -s $DIR/$tdir $tmp_dir/symlink11
4031         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4032         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4033         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4034 }
4035 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4036
4037 test_32g() {
4038         local tmp_dir=$DIR/$tdir/tmp
4039         test_mkdir -p $tmp_dir
4040         test_mkdir $DIR/${tdir}2
4041         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4042         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4043         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4044         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4045         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4046         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4047 }
4048 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4049
4050 test_32h() {
4051         rm -fr $DIR/$tdir $DIR/${tdir}2
4052         tmp_dir=$DIR/$tdir/tmp
4053         test_mkdir -p $tmp_dir
4054         test_mkdir $DIR/${tdir}2
4055         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4056         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4057         ls $tmp_dir/symlink12 || error "listing symlink12"
4058         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4059 }
4060 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4061
4062 test_32i() {
4063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4064
4065         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4066         trap cleanup_test32_mount EXIT
4067         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4068         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4069                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4070         touch $DIR/$tdir/test_file
4071         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4072                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4073         cleanup_test32_mount
4074 }
4075 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4076
4077 test_32j() {
4078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4079
4080         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4081         trap cleanup_test32_mount EXIT
4082         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4083         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4084                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4085         touch $DIR/$tdir/test_file
4086         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4087                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4088         cleanup_test32_mount
4089 }
4090 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4091
4092 test_32k() {
4093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4094
4095         rm -fr $DIR/$tdir
4096         trap cleanup_test32_mount EXIT
4097         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4098         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4099                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4100         test_mkdir -p $DIR/$tdir/d2
4101         touch $DIR/$tdir/d2/test_file || error "touch failed"
4102         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4103                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4104         cleanup_test32_mount
4105 }
4106 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4107
4108 test_32l() {
4109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4110
4111         rm -fr $DIR/$tdir
4112         trap cleanup_test32_mount EXIT
4113         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4114         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4115                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4116         test_mkdir -p $DIR/$tdir/d2
4117         touch $DIR/$tdir/d2/test_file || error "touch failed"
4118         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4119                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4120         cleanup_test32_mount
4121 }
4122 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4123
4124 test_32m() {
4125         rm -fr $DIR/d32m
4126         test_mkdir -p $DIR/d32m/tmp
4127         TMP_DIR=$DIR/d32m/tmp
4128         ln -s $DIR $TMP_DIR/symlink11
4129         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4130         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4131                 error "symlink11 not a link"
4132         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4133                 error "symlink01 not a link"
4134 }
4135 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4136
4137 test_32n() {
4138         rm -fr $DIR/d32n
4139         test_mkdir -p $DIR/d32n/tmp
4140         TMP_DIR=$DIR/d32n/tmp
4141         ln -s $DIR $TMP_DIR/symlink11
4142         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4143         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4144         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4145 }
4146 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4147
4148 test_32o() {
4149         touch $DIR/$tfile
4150         test_mkdir -p $DIR/d32o/tmp
4151         TMP_DIR=$DIR/d32o/tmp
4152         ln -s $DIR/$tfile $TMP_DIR/symlink12
4153         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4154         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4155                 error "symlink12 not a link"
4156         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4157         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4158                 error "$DIR/d32o/tmp/symlink12 not file type"
4159         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4160                 error "$DIR/d32o/symlink02 not file type"
4161 }
4162 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4163
4164 test_32p() {
4165         log 32p_1
4166         rm -fr $DIR/d32p
4167         log 32p_2
4168         rm -f $DIR/$tfile
4169         log 32p_3
4170         touch $DIR/$tfile
4171         log 32p_4
4172         test_mkdir -p $DIR/d32p/tmp
4173         log 32p_5
4174         TMP_DIR=$DIR/d32p/tmp
4175         log 32p_6
4176         ln -s $DIR/$tfile $TMP_DIR/symlink12
4177         log 32p_7
4178         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4179         log 32p_8
4180         cat $DIR/d32p/tmp/symlink12 ||
4181                 error "Can't open $DIR/d32p/tmp/symlink12"
4182         log 32p_9
4183         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4184         log 32p_10
4185 }
4186 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4187
4188 test_32q() {
4189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4190
4191         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4192         trap cleanup_test32_mount EXIT
4193         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4194         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4195         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4196                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4197         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4198         cleanup_test32_mount
4199 }
4200 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4201
4202 test_32r() {
4203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4204
4205         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4206         trap cleanup_test32_mount EXIT
4207         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4208         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4209         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4210                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4211         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4212         cleanup_test32_mount
4213 }
4214 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4215
4216 test_33aa() {
4217         rm -f $DIR/$tfile
4218         touch $DIR/$tfile
4219         chmod 444 $DIR/$tfile
4220         chown $RUNAS_ID $DIR/$tfile
4221         log 33_1
4222         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4223         log 33_2
4224 }
4225 run_test 33aa "write file with mode 444 (should return error)"
4226
4227 test_33a() {
4228         rm -fr $DIR/$tdir
4229         test_mkdir $DIR/$tdir
4230         chown $RUNAS_ID $DIR/$tdir
4231         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4232                 error "$RUNAS create $tdir/$tfile failed"
4233         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4234                 error "open RDWR" || true
4235 }
4236 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4237
4238 test_33b() {
4239         rm -fr $DIR/$tdir
4240         test_mkdir $DIR/$tdir
4241         chown $RUNAS_ID $DIR/$tdir
4242         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4243 }
4244 run_test 33b "test open file with malformed flags (No panic)"
4245
4246 test_33c() {
4247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4248         remote_ost_nodsh && skip "remote OST with nodsh"
4249
4250         local ostnum
4251         local ostname
4252         local write_bytes
4253         local all_zeros
4254
4255         all_zeros=true
4256         test_mkdir $DIR/$tdir
4257         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4258
4259         sync
4260         for ostnum in $(seq $OSTCOUNT); do
4261                 # test-framework's OST numbering is one-based, while Lustre's
4262                 # is zero-based
4263                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4264                 # check if at least some write_bytes stats are counted
4265                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4266                               obdfilter.$ostname.stats |
4267                               awk '/^write_bytes/ {print $7}' )
4268                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4269                 if (( ${write_bytes:-0} > 0 )); then
4270                         all_zeros=false
4271                         break
4272                 fi
4273         done
4274
4275         $all_zeros || return 0
4276
4277         # Write four bytes
4278         echo foo > $DIR/$tdir/bar
4279         # Really write them
4280         sync
4281
4282         # Total up write_bytes after writing.  We'd better find non-zeros.
4283         for ostnum in $(seq $OSTCOUNT); do
4284                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4285                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4286                               obdfilter/$ostname/stats |
4287                               awk '/^write_bytes/ {print $7}' )
4288                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4289                 if (( ${write_bytes:-0} > 0 )); then
4290                         all_zeros=false
4291                         break
4292                 fi
4293         done
4294
4295         if $all_zeros; then
4296                 for ostnum in $(seq $OSTCOUNT); do
4297                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4298                         echo "Check write_bytes is in obdfilter.*.stats:"
4299                         do_facet ost$ostnum lctl get_param -n \
4300                                 obdfilter.$ostname.stats
4301                 done
4302                 error "OST not keeping write_bytes stats (b=22312)"
4303         fi
4304 }
4305 run_test 33c "test write_bytes stats"
4306
4307 test_33d() {
4308         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4310
4311         local MDTIDX=1
4312         local remote_dir=$DIR/$tdir/remote_dir
4313
4314         test_mkdir $DIR/$tdir
4315         $LFS mkdir -i $MDTIDX $remote_dir ||
4316                 error "create remote directory failed"
4317
4318         touch $remote_dir/$tfile
4319         chmod 444 $remote_dir/$tfile
4320         chown $RUNAS_ID $remote_dir/$tfile
4321
4322         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4323
4324         chown $RUNAS_ID $remote_dir
4325         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4326                                         error "create" || true
4327         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4328                                     error "open RDWR" || true
4329         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4330 }
4331 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4332
4333 test_33e() {
4334         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4335
4336         mkdir $DIR/$tdir
4337
4338         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4339         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4340         mkdir $DIR/$tdir/local_dir
4341
4342         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4343         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4344         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4345
4346         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4347                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4348
4349         rmdir $DIR/$tdir/* || error "rmdir failed"
4350
4351         umask 777
4352         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4353         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4354         mkdir $DIR/$tdir/local_dir
4355
4356         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4357         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4358         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4359
4360         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4361                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4362
4363         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4364
4365         umask 000
4366         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4367         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4368         mkdir $DIR/$tdir/local_dir
4369
4370         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4371         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4372         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4373
4374         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4375                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4376 }
4377 run_test 33e "mkdir and striped directory should have same mode"
4378
4379 cleanup_33f() {
4380         trap 0
4381         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4382 }
4383
4384 test_33f() {
4385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4386         remote_mds_nodsh && skip "remote MDS with nodsh"
4387
4388         mkdir $DIR/$tdir
4389         chmod go+rwx $DIR/$tdir
4390         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4391         trap cleanup_33f EXIT
4392
4393         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4394                 error "cannot create striped directory"
4395
4396         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4397                 error "cannot create files in striped directory"
4398
4399         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4400                 error "cannot remove files in striped directory"
4401
4402         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4403                 error "cannot remove striped directory"
4404
4405         cleanup_33f
4406 }
4407 run_test 33f "nonroot user can create, access, and remove a striped directory"
4408
4409 test_33g() {
4410         mkdir -p $DIR/$tdir/dir2
4411
4412         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4413         echo $err
4414         [[ $err =~ "exists" ]] || error "Not exists error"
4415 }
4416 run_test 33g "nonroot user create already existing root created file"
4417
4418 sub_33h() {
4419         local hash_type=$1
4420         local count=250
4421
4422         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4423                 error "lfs mkdir -H $hash_type $tdir failed"
4424         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4425
4426         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4427         local index2
4428         local fname
4429
4430         for fname in $DIR/$tdir/$tfile.bak \
4431                      $DIR/$tdir/$tfile.SAV \
4432                      $DIR/$tdir/$tfile.orig \
4433                      $DIR/$tdir/$tfile~; do
4434                 touch $fname || error "touch $fname failed"
4435                 index2=$($LFS getstripe -m $fname)
4436                 (( $index == $index2 )) ||
4437                         error "$fname MDT index mismatch $index != $index2"
4438         done
4439
4440         local failed=0
4441         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4442         local pattern
4443
4444         for pattern in ${patterns[*]}; do
4445                 echo "pattern $pattern"
4446                 fname=$DIR/$tdir/$pattern
4447                 for (( i = 0; i < $count; i++ )); do
4448                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4449                                 error "mktemp $DIR/$tdir/$pattern failed"
4450                         index2=$($LFS getstripe -m $fname)
4451                         (( $index == $index2 )) && continue
4452
4453                         failed=$((failed + 1))
4454                         echo "$fname MDT index mismatch $index != $index2"
4455                 done
4456         done
4457
4458         echo "$failed/$count MDT index mismatches, expect ~2-4"
4459         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4460
4461         local same=0
4462         local expect
4463
4464         # verify that "crush" is still broken with all files on same MDT,
4465         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4466         [[ "$hash_type" == "crush" ]] && expect=$count ||
4467                 expect=$((count / MDSCOUNT))
4468
4469         # crush2 doesn't put all-numeric suffixes on the same MDT,
4470         # filename like $tfile.12345678 should *not* be considered temp
4471         for pattern in ${patterns[*]}; do
4472                 local base=${pattern%%X*}
4473                 local suff=${pattern#$base}
4474
4475                 echo "pattern $pattern"
4476                 for (( i = 0; i < $count; i++ )); do
4477                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4478                         touch $fname || error "touch $fname failed"
4479                         index2=$($LFS getstripe -m $fname)
4480                         (( $index != $index2 )) && continue
4481
4482                         same=$((same + 1))
4483                 done
4484         done
4485
4486         # the number of "bad" hashes is random, as it depends on the random
4487         # filenames generated by "mktemp".  Allow some margin in the results.
4488         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4489         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4490            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4491                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4492         same=0
4493
4494         # crush2 doesn't put suffixes with special characters on the same MDT
4495         # filename like $tfile.txt.1234 should *not* be considered temp
4496         for pattern in ${patterns[*]}; do
4497                 local base=${pattern%%X*}
4498                 local suff=${pattern#$base}
4499
4500                 pattern=$base...${suff/XXX}
4501                 echo "pattern=$pattern"
4502                 for (( i = 0; i < $count; i++ )); do
4503                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4504                                 error "touch $fname failed"
4505                         index2=$($LFS getstripe -m $fname)
4506                         (( $index != $index2 )) && continue
4507
4508                         same=$((same + 1))
4509                 done
4510         done
4511
4512         # the number of "bad" hashes is random, as it depends on the random
4513         # filenames generated by "mktemp".  Allow some margin in the results.
4514         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4515         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4516            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4517                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4518 }
4519
4520 test_33h() {
4521         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4522         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4523                 skip "Need MDS version at least 2.13.50"
4524
4525         sub_33h crush
4526 }
4527 run_test 33h "temp file is located on the same MDT as target (crush)"
4528
4529 test_33hh() {
4530         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4531         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4532         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4533                 skip "Need MDS version at least 2.15.0 for crush2"
4534
4535         sub_33h crush2
4536 }
4537 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4538
4539 test_33i()
4540 {
4541         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4542
4543         local FNAME=$(str_repeat 'f' 250)
4544
4545         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4546         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4547
4548         local count
4549         local total
4550
4551         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4552
4553         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4554
4555         lctl --device %$MDC deactivate
4556         stack_trap "lctl --device %$MDC activate"
4557         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4558         total=$(\ls -l $DIR/$tdir | wc -l)
4559         # "ls -l" will list total in the first line
4560         total=$((total - 1))
4561         (( total + count == 1000 )) ||
4562                 error "ls list $total files, $count files on MDT1"
4563 }
4564 run_test 33i "striped directory can be accessed when one MDT is down"
4565
4566 test_33j() {
4567         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4568
4569         mkdir -p $DIR/$tdir/
4570
4571         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4572                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4573
4574         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4575                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4576
4577         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4578                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4579
4580         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4581                 error "-D was not specified, but still failed"
4582 }
4583 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4584
4585 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4586 test_34a() {
4587         rm -f $DIR/f34
4588         $MCREATE $DIR/f34 || error "mcreate failed"
4589         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4590                 error "getstripe failed"
4591         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4592         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4593                 error "getstripe failed"
4594         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4595                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4596 }
4597 run_test 34a "truncate file that has not been opened ==========="
4598
4599 test_34b() {
4600         [ ! -f $DIR/f34 ] && test_34a
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4602                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4603         $OPENFILE -f O_RDONLY $DIR/f34
4604         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4605                 error "getstripe failed"
4606         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4607                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4608 }
4609 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4610
4611 test_34c() {
4612         [ ! -f $DIR/f34 ] && test_34a
4613         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4614                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4615         $OPENFILE -f O_RDWR $DIR/f34
4616         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4617                 error "$LFS getstripe failed"
4618         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4619                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4620 }
4621 run_test 34c "O_RDWR opening file-with-size works =============="
4622
4623 test_34d() {
4624         [ ! -f $DIR/f34 ] && test_34a
4625         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4626                 error "dd failed"
4627         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4628                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4629         rm $DIR/f34
4630 }
4631 run_test 34d "write to sparse file ============================="
4632
4633 test_34e() {
4634         rm -f $DIR/f34e
4635         $MCREATE $DIR/f34e || error "mcreate failed"
4636         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4637         $CHECKSTAT -s 1000 $DIR/f34e ||
4638                 error "Size of $DIR/f34e not equal to 1000 bytes"
4639         $OPENFILE -f O_RDWR $DIR/f34e
4640         $CHECKSTAT -s 1000 $DIR/f34e ||
4641                 error "Size of $DIR/f34e not equal to 1000 bytes"
4642 }
4643 run_test 34e "create objects, some with size and some without =="
4644
4645 test_34f() { # bug 6242, 6243
4646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4647
4648         SIZE34F=48000
4649         rm -f $DIR/f34f
4650         $MCREATE $DIR/f34f || error "mcreate failed"
4651         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4652         dd if=$DIR/f34f of=$TMP/f34f
4653         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4654         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4655         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4656         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4657         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4658 }
4659 run_test 34f "read from a file with no objects until EOF ======="
4660
4661 test_34g() {
4662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4663
4664         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4665                 error "dd failed"
4666         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4667         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4668                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4669         cancel_lru_locks osc
4670         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4671                 error "wrong size after lock cancel"
4672
4673         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4674         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4675                 error "expanding truncate failed"
4676         cancel_lru_locks osc
4677         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4678                 error "wrong expanded size after lock cancel"
4679 }
4680 run_test 34g "truncate long file ==============================="
4681
4682 test_34h() {
4683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4684
4685         local gid=10
4686         local sz=1000
4687
4688         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4689         sync # Flush the cache so that multiop below does not block on cache
4690              # flush when getting the group lock
4691         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4692         MULTIPID=$!
4693
4694         # Since just timed wait is not good enough, let's do a sync write
4695         # that way we are sure enough time for a roundtrip + processing
4696         # passed + 2 seconds of extra margin.
4697         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4698         rm $DIR/${tfile}-1
4699         sleep 2
4700
4701         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4702                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4703                 kill -9 $MULTIPID
4704         fi
4705         wait $MULTIPID
4706         local nsz=`stat -c %s $DIR/$tfile`
4707         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4708 }
4709 run_test 34h "ftruncate file under grouplock should not block"
4710
4711 test_35a() {
4712         cp /bin/sh $DIR/f35a
4713         chmod 444 $DIR/f35a
4714         chown $RUNAS_ID $DIR/f35a
4715         $RUNAS $DIR/f35a && error || true
4716         rm $DIR/f35a
4717 }
4718 run_test 35a "exec file with mode 444 (should return and not leak)"
4719
4720 test_36a() {
4721         rm -f $DIR/f36
4722         utime $DIR/f36 || error "utime failed for MDS"
4723 }
4724 run_test 36a "MDS utime check (mknod, utime)"
4725
4726 test_36b() {
4727         echo "" > $DIR/f36
4728         utime $DIR/f36 || error "utime failed for OST"
4729 }
4730 run_test 36b "OST utime check (open, utime)"
4731
4732 test_36c() {
4733         rm -f $DIR/d36/f36
4734         test_mkdir $DIR/d36
4735         chown $RUNAS_ID $DIR/d36
4736         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4737 }
4738 run_test 36c "non-root MDS utime check (mknod, utime)"
4739
4740 test_36d() {
4741         [ ! -d $DIR/d36 ] && test_36c
4742         echo "" > $DIR/d36/f36
4743         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4744 }
4745 run_test 36d "non-root OST utime check (open, utime)"
4746
4747 test_36e() {
4748         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4749
4750         test_mkdir $DIR/$tdir
4751         touch $DIR/$tdir/$tfile
4752         $RUNAS utime $DIR/$tdir/$tfile &&
4753                 error "utime worked, expected failure" || true
4754 }
4755 run_test 36e "utime on non-owned file (should return error)"
4756
4757 subr_36fh() {
4758         local fl="$1"
4759         local LANG_SAVE=$LANG
4760         local LC_LANG_SAVE=$LC_LANG
4761         export LANG=C LC_LANG=C # for date language
4762
4763         DATESTR="Dec 20  2000"
4764         test_mkdir $DIR/$tdir
4765         lctl set_param fail_loc=$fl
4766         date; date +%s
4767         cp /etc/hosts $DIR/$tdir/$tfile
4768         sync & # write RPC generated with "current" inode timestamp, but delayed
4769         sleep 1
4770         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4771         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4772         cancel_lru_locks $OSC
4773         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4774         date; date +%s
4775         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4776                 echo "BEFORE: $LS_BEFORE" && \
4777                 echo "AFTER : $LS_AFTER" && \
4778                 echo "WANT  : $DATESTR" && \
4779                 error "$DIR/$tdir/$tfile timestamps changed" || true
4780
4781         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4782 }
4783
4784 test_36f() {
4785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4786
4787         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4788         subr_36fh "0x80000214"
4789 }
4790 run_test 36f "utime on file racing with OST BRW write =========="
4791
4792 test_36g() {
4793         remote_ost_nodsh && skip "remote OST with nodsh"
4794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4795         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4796                 skip "Need MDS version at least 2.12.51"
4797
4798         local fmd_max_age
4799         local fmd
4800         local facet="ost1"
4801         local tgt="obdfilter"
4802
4803         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4804
4805         test_mkdir $DIR/$tdir
4806         fmd_max_age=$(do_facet $facet \
4807                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4808                 head -n 1")
4809
4810         echo "FMD max age: ${fmd_max_age}s"
4811         touch $DIR/$tdir/$tfile
4812         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4813                 gawk '{cnt=cnt+$1}  END{print cnt}')
4814         echo "FMD before: $fmd"
4815         [[ $fmd == 0 ]] &&
4816                 error "FMD wasn't create by touch"
4817         sleep $((fmd_max_age + 12))
4818         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4819                 gawk '{cnt=cnt+$1}  END{print cnt}')
4820         echo "FMD after: $fmd"
4821         [[ $fmd == 0 ]] ||
4822                 error "FMD wasn't expired by ping"
4823 }
4824 run_test 36g "FMD cache expiry ====================="
4825
4826 test_36h() {
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4830         subr_36fh "0x80000227"
4831 }
4832 run_test 36h "utime on file racing with OST BRW write =========="
4833
4834 test_36i() {
4835         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4836
4837         test_mkdir $DIR/$tdir
4838         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4839
4840         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4841         local new_mtime=$((mtime + 200))
4842
4843         #change Modify time of striped dir
4844         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4845                         error "change mtime failed"
4846
4847         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4848
4849         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4850 }
4851 run_test 36i "change mtime on striped directory"
4852
4853 # test_37 - duplicate with tests 32q 32r
4854
4855 test_38() {
4856         local file=$DIR/$tfile
4857         touch $file
4858         openfile -f O_DIRECTORY $file
4859         local RC=$?
4860         local ENOTDIR=20
4861         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4862         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4863 }
4864 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4865
4866 test_39a() { # was test_39
4867         touch $DIR/$tfile
4868         touch $DIR/${tfile}2
4869 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4870 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4871 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4872         sleep 2
4873         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4874         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4875                 echo "mtime"
4876                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4877                 echo "atime"
4878                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4879                 echo "ctime"
4880                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4881                 error "O_TRUNC didn't change timestamps"
4882         fi
4883 }
4884 run_test 39a "mtime changed on create"
4885
4886 test_39b() {
4887         test_mkdir -c1 $DIR/$tdir
4888         cp -p /etc/passwd $DIR/$tdir/fopen
4889         cp -p /etc/passwd $DIR/$tdir/flink
4890         cp -p /etc/passwd $DIR/$tdir/funlink
4891         cp -p /etc/passwd $DIR/$tdir/frename
4892         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4893
4894         sleep 1
4895         echo "aaaaaa" >> $DIR/$tdir/fopen
4896         echo "aaaaaa" >> $DIR/$tdir/flink
4897         echo "aaaaaa" >> $DIR/$tdir/funlink
4898         echo "aaaaaa" >> $DIR/$tdir/frename
4899
4900         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4901         local link_new=`stat -c %Y $DIR/$tdir/flink`
4902         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4903         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4904
4905         cat $DIR/$tdir/fopen > /dev/null
4906         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4907         rm -f $DIR/$tdir/funlink2
4908         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4909
4910         for (( i=0; i < 2; i++ )) ; do
4911                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4912                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4913                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4914                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4915
4916                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4917                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4918                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4919                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4920
4921                 cancel_lru_locks $OSC
4922                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4923         done
4924 }
4925 run_test 39b "mtime change on open, link, unlink, rename  ======"
4926
4927 # this should be set to past
4928 TEST_39_MTIME=`date -d "1 year ago" +%s`
4929
4930 # bug 11063
4931 test_39c() {
4932         touch $DIR1/$tfile
4933         sleep 2
4934         local mtime0=`stat -c %Y $DIR1/$tfile`
4935
4936         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4937         local mtime1=`stat -c %Y $DIR1/$tfile`
4938         [ "$mtime1" = $TEST_39_MTIME ] || \
4939                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4940
4941         local d1=`date +%s`
4942         echo hello >> $DIR1/$tfile
4943         local d2=`date +%s`
4944         local mtime2=`stat -c %Y $DIR1/$tfile`
4945         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4946                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4947
4948         mv $DIR1/$tfile $DIR1/$tfile-1
4949
4950         for (( i=0; i < 2; i++ )) ; do
4951                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4952                 [ "$mtime2" = "$mtime3" ] || \
4953                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4954
4955                 cancel_lru_locks $OSC
4956                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4957         done
4958 }
4959 run_test 39c "mtime change on rename ==========================="
4960
4961 # bug 21114
4962 test_39d() {
4963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4964
4965         touch $DIR1/$tfile
4966         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4967
4968         for (( i=0; i < 2; i++ )) ; do
4969                 local mtime=`stat -c %Y $DIR1/$tfile`
4970                 [ $mtime = $TEST_39_MTIME ] || \
4971                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4972
4973                 cancel_lru_locks $OSC
4974                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4975         done
4976 }
4977 run_test 39d "create, utime, stat =============================="
4978
4979 # bug 21114
4980 test_39e() {
4981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4982
4983         touch $DIR1/$tfile
4984         local mtime1=`stat -c %Y $DIR1/$tfile`
4985
4986         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4987
4988         for (( i=0; i < 2; i++ )) ; do
4989                 local mtime2=`stat -c %Y $DIR1/$tfile`
4990                 [ $mtime2 = $TEST_39_MTIME ] || \
4991                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4992
4993                 cancel_lru_locks $OSC
4994                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4995         done
4996 }
4997 run_test 39e "create, stat, utime, stat ========================"
4998
4999 # bug 21114
5000 test_39f() {
5001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5002
5003         touch $DIR1/$tfile
5004         mtime1=`stat -c %Y $DIR1/$tfile`
5005
5006         sleep 2
5007         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5008
5009         for (( i=0; i < 2; i++ )) ; do
5010                 local mtime2=`stat -c %Y $DIR1/$tfile`
5011                 [ $mtime2 = $TEST_39_MTIME ] || \
5012                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5013
5014                 cancel_lru_locks $OSC
5015                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5016         done
5017 }
5018 run_test 39f "create, stat, sleep, utime, stat ================="
5019
5020 # bug 11063
5021 test_39g() {
5022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5023
5024         echo hello >> $DIR1/$tfile
5025         local mtime1=`stat -c %Y $DIR1/$tfile`
5026
5027         sleep 2
5028         chmod o+r $DIR1/$tfile
5029
5030         for (( i=0; i < 2; i++ )) ; do
5031                 local mtime2=`stat -c %Y $DIR1/$tfile`
5032                 [ "$mtime1" = "$mtime2" ] || \
5033                         error "lost mtime: $mtime2, should be $mtime1"
5034
5035                 cancel_lru_locks $OSC
5036                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5037         done
5038 }
5039 run_test 39g "write, chmod, stat ==============================="
5040
5041 # bug 11063
5042 test_39h() {
5043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5044
5045         touch $DIR1/$tfile
5046         sleep 1
5047
5048         local d1=`date`
5049         echo hello >> $DIR1/$tfile
5050         local mtime1=`stat -c %Y $DIR1/$tfile`
5051
5052         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5053         local d2=`date`
5054         if [ "$d1" != "$d2" ]; then
5055                 echo "write and touch not within one second"
5056         else
5057                 for (( i=0; i < 2; i++ )) ; do
5058                         local mtime2=`stat -c %Y $DIR1/$tfile`
5059                         [ "$mtime2" = $TEST_39_MTIME ] || \
5060                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5061
5062                         cancel_lru_locks $OSC
5063                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5064                 done
5065         fi
5066 }
5067 run_test 39h "write, utime within one second, stat ============="
5068
5069 test_39i() {
5070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5071
5072         touch $DIR1/$tfile
5073         sleep 1
5074
5075         echo hello >> $DIR1/$tfile
5076         local mtime1=`stat -c %Y $DIR1/$tfile`
5077
5078         mv $DIR1/$tfile $DIR1/$tfile-1
5079
5080         for (( i=0; i < 2; i++ )) ; do
5081                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5082
5083                 [ "$mtime1" = "$mtime2" ] || \
5084                         error "lost mtime: $mtime2, should be $mtime1"
5085
5086                 cancel_lru_locks $OSC
5087                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5088         done
5089 }
5090 run_test 39i "write, rename, stat =============================="
5091
5092 test_39j() {
5093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5094
5095         start_full_debug_logging
5096         touch $DIR1/$tfile
5097         sleep 1
5098
5099         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5100         lctl set_param fail_loc=0x80000412
5101         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5102                 error "multiop failed"
5103         local multipid=$!
5104         local mtime1=`stat -c %Y $DIR1/$tfile`
5105
5106         mv $DIR1/$tfile $DIR1/$tfile-1
5107
5108         kill -USR1 $multipid
5109         wait $multipid || error "multiop close failed"
5110
5111         for (( i=0; i < 2; i++ )) ; do
5112                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5113                 [ "$mtime1" = "$mtime2" ] ||
5114                         error "mtime is lost on close: $mtime2, " \
5115                               "should be $mtime1"
5116
5117                 cancel_lru_locks
5118                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5119         done
5120         lctl set_param fail_loc=0
5121         stop_full_debug_logging
5122 }
5123 run_test 39j "write, rename, close, stat ======================="
5124
5125 test_39k() {
5126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5127
5128         touch $DIR1/$tfile
5129         sleep 1
5130
5131         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5132         local multipid=$!
5133         local mtime1=`stat -c %Y $DIR1/$tfile`
5134
5135         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5136
5137         kill -USR1 $multipid
5138         wait $multipid || error "multiop close failed"
5139
5140         for (( i=0; i < 2; i++ )) ; do
5141                 local mtime2=`stat -c %Y $DIR1/$tfile`
5142
5143                 [ "$mtime2" = $TEST_39_MTIME ] || \
5144                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5145
5146                 cancel_lru_locks
5147                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5148         done
5149 }
5150 run_test 39k "write, utime, close, stat ========================"
5151
5152 # this should be set to future
5153 TEST_39_ATIME=`date -d "1 year" +%s`
5154
5155 test_39l() {
5156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5157         remote_mds_nodsh && skip "remote MDS with nodsh"
5158
5159         local atime_diff=$(do_facet $SINGLEMDS \
5160                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5161         rm -rf $DIR/$tdir
5162         mkdir_on_mdt0 $DIR/$tdir
5163
5164         # test setting directory atime to future
5165         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5166         local atime=$(stat -c %X $DIR/$tdir)
5167         [ "$atime" = $TEST_39_ATIME ] ||
5168                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5169
5170         # test setting directory atime from future to now
5171         local now=$(date +%s)
5172         touch -a -d @$now $DIR/$tdir
5173
5174         atime=$(stat -c %X $DIR/$tdir)
5175         [ "$atime" -eq "$now"  ] ||
5176                 error "atime is not updated from future: $atime, $now"
5177
5178         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5179         sleep 3
5180
5181         # test setting directory atime when now > dir atime + atime_diff
5182         local d1=$(date +%s)
5183         ls $DIR/$tdir
5184         local d2=$(date +%s)
5185         cancel_lru_locks mdc
5186         atime=$(stat -c %X $DIR/$tdir)
5187         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5188                 error "atime is not updated  : $atime, should be $d2"
5189
5190         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5191         sleep 3
5192
5193         # test not setting directory atime when now < dir atime + atime_diff
5194         ls $DIR/$tdir
5195         cancel_lru_locks mdc
5196         atime=$(stat -c %X $DIR/$tdir)
5197         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5198                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5199
5200         do_facet $SINGLEMDS \
5201                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5202 }
5203 run_test 39l "directory atime update ==========================="
5204
5205 test_39m() {
5206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5207
5208         touch $DIR1/$tfile
5209         sleep 2
5210         local far_past_mtime=$(date -d "May 29 1953" +%s)
5211         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5212
5213         touch -m -d @$far_past_mtime $DIR1/$tfile
5214         touch -a -d @$far_past_atime $DIR1/$tfile
5215
5216         for (( i=0; i < 2; i++ )) ; do
5217                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5218                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5219                         error "atime or mtime set incorrectly"
5220
5221                 cancel_lru_locks $OSC
5222                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5223         done
5224 }
5225 run_test 39m "test atime and mtime before 1970"
5226
5227 test_39n() { # LU-3832
5228         remote_mds_nodsh && skip "remote MDS with nodsh"
5229
5230         local atime_diff=$(do_facet $SINGLEMDS \
5231                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5232         local atime0
5233         local atime1
5234         local atime2
5235
5236         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5237
5238         rm -rf $DIR/$tfile
5239         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5240         atime0=$(stat -c %X $DIR/$tfile)
5241
5242         sleep 5
5243         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5244         atime1=$(stat -c %X $DIR/$tfile)
5245
5246         sleep 5
5247         cancel_lru_locks mdc
5248         cancel_lru_locks osc
5249         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5250         atime2=$(stat -c %X $DIR/$tfile)
5251
5252         do_facet $SINGLEMDS \
5253                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5254
5255         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5256         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5257 }
5258 run_test 39n "check that O_NOATIME is honored"
5259
5260 test_39o() {
5261         TESTDIR=$DIR/$tdir/$tfile
5262         [ -e $TESTDIR ] && rm -rf $TESTDIR
5263         mkdir -p $TESTDIR
5264         cd $TESTDIR
5265         links1=2
5266         ls
5267         mkdir a b
5268         ls
5269         links2=$(stat -c %h .)
5270         [ $(($links1 + 2)) != $links2 ] &&
5271                 error "wrong links count $(($links1 + 2)) != $links2"
5272         rmdir b
5273         links3=$(stat -c %h .)
5274         [ $(($links1 + 1)) != $links3 ] &&
5275                 error "wrong links count $links1 != $links3"
5276         return 0
5277 }
5278 run_test 39o "directory cached attributes updated after create"
5279
5280 test_39p() {
5281         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5282
5283         local MDTIDX=1
5284         TESTDIR=$DIR/$tdir/$tdir
5285         [ -e $TESTDIR ] && rm -rf $TESTDIR
5286         test_mkdir -p $TESTDIR
5287         cd $TESTDIR
5288         links1=2
5289         ls
5290         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5291         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5292         ls
5293         links2=$(stat -c %h .)
5294         [ $(($links1 + 2)) != $links2 ] &&
5295                 error "wrong links count $(($links1 + 2)) != $links2"
5296         rmdir remote_dir2
5297         links3=$(stat -c %h .)
5298         [ $(($links1 + 1)) != $links3 ] &&
5299                 error "wrong links count $links1 != $links3"
5300         return 0
5301 }
5302 run_test 39p "remote directory cached attributes updated after create ========"
5303
5304 test_39r() {
5305         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5306                 skip "no atime update on old OST"
5307         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5308                 skip_env "ldiskfs only test"
5309         fi
5310
5311         local saved_adiff
5312         local ahost=$(facet_active_host ost1)
5313         saved_adiff=$(do_facet ost1 \
5314                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5315         stack_trap "do_facet ost1 \
5316                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5317
5318         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5319
5320         $LFS setstripe -i 0 $DIR/$tfile
5321         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5322                 error "can't write initial file"
5323         cancel_lru_locks osc
5324
5325         # exceed atime_diff and access file
5326         sleep 10
5327         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5328                 error "can't udpate atime"
5329
5330         # atime_cli value is in decimal
5331         local atime_cli=$(stat -c %X $DIR/$tfile)
5332         echo "client atime: $atime_cli"
5333
5334         local ostdev=$(ostdevname 1)
5335         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5336         local seq=${fid[3]#0x}
5337         local oid=${fid[1]}
5338         local oid_hex
5339
5340         if [ $seq == 0 ]; then
5341                 oid_hex=${fid[1]}
5342         else
5343                 oid_hex=${fid[2]#0x}
5344         fi
5345         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5346         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5347
5348         # allow atime update to be written to device
5349         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5350         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5351
5352         # Give enough time for server to get updated. Until then
5353         # the value read is defaulted to "0x00000000:00000000"
5354         # Wait until atime read via debugfs is not equal to zero.
5355         # Max limit to wait is 30 seconds.
5356         wait_update_cond $ahost                                         \
5357                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5358                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5359         # atime_ost value is in hex
5360         local atime_ost=$(do_facet ost1 "$cmd" |&
5361                           awk -F'[: ]' '/atime:/ { print $4 }')
5362         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5363         # convert Hex to decimal before comparing
5364         local atime_ost_dec=$((atime_ost))
5365
5366         # The test pass criteria is that the client time and server should
5367         # be same (2s gap accepted). This gap could arise due to VFS updating
5368         # the atime after the read(dd), stat and the updated time from the
5369         # inode
5370         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5371                 error "atime on client $atime_cli != ost $atime_ost_dec"
5372 }
5373 run_test 39r "lazy atime update on OST"
5374
5375 test_39q() { # LU-8041
5376         local testdir=$DIR/$tdir
5377         mkdir -p $testdir
5378         multiop_bg_pause $testdir D_c || error "multiop failed"
5379         local multipid=$!
5380         cancel_lru_locks mdc
5381         kill -USR1 $multipid
5382         local atime=$(stat -c %X $testdir)
5383         [ "$atime" -ne 0 ] || error "atime is zero"
5384 }
5385 run_test 39q "close won't zero out atime"
5386
5387 test_39s() {
5388         local atime0
5389         local atime1
5390         local atime2
5391         local atime3
5392         local atime4
5393
5394         umount_client $MOUNT
5395         mount_client $MOUNT relatime
5396
5397         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5398         atime0=$(stat -c %X $DIR/$tfile)
5399
5400         # First read updates atime
5401         sleep 1
5402         cat $DIR/$tfile >/dev/null
5403         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5404
5405         # Next reads do not update atime
5406         sleep 1
5407         cat $DIR/$tfile >/dev/null
5408         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5409
5410         # If mtime is greater than atime, atime is updated
5411         sleep 1
5412         touch -m $DIR/$tfile # (mtime = now)
5413         sleep 1
5414         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5415         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5416
5417         # Next reads do not update atime
5418         sleep 1
5419         cat $DIR/$tfile >/dev/null
5420         atime4=$(stat -c %X $DIR/$tfile)
5421
5422         # Remount the client to clear 'relatime' option
5423         remount_client $MOUNT
5424
5425         (( atime0 < atime1 )) ||
5426                 error "atime $atime0 should be smaller than $atime1"
5427         (( atime1 == atime2 )) ||
5428                 error "atime $atime1 was updated to $atime2"
5429         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5430         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5431 }
5432 run_test 39s "relatime is supported"
5433
5434 test_40() {
5435         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5436         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5437                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5438         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5439                 error "$tfile is not 4096 bytes in size"
5440 }
5441 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5442
5443 test_41() {
5444         # bug 1553
5445         small_write $DIR/f41 18
5446 }
5447 run_test 41 "test small file write + fstat ====================="
5448
5449 count_ost_writes() {
5450         lctl get_param -n ${OSC}.*.stats |
5451                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5452                         END { printf("%0.0f", writes) }'
5453 }
5454
5455 # decent default
5456 WRITEBACK_SAVE=500
5457 DIRTY_RATIO_SAVE=40
5458 MAX_DIRTY_RATIO=50
5459 BG_DIRTY_RATIO_SAVE=10
5460 MAX_BG_DIRTY_RATIO=25
5461
5462 start_writeback() {
5463         trap 0
5464         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5465         # dirty_ratio, dirty_background_ratio
5466         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5467                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5468                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5469                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5470         else
5471                 # if file not here, we are a 2.4 kernel
5472                 kill -CONT `pidof kupdated`
5473         fi
5474 }
5475
5476 stop_writeback() {
5477         # setup the trap first, so someone cannot exit the test at the
5478         # exact wrong time and mess up a machine
5479         trap start_writeback EXIT
5480         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5481         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5482                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5483                 sysctl -w vm.dirty_writeback_centisecs=0
5484                 sysctl -w vm.dirty_writeback_centisecs=0
5485                 # save and increase /proc/sys/vm/dirty_ratio
5486                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5487                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5488                 # save and increase /proc/sys/vm/dirty_background_ratio
5489                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5490                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5491         else
5492                 # if file not here, we are a 2.4 kernel
5493                 kill -STOP `pidof kupdated`
5494         fi
5495 }
5496
5497 # ensure that all stripes have some grant before we test client-side cache
5498 setup_test42() {
5499         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5500                 dd if=/dev/zero of=$i bs=4k count=1
5501                 rm $i
5502         done
5503 }
5504
5505 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5506 # file truncation, and file removal.
5507 test_42a() {
5508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5509
5510         setup_test42
5511         cancel_lru_locks $OSC
5512         stop_writeback
5513         sync; sleep 1; sync # just to be safe
5514         BEFOREWRITES=`count_ost_writes`
5515         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5516         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5517         AFTERWRITES=`count_ost_writes`
5518         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5519                 error "$BEFOREWRITES < $AFTERWRITES"
5520         start_writeback
5521 }
5522 run_test 42a "ensure that we don't flush on close"
5523
5524 test_42b() {
5525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5526
5527         setup_test42
5528         cancel_lru_locks $OSC
5529         stop_writeback
5530         sync
5531         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5532         BEFOREWRITES=$(count_ost_writes)
5533         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5534         AFTERWRITES=$(count_ost_writes)
5535         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5536                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5537         fi
5538         BEFOREWRITES=$(count_ost_writes)
5539         sync || error "sync: $?"
5540         AFTERWRITES=$(count_ost_writes)
5541         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5542                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5543         fi
5544         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5545         start_writeback
5546         return 0
5547 }
5548 run_test 42b "test destroy of file with cached dirty data ======"
5549
5550 # if these tests just want to test the effect of truncation,
5551 # they have to be very careful.  consider:
5552 # - the first open gets a {0,EOF}PR lock
5553 # - the first write conflicts and gets a {0, count-1}PW
5554 # - the rest of the writes are under {count,EOF}PW
5555 # - the open for truncate tries to match a {0,EOF}PR
5556 #   for the filesize and cancels the PWs.
5557 # any number of fixes (don't get {0,EOF} on open, match
5558 # composite locks, do smarter file size management) fix
5559 # this, but for now we want these tests to verify that
5560 # the cancellation with truncate intent works, so we
5561 # start the file with a full-file pw lock to match against
5562 # until the truncate.
5563 trunc_test() {
5564         test=$1
5565         file=$DIR/$test
5566         offset=$2
5567         cancel_lru_locks $OSC
5568         stop_writeback
5569         # prime the file with 0,EOF PW to match
5570         touch $file
5571         $TRUNCATE $file 0
5572         sync; sync
5573         # now the real test..
5574         dd if=/dev/zero of=$file bs=1024 count=100
5575         BEFOREWRITES=`count_ost_writes`
5576         $TRUNCATE $file $offset
5577         cancel_lru_locks $OSC
5578         AFTERWRITES=`count_ost_writes`
5579         start_writeback
5580 }
5581
5582 test_42c() {
5583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5584
5585         trunc_test 42c 1024
5586         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5587                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5588         rm $file
5589 }
5590 run_test 42c "test partial truncate of file with cached dirty data"
5591
5592 test_42d() {
5593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5594
5595         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5596         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5597         $LCTL set_param debug=+cache
5598
5599         trunc_test 42d 0
5600         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5601                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5602         rm $file
5603 }
5604 run_test 42d "test complete truncate of file with cached dirty data"
5605
5606 test_42e() { # bug22074
5607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5608
5609         local TDIR=$DIR/${tdir}e
5610         local pages=16 # hardcoded 16 pages, don't change it.
5611         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5612         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5613         local max_dirty_mb
5614         local warmup_files
5615
5616         test_mkdir $DIR/${tdir}e
5617         $LFS setstripe -c 1 $TDIR
5618         createmany -o $TDIR/f $files
5619
5620         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5621
5622         # we assume that with $OSTCOUNT files, at least one of them will
5623         # be allocated on OST0.
5624         warmup_files=$((OSTCOUNT * max_dirty_mb))
5625         createmany -o $TDIR/w $warmup_files
5626
5627         # write a large amount of data into one file and sync, to get good
5628         # avail_grant number from OST.
5629         for ((i=0; i<$warmup_files; i++)); do
5630                 idx=$($LFS getstripe -i $TDIR/w$i)
5631                 [ $idx -ne 0 ] && continue
5632                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5633                 break
5634         done
5635         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5636         sync
5637         $LCTL get_param $proc_osc0/cur_dirty_bytes
5638         $LCTL get_param $proc_osc0/cur_grant_bytes
5639
5640         # create as much dirty pages as we can while not to trigger the actual
5641         # RPCs directly. but depends on the env, VFS may trigger flush during this
5642         # period, hopefully we are good.
5643         for ((i=0; i<$warmup_files; i++)); do
5644                 idx=$($LFS getstripe -i $TDIR/w$i)
5645                 [ $idx -ne 0 ] && continue
5646                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5647         done
5648         $LCTL get_param $proc_osc0/cur_dirty_bytes
5649         $LCTL get_param $proc_osc0/cur_grant_bytes
5650
5651         # perform the real test
5652         $LCTL set_param $proc_osc0/rpc_stats 0
5653         for ((;i<$files; i++)); do
5654                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5655                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5656         done
5657         sync
5658         $LCTL get_param $proc_osc0/rpc_stats
5659
5660         local percent=0
5661         local have_ppr=false
5662         $LCTL get_param $proc_osc0/rpc_stats |
5663                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5664                         # skip lines until we are at the RPC histogram data
5665                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5666                         $have_ppr || continue
5667
5668                         # we only want the percent stat for < 16 pages
5669                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5670
5671                         percent=$((percent + WPCT))
5672                         if [[ $percent -gt 15 ]]; then
5673                                 error "less than 16-pages write RPCs" \
5674                                       "$percent% > 15%"
5675                                 break
5676                         fi
5677                 done
5678         rm -rf $TDIR
5679 }
5680 run_test 42e "verify sub-RPC writes are not done synchronously"
5681
5682 test_43A() { # was test_43
5683         test_mkdir $DIR/$tdir
5684         cp -p /bin/ls $DIR/$tdir/$tfile
5685         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5686         pid=$!
5687         # give multiop a chance to open
5688         sleep 1
5689
5690         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5691         kill -USR1 $pid
5692         # Wait for multiop to exit
5693         wait $pid
5694 }
5695 run_test 43A "execution of file opened for write should return -ETXTBSY"
5696
5697 test_43a() {
5698         test_mkdir $DIR/$tdir
5699         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5700         $DIR/$tdir/sleep 60 &
5701         SLEEP_PID=$!
5702         # Make sure exec of $tdir/sleep wins race with truncate
5703         sleep 1
5704         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5705         kill $SLEEP_PID
5706 }
5707 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5708
5709 test_43b() {
5710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5711
5712         test_mkdir $DIR/$tdir
5713         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5714         $DIR/$tdir/sleep 60 &
5715         SLEEP_PID=$!
5716         # Make sure exec of $tdir/sleep wins race with truncate
5717         sleep 1
5718         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5719         kill $SLEEP_PID
5720 }
5721 run_test 43b "truncate of file being executed should return -ETXTBSY"
5722
5723 test_43c() {
5724         local testdir="$DIR/$tdir"
5725         test_mkdir $testdir
5726         cp $SHELL $testdir/
5727         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5728                 ( cd $testdir && md5sum -c )
5729 }
5730 run_test 43c "md5sum of copy into lustre"
5731
5732 test_44A() { # was test_44
5733         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5734
5735         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5736         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5737 }
5738 run_test 44A "zero length read from a sparse stripe"
5739
5740 test_44a() {
5741         local nstripe=$($LFS getstripe -c -d $DIR)
5742         [ -z "$nstripe" ] && skip "can't get stripe info"
5743         [[ $nstripe -gt $OSTCOUNT ]] &&
5744                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5745
5746         local stride=$($LFS getstripe -S -d $DIR)
5747         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5748                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5749         fi
5750
5751         OFFSETS="0 $((stride/2)) $((stride-1))"
5752         for offset in $OFFSETS; do
5753                 for i in $(seq 0 $((nstripe-1))); do
5754                         local GLOBALOFFSETS=""
5755                         # size in Bytes
5756                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5757                         local myfn=$DIR/d44a-$size
5758                         echo "--------writing $myfn at $size"
5759                         ll_sparseness_write $myfn $size ||
5760                                 error "ll_sparseness_write"
5761                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5762                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5763                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5764
5765                         for j in $(seq 0 $((nstripe-1))); do
5766                                 # size in Bytes
5767                                 size=$((((j + $nstripe )*$stride + $offset)))
5768                                 ll_sparseness_write $myfn $size ||
5769                                         error "ll_sparseness_write"
5770                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5771                         done
5772                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5773                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5774                         rm -f $myfn
5775                 done
5776         done
5777 }
5778 run_test 44a "test sparse pwrite ==============================="
5779
5780 dirty_osc_total() {
5781         tot=0
5782         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5783                 tot=$(($tot + $d))
5784         done
5785         echo $tot
5786 }
5787 do_dirty_record() {
5788         before=`dirty_osc_total`
5789         echo executing "\"$*\""
5790         eval $*
5791         after=`dirty_osc_total`
5792         echo before $before, after $after
5793 }
5794 test_45() {
5795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5796
5797         f="$DIR/f45"
5798         # Obtain grants from OST if it supports it
5799         echo blah > ${f}_grant
5800         stop_writeback
5801         sync
5802         do_dirty_record "echo blah > $f"
5803         [[ $before -eq $after ]] && error "write wasn't cached"
5804         do_dirty_record "> $f"
5805         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5806         do_dirty_record "echo blah > $f"
5807         [[ $before -eq $after ]] && error "write wasn't cached"
5808         do_dirty_record "sync"
5809         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5810         do_dirty_record "echo blah > $f"
5811         [[ $before -eq $after ]] && error "write wasn't cached"
5812         do_dirty_record "cancel_lru_locks osc"
5813         [[ $before -gt $after ]] ||
5814                 error "lock cancellation didn't lower dirty count"
5815         start_writeback
5816 }
5817 run_test 45 "osc io page accounting ============================"
5818
5819 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5820 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5821 # objects offset and an assert hit when an rpc was built with 1023's mapped
5822 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5823 test_46() {
5824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5825
5826         f="$DIR/f46"
5827         stop_writeback
5828         sync
5829         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5830         sync
5831         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5832         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5833         sync
5834         start_writeback
5835 }
5836 run_test 46 "dirtying a previously written page ================"
5837
5838 # test_47 is removed "Device nodes check" is moved to test_28
5839
5840 test_48a() { # bug 2399
5841         [ "$mds1_FSTYPE" = "zfs" ] &&
5842         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5843                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5844
5845         test_mkdir $DIR/$tdir
5846         cd $DIR/$tdir
5847         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5848         test_mkdir $DIR/$tdir
5849         touch foo || error "'touch foo' failed after recreating cwd"
5850         test_mkdir bar
5851         touch .foo || error "'touch .foo' failed after recreating cwd"
5852         test_mkdir .bar
5853         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5854         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5855         cd . || error "'cd .' failed after recreating cwd"
5856         mkdir . && error "'mkdir .' worked after recreating cwd"
5857         rmdir . && error "'rmdir .' worked after recreating cwd"
5858         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5859         cd .. || error "'cd ..' failed after recreating cwd"
5860 }
5861 run_test 48a "Access renamed working dir (should return errors)="
5862
5863 test_48b() { # bug 2399
5864         rm -rf $DIR/$tdir
5865         test_mkdir $DIR/$tdir
5866         cd $DIR/$tdir
5867         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5868         touch foo && error "'touch foo' worked after removing cwd"
5869         mkdir foo && error "'mkdir foo' worked after removing cwd"
5870         touch .foo && error "'touch .foo' worked after removing cwd"
5871         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5872         ls . > /dev/null && error "'ls .' worked after removing cwd"
5873         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5874         mkdir . && error "'mkdir .' worked after removing cwd"
5875         rmdir . && error "'rmdir .' worked after removing cwd"
5876         ln -s . foo && error "'ln -s .' worked after removing cwd"
5877         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5878 }
5879 run_test 48b "Access removed working dir (should return errors)="
5880
5881 test_48c() { # bug 2350
5882         #lctl set_param debug=-1
5883         #set -vx
5884         rm -rf $DIR/$tdir
5885         test_mkdir -p $DIR/$tdir/dir
5886         cd $DIR/$tdir/dir
5887         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5888         $TRACE touch foo && error "touch foo worked after removing cwd"
5889         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5890         touch .foo && error "touch .foo worked after removing cwd"
5891         mkdir .foo && error "mkdir .foo worked after removing cwd"
5892         $TRACE ls . && error "'ls .' worked after removing cwd"
5893         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5894         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5895         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5896         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5897         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5898 }
5899 run_test 48c "Access removed working subdir (should return errors)"
5900
5901 test_48d() { # bug 2350
5902         #lctl set_param debug=-1
5903         #set -vx
5904         rm -rf $DIR/$tdir
5905         test_mkdir -p $DIR/$tdir/dir
5906         cd $DIR/$tdir/dir
5907         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5908         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5909         $TRACE touch foo && error "'touch foo' worked after removing parent"
5910         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5911         touch .foo && error "'touch .foo' worked after removing parent"
5912         mkdir .foo && error "mkdir .foo worked after removing parent"
5913         $TRACE ls . && error "'ls .' worked after removing parent"
5914         $TRACE ls .. && error "'ls ..' worked after removing parent"
5915         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5916         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5917         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5918         true
5919 }
5920 run_test 48d "Access removed parent subdir (should return errors)"
5921
5922 test_48e() { # bug 4134
5923         #lctl set_param debug=-1
5924         #set -vx
5925         rm -rf $DIR/$tdir
5926         test_mkdir -p $DIR/$tdir/dir
5927         cd $DIR/$tdir/dir
5928         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5929         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5930         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5931         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5932         # On a buggy kernel addition of "touch foo" after cd .. will
5933         # produce kernel oops in lookup_hash_it
5934         touch ../foo && error "'cd ..' worked after recreate parent"
5935         cd $DIR
5936         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5937 }
5938 run_test 48e "Access to recreated parent subdir (should return errors)"
5939
5940 test_48f() {
5941         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5942                 skip "need MDS >= 2.13.55"
5943         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5944         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5945                 skip "needs different host for mdt1 mdt2"
5946         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5947
5948         $LFS mkdir -i0 $DIR/$tdir
5949         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5950
5951         for d in sub1 sub2 sub3; do
5952                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5953                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5954                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5955         done
5956
5957         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5958 }
5959 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5960
5961 test_49() { # LU-1030
5962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5963         remote_ost_nodsh && skip "remote OST with nodsh"
5964
5965         # get ost1 size - $FSNAME-OST0000
5966         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5967                 awk '{ print $4 }')
5968         # write 800M at maximum
5969         [[ $ost1_size -lt 2 ]] && ost1_size=2
5970         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5971
5972         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5973         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5974         local dd_pid=$!
5975
5976         # change max_pages_per_rpc while writing the file
5977         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5978         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5979         # loop until dd process exits
5980         while ps ax -opid | grep -wq $dd_pid; do
5981                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5982                 sleep $((RANDOM % 5 + 1))
5983         done
5984         # restore original max_pages_per_rpc
5985         $LCTL set_param $osc1_mppc=$orig_mppc
5986         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5987 }
5988 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5989
5990 test_50() {
5991         # bug 1485
5992         test_mkdir $DIR/$tdir
5993         cd $DIR/$tdir
5994         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5995 }
5996 run_test 50 "special situations: /proc symlinks  ==============="
5997
5998 test_51a() {    # was test_51
5999         # bug 1516 - create an empty entry right after ".." then split dir
6000         test_mkdir -c1 $DIR/$tdir
6001         touch $DIR/$tdir/foo
6002         $MCREATE $DIR/$tdir/bar
6003         rm $DIR/$tdir/foo
6004         createmany -m $DIR/$tdir/longfile 201
6005         FNUM=202
6006         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
6007                 $MCREATE $DIR/$tdir/longfile$FNUM
6008                 FNUM=$(($FNUM + 1))
6009                 echo -n "+"
6010         done
6011         echo
6012         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
6013 }
6014 run_test 51a "special situations: split htree with empty entry =="
6015
6016 cleanup_print_lfs_df () {
6017         trap 0
6018         $LFS df
6019         $LFS df -i
6020 }
6021
6022 test_51b() {
6023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6024
6025         local dir=$DIR/$tdir
6026         local nrdirs=$((65536 + 100))
6027
6028         # cleanup the directory
6029         rm -fr $dir
6030
6031         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6032
6033         $LFS df
6034         $LFS df -i
6035         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6036         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6037         [[ $numfree -lt $nrdirs ]] &&
6038                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6039
6040         # need to check free space for the directories as well
6041         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6042         numfree=$(( blkfree / $(fs_inode_ksize) ))
6043         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6044
6045         trap cleanup_print_lfs_df EXIT
6046
6047         # create files
6048         createmany -d $dir/d $nrdirs || {
6049                 unlinkmany $dir/d $nrdirs
6050                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6051         }
6052
6053         # really created :
6054         nrdirs=$(ls -U $dir | wc -l)
6055
6056         # unlink all but 100 subdirectories, then check it still works
6057         local left=100
6058         local delete=$((nrdirs - left))
6059
6060         $LFS df
6061         $LFS df -i
6062
6063         # for ldiskfs the nlink count should be 1, but this is OSD specific
6064         # and so this is listed for informational purposes only
6065         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6066         unlinkmany -d $dir/d $delete ||
6067                 error "unlink of first $delete subdirs failed"
6068
6069         echo "nlink between: $(stat -c %h $dir)"
6070         local found=$(ls -U $dir | wc -l)
6071         [ $found -ne $left ] &&
6072                 error "can't find subdirs: found only $found, expected $left"
6073
6074         unlinkmany -d $dir/d $delete $left ||
6075                 error "unlink of second $left subdirs failed"
6076         # regardless of whether the backing filesystem tracks nlink accurately
6077         # or not, the nlink count shouldn't be more than "." and ".." here
6078         local after=$(stat -c %h $dir)
6079         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6080                 echo "nlink after: $after"
6081
6082         cleanup_print_lfs_df
6083 }
6084 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6085
6086 test_51d_sub() {
6087         local stripecount=$1
6088         local nfiles=$2
6089
6090         log "create files with stripecount=$stripecount"
6091         $LFS setstripe -C $stripecount $DIR/$tdir
6092         createmany -o $DIR/$tdir/t- $nfiles
6093         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6094         for ((n = 0; n < $OSTCOUNT; n++)); do
6095                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6096                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6097                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6098                             '($1 == '$n') { objs += 1 } \
6099                             END { printf("%0.0f", objs) }')
6100                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6101         done
6102         unlinkmany $DIR/$tdir/t- $nfiles
6103         rm  -f $TMP/$tfile
6104
6105         local nlast
6106         local min=4
6107         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6108
6109         # For some combinations of stripecount and OSTCOUNT current code
6110         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6111         # than others. Rather than skipping this test entirely, check that
6112         # and keep testing to ensure imbalance does not get worse. LU-15282
6113         (( (OSTCOUNT == 6 && stripecount == 4) ||
6114            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6115            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6116         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6117                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6118                         { $LFS df && $LFS df -i &&
6119                         error "stripecount=$stripecount: " \
6120                               "OST $n has fewer objects vs. OST $nlast " \
6121                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6122                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6123                         { $LFS df && $LFS df -i &&
6124                         error "stripecount=$stripecount: " \
6125                               "OST $n has more objects vs. OST $nlast " \
6126                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6127
6128                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6129                         { $LFS df && $LFS df -i &&
6130                         error "stripecount=$stripecount: " \
6131                               "OST $n has fewer #0 objects vs. OST $nlast " \
6132                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6133                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6134                         { $LFS df && $LFS df -i &&
6135                         error "stripecount=$stripecount: " \
6136                               "OST $n has more #0 objects vs. OST $nlast " \
6137                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6138         done
6139 }
6140
6141 test_51d() {
6142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6143         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6144
6145         local stripecount
6146         local per_ost=100
6147         local nfiles=$((per_ost * OSTCOUNT))
6148         local mdts=$(comma_list $(mdts_nodes))
6149         local param="osp.*.create_count"
6150         local qos_old=$(do_facet mds1 \
6151                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6152
6153         do_nodes $mdts \
6154                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6155         stack_trap "do_nodes $mdts \
6156                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6157
6158         test_mkdir $DIR/$tdir
6159         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6160         (( dirstripes > 0 )) || dirstripes=1
6161
6162         # Ensure enough OST objects precreated for tests to pass without
6163         # running out of objects.  This is an LOV r-r OST algorithm test,
6164         # not an OST object precreation test.
6165         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6166         (( old >= nfiles )) ||
6167         {
6168                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6169
6170                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6171                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6172
6173                 # trigger precreation from all MDTs for all OSTs
6174                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6175                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6176                 done
6177         }
6178
6179         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6180                 sleep 8  # allow object precreation to catch up
6181                 test_51d_sub $stripecount $nfiles
6182         done
6183 }
6184 run_test 51d "check LOV round-robin OST object distribution"
6185
6186 test_51e() {
6187         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6188                 skip_env "ldiskfs only test"
6189         fi
6190
6191         test_mkdir -c1 $DIR/$tdir
6192         test_mkdir -c1 $DIR/$tdir/d0
6193
6194         touch $DIR/$tdir/d0/foo
6195         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6196                 error "file exceed 65000 nlink limit!"
6197         unlinkmany $DIR/$tdir/d0/f- 65001
6198         return 0
6199 }
6200 run_test 51e "check file nlink limit"
6201
6202 test_51f() {
6203         test_mkdir $DIR/$tdir
6204
6205         local max=100000
6206         local ulimit_old=$(ulimit -n)
6207         local spare=20 # number of spare fd's for scripts/libraries, etc.
6208         local mdt=$($LFS getstripe -m $DIR/$tdir)
6209         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6210
6211         echo "MDT$mdt numfree=$numfree, max=$max"
6212         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6213         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6214                 while ! ulimit -n $((numfree + spare)); do
6215                         numfree=$((numfree * 3 / 4))
6216                 done
6217                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6218         else
6219                 echo "left ulimit at $ulimit_old"
6220         fi
6221
6222         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6223                 unlinkmany $DIR/$tdir/f $numfree
6224                 error "create+open $numfree files in $DIR/$tdir failed"
6225         }
6226         ulimit -n $ulimit_old
6227
6228         # if createmany exits at 120s there will be fewer than $numfree files
6229         unlinkmany $DIR/$tdir/f $numfree || true
6230 }
6231 run_test 51f "check many open files limit"
6232
6233 test_52a() {
6234         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6235         test_mkdir $DIR/$tdir
6236         touch $DIR/$tdir/foo
6237         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6238         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6239         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6240         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6241         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6242                                         error "link worked"
6243         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6244         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6245         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6246                                                      error "lsattr"
6247         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6248         cp -r $DIR/$tdir $TMP/
6249         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6250 }
6251 run_test 52a "append-only flag test (should return errors)"
6252
6253 test_52b() {
6254         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6255         test_mkdir $DIR/$tdir
6256         touch $DIR/$tdir/foo
6257         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6258         cat test > $DIR/$tdir/foo && error "cat test worked"
6259         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6260         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6261         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6262                                         error "link worked"
6263         echo foo >> $DIR/$tdir/foo && error "echo worked"
6264         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6265         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6266         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6267         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6268                                                         error "lsattr"
6269         chattr -i $DIR/$tdir/foo || error "chattr failed"
6270
6271         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6272 }
6273 run_test 52b "immutable flag test (should return errors) ======="
6274
6275 test_53() {
6276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6277         remote_mds_nodsh && skip "remote MDS with nodsh"
6278         remote_ost_nodsh && skip "remote OST with nodsh"
6279
6280         local param
6281         local param_seq
6282         local ostname
6283         local mds_last
6284         local mds_last_seq
6285         local ost_last
6286         local ost_last_seq
6287         local ost_last_id
6288         local ostnum
6289         local node
6290         local found=false
6291         local support_last_seq=true
6292
6293         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6294                 support_last_seq=false
6295
6296         # only test MDT0000
6297         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6298         local value
6299         for value in $(do_facet $SINGLEMDS \
6300                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6301                 param=$(echo ${value[0]} | cut -d "=" -f1)
6302                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6303
6304                 if $support_last_seq; then
6305                         param_seq=$(echo $param |
6306                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6307                         mds_last_seq=$(do_facet $SINGLEMDS \
6308                                        $LCTL get_param -n $param_seq)
6309                 fi
6310                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6311
6312                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6313                 node=$(facet_active_host ost$((ostnum+1)))
6314                 param="obdfilter.$ostname.last_id"
6315                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6316                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6317                         ost_last_id=$ost_last
6318
6319                         if $support_last_seq; then
6320                                 ost_last_id=$(echo $ost_last |
6321                                               awk -F':' '{print $2}' |
6322                                               sed -e "s/^0x//g")
6323                                 ost_last_seq=$(echo $ost_last |
6324                                                awk -F':' '{print $1}')
6325                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6326                         fi
6327
6328                         if [[ $ost_last_id != $mds_last ]]; then
6329                                 error "$ost_last_id != $mds_last"
6330                         else
6331                                 found=true
6332                                 break
6333                         fi
6334                 done
6335         done
6336         $found || error "can not match last_seq/last_id for $mdtosc"
6337         return 0
6338 }
6339 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6340
6341 test_54a() {
6342         $SOCKETSERVER $DIR/socket ||
6343                 error "$SOCKETSERVER $DIR/socket failed: $?"
6344         $SOCKETCLIENT $DIR/socket ||
6345                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6346         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6347 }
6348 run_test 54a "unix domain socket test"
6349
6350 test_54b() {
6351         f="$DIR/f54b"
6352         mknod $f c 1 3
6353         chmod 0666 $f
6354         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6355 }
6356 run_test 54b "char device works in lustre ======================"
6357
6358 find_loop_dev() {
6359         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6360         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6361         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6362
6363         for i in $(seq 3 7); do
6364                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6365                 LOOPDEV=$LOOPBASE$i
6366                 LOOPNUM=$i
6367                 break
6368         done
6369 }
6370
6371 cleanup_54c() {
6372         local rc=0
6373         loopdev="$DIR/loop54c"
6374
6375         trap 0
6376         $UMOUNT $DIR/$tdir || rc=$?
6377         losetup -d $loopdev || true
6378         losetup -d $LOOPDEV || true
6379         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6380         return $rc
6381 }
6382
6383 test_54c() {
6384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6385
6386         loopdev="$DIR/loop54c"
6387
6388         find_loop_dev
6389         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6390         trap cleanup_54c EXIT
6391         mknod $loopdev b 7 $LOOPNUM
6392         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6393         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6394         losetup $loopdev $DIR/$tfile ||
6395                 error "can't set up $loopdev for $DIR/$tfile"
6396         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6397         test_mkdir $DIR/$tdir
6398         mount -t ext2 $loopdev $DIR/$tdir ||
6399                 error "error mounting $loopdev on $DIR/$tdir"
6400         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6401                 error "dd write"
6402         df $DIR/$tdir
6403         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6404                 error "dd read"
6405         cleanup_54c
6406 }
6407 run_test 54c "block device works in lustre ====================="
6408
6409 test_54d() {
6410         local pipe="$DIR/$tfile.pipe"
6411         local string="aaaaaa"
6412
6413         mknod $pipe p
6414         echo -n "$string" > $pipe &
6415         local result=$(cat $pipe)
6416         [[ "$result" == "$string" ]] || error "$result != $string"
6417 }
6418 run_test 54d "fifo device works in lustre ======================"
6419
6420 test_54e() {
6421         f="$DIR/f54e"
6422         string="aaaaaa"
6423         cp -aL /dev/console $f
6424         echo $string > $f || error "echo $string to $f failed"
6425 }
6426 run_test 54e "console/tty device works in lustre ======================"
6427
6428 test_55a() {
6429         local dev_path="/sys/kernel/debug/lustre/devices"
6430
6431         load_module kunit/obd_test verbose=2 || error "load_module failed"
6432
6433         # This must be run in iteractive mode, since attach and setup
6434         # are stateful
6435         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6436                 attach obd_test obd_name obd_uuid
6437                 setup obd_test
6438         EOF"
6439
6440         echo "Devices:"
6441         cat "$dev_path" | tail -n 10
6442
6443         $LCTL --device "obd_name" cleanup
6444         $LCTL --device "obd_name" detach
6445
6446         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6447                 error "OBD unit test failed"
6448
6449         rmmod -v obd_test ||
6450                 error "rmmod failed (may trigger a failure in a later test)"
6451 }
6452 run_test 55a "OBD device life cycle unit tests"
6453
6454 test_55b() {
6455         local dev_path="/sys/kernel/debug/lustre/devices"
6456         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6457
6458         # Set up a large number of devices, using the number
6459         # that can be set up in about a minute (based on prior
6460         # testing). We don't want to run this test forever.
6461         local num_dev_to_create="$(( 24000 - $dev_count))"
6462
6463         load_module kunit/obd_test || error "load_module failed"
6464
6465         local start=$SECONDS
6466
6467         # This must be run in iteractive mode, since attach and setup
6468         # are stateful
6469         for ((i = 1; i <= num_dev_to_create; i++)); do
6470                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6471                 echo "setup obd_test_$i"
6472         done | $LCTL || error "OBD device creation failed"
6473
6474         echo "Load time: $((SECONDS - start))"
6475         echo "Devices:"
6476         cat "$dev_path" | tail -n 10
6477
6478         for ((i = 1; i <= num_dev_to_create; i++)); do
6479                 echo "--device obd_name_$i cleanup"
6480                 echo "--device obd_name_$i detach"
6481         done | $LCTL || error "OBD device cleanup failed"
6482
6483         echo "Unload time: $((SECONDS - start))"
6484
6485         rmmod -v obd_test ||
6486                 error "rmmod failed (may trigger a failure in a later test)"
6487 }
6488 run_test 55b "Load and unload max OBD devices"
6489
6490 test_56a() {
6491         local numfiles=3
6492         local numdirs=2
6493         local dir=$DIR/$tdir
6494
6495         rm -rf $dir
6496         test_mkdir -p $dir/dir
6497         for i in $(seq $numfiles); do
6498                 touch $dir/file$i
6499                 touch $dir/dir/file$i
6500         done
6501
6502         local numcomp=$($LFS getstripe --component-count $dir)
6503
6504         [[ $numcomp == 0 ]] && numcomp=1
6505
6506         # test lfs getstripe with --recursive
6507         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6508
6509         [[ $filenum -eq $((numfiles * 2)) ]] ||
6510                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6511         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6512         [[ $filenum -eq $numfiles ]] ||
6513                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6514         echo "$LFS getstripe showed obdidx or l_ost_idx"
6515
6516         # test lfs getstripe with file instead of dir
6517         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6518         [[ $filenum -eq 1 ]] ||
6519                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6520         echo "$LFS getstripe file1 passed"
6521
6522         #test lfs getstripe with --verbose
6523         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6524         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6525                 error "$LFS getstripe --verbose $dir: "\
6526                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6527         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6528                 error "$LFS getstripe $dir: showed lmm_magic"
6529
6530         #test lfs getstripe with -v prints lmm_fid
6531         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6532         local countfids=$((numdirs + numfiles * numcomp))
6533         [[ $filenum -eq $countfids ]] ||
6534                 error "$LFS getstripe -v $dir: "\
6535                       "got $filenum want $countfids lmm_fid"
6536         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6537                 error "$LFS getstripe $dir: showed lmm_fid by default"
6538         echo "$LFS getstripe --verbose passed"
6539
6540         #check for FID information
6541         local fid1=$($LFS getstripe --fid $dir/file1)
6542         local fid2=$($LFS getstripe --verbose $dir/file1 |
6543                      awk '/lmm_fid: / { print $2; exit; }')
6544         local fid3=$($LFS path2fid $dir/file1)
6545
6546         [ "$fid1" != "$fid2" ] &&
6547                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6548         [ "$fid1" != "$fid3" ] &&
6549                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6550         echo "$LFS getstripe --fid passed"
6551
6552         #test lfs getstripe with --obd
6553         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6554                 error "$LFS getstripe --obd wrong_uuid: should return error"
6555
6556         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6557
6558         local ostidx=1
6559         local obduuid=$(ostuuid_from_index $ostidx)
6560         local found=$($LFS getstripe -r --obd $obduuid $dir |
6561                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6562
6563         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6564         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6565                 ((filenum--))
6566         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6567                 ((filenum--))
6568
6569         [[ $found -eq $filenum ]] ||
6570                 error "$LFS getstripe --obd: found $found expect $filenum"
6571         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6572                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6573                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6574                 error "$LFS getstripe --obd: should not show file on other obd"
6575         echo "$LFS getstripe --obd passed"
6576 }
6577 run_test 56a "check $LFS getstripe"
6578
6579 test_56b() {
6580         local dir=$DIR/$tdir
6581         local numdirs=3
6582
6583         test_mkdir $dir
6584         for i in $(seq $numdirs); do
6585                 test_mkdir $dir/dir$i
6586         done
6587
6588         # test lfs getdirstripe default mode is non-recursion, which is
6589         # different from lfs getstripe
6590         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6591
6592         [[ $dircnt -eq 1 ]] ||
6593                 error "$LFS getdirstripe: found $dircnt, not 1"
6594         dircnt=$($LFS getdirstripe --recursive $dir |
6595                 grep -c lmv_stripe_count)
6596         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6597                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6598 }
6599 run_test 56b "check $LFS getdirstripe"
6600
6601 test_56bb() {
6602         verify_yaml_available || skip_env "YAML verification not installed"
6603         local output_file=$DIR/$tfile.out
6604
6605         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6606
6607         cat $output_file
6608         cat $output_file | verify_yaml || error "layout is not valid YAML"
6609 }
6610 run_test 56bb "check $LFS getdirstripe layout is YAML"
6611
6612 test_56c() {
6613         remote_ost_nodsh && skip "remote OST with nodsh"
6614
6615         local ost_idx=0
6616         local ost_name=$(ostname_from_index $ost_idx)
6617         local old_status=$(ost_dev_status $ost_idx)
6618         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6619
6620         [[ -z "$old_status" ]] ||
6621                 skip_env "OST $ost_name is in $old_status status"
6622
6623         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6624         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6625                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6626         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6627                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6628                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6629         fi
6630
6631         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6632                 error "$LFS df -v showing inactive devices"
6633         sleep_maxage
6634
6635         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6636
6637         [[ "$new_status" =~ "D" ]] ||
6638                 error "$ost_name status is '$new_status', missing 'D'"
6639         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6640                 [[ "$new_status" =~ "N" ]] ||
6641                         error "$ost_name status is '$new_status', missing 'N'"
6642         fi
6643         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6644                 [[ "$new_status" =~ "f" ]] ||
6645                         error "$ost_name status is '$new_status', missing 'f'"
6646         fi
6647
6648         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6649         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6650                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6651         [[ -z "$p" ]] && restore_lustre_params < $p || true
6652         sleep_maxage
6653
6654         new_status=$(ost_dev_status $ost_idx)
6655         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6656                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6657         # can't check 'f' as devices may actually be on flash
6658 }
6659 run_test 56c "check 'lfs df' showing device status"
6660
6661 test_56d() {
6662         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6663         local osts=$($LFS df -v $MOUNT | grep -c OST)
6664
6665         $LFS df $MOUNT
6666
6667         (( mdts == MDSCOUNT )) ||
6668                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6669         (( osts == OSTCOUNT )) ||
6670                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6671 }
6672 run_test 56d "'lfs df -v' prints only configured devices"
6673
6674 test_56e() {
6675         err_enoent=2 # No such file or directory
6676         err_eopnotsupp=95 # Operation not supported
6677
6678         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6679         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6680
6681         # Check for handling of path not exists
6682         output=$($LFS df $enoent_mnt 2>&1)
6683         ret=$?
6684
6685         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6686         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6687                 error "expect failure $err_enoent, not $ret"
6688
6689         # Check for handling of non-Lustre FS
6690         output=$($LFS df $notsup_mnt)
6691         ret=$?
6692
6693         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6694         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6695                 error "expect success $err_eopnotsupp, not $ret"
6696
6697         # Check for multiple LustreFS argument
6698         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6699         ret=$?
6700
6701         [[ $output -eq 3 && $ret -eq 0 ]] ||
6702                 error "expect success 3, not $output, rc = $ret"
6703
6704         # Check for correct non-Lustre FS handling among multiple
6705         # LustreFS argument
6706         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6707                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6708         ret=$?
6709
6710         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6711                 error "expect success 2, not $output, rc = $ret"
6712 }
6713 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6714
6715 NUMFILES=3
6716 NUMDIRS=3
6717 setup_56() {
6718         local local_tdir="$1"
6719         local local_numfiles="$2"
6720         local local_numdirs="$3"
6721         local dir_params="$4"
6722         local dir_stripe_params="$5"
6723
6724         if [ ! -d "$local_tdir" ] ; then
6725                 test_mkdir -p $dir_stripe_params $local_tdir
6726                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6727                 for i in $(seq $local_numfiles) ; do
6728                         touch $local_tdir/file$i
6729                 done
6730                 for i in $(seq $local_numdirs) ; do
6731                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6732                         for j in $(seq $local_numfiles) ; do
6733                                 touch $local_tdir/dir$i/file$j
6734                         done
6735                 done
6736         fi
6737 }
6738
6739 setup_56_special() {
6740         local local_tdir=$1
6741         local local_numfiles=$2
6742         local local_numdirs=$3
6743
6744         setup_56 $local_tdir $local_numfiles $local_numdirs
6745
6746         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6747                 for i in $(seq $local_numfiles) ; do
6748                         mknod $local_tdir/loop${i}b b 7 $i
6749                         mknod $local_tdir/null${i}c c 1 3
6750                         ln -s $local_tdir/file1 $local_tdir/link${i}
6751                 done
6752                 for i in $(seq $local_numdirs) ; do
6753                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6754                         mknod $local_tdir/dir$i/null${i}c c 1 3
6755                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6756                 done
6757         fi
6758 }
6759
6760 test_56g() {
6761         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6762         local expected=$(($NUMDIRS + 2))
6763
6764         setup_56 $dir $NUMFILES $NUMDIRS
6765
6766         # test lfs find with -name
6767         for i in $(seq $NUMFILES) ; do
6768                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6769
6770                 [ $nums -eq $expected ] ||
6771                         error "lfs find -name '*$i' $dir wrong: "\
6772                               "found $nums, expected $expected"
6773         done
6774 }
6775 run_test 56g "check lfs find -name"
6776
6777 test_56h() {
6778         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6779         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6780
6781         setup_56 $dir $NUMFILES $NUMDIRS
6782
6783         # test lfs find with ! -name
6784         for i in $(seq $NUMFILES) ; do
6785                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6786
6787                 [ $nums -eq $expected ] ||
6788                         error "lfs find ! -name '*$i' $dir wrong: "\
6789                               "found $nums, expected $expected"
6790         done
6791 }
6792 run_test 56h "check lfs find ! -name"
6793
6794 test_56i() {
6795         local dir=$DIR/$tdir
6796
6797         test_mkdir $dir
6798
6799         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6800         local out=$($cmd)
6801
6802         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6803 }
6804 run_test 56i "check 'lfs find -ost UUID' skips directories"
6805
6806 test_56j() {
6807         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6808
6809         setup_56_special $dir $NUMFILES $NUMDIRS
6810
6811         local expected=$((NUMDIRS + 1))
6812         local cmd="$LFS find -type d $dir"
6813         local nums=$($cmd | wc -l)
6814
6815         [ $nums -eq $expected ] ||
6816                 error "'$cmd' wrong: found $nums, expected $expected"
6817 }
6818 run_test 56j "check lfs find -type d"
6819
6820 test_56k() {
6821         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6822
6823         setup_56_special $dir $NUMFILES $NUMDIRS
6824
6825         local expected=$(((NUMDIRS + 1) * NUMFILES))
6826         local cmd="$LFS find -type f $dir"
6827         local nums=$($cmd | wc -l)
6828
6829         [ $nums -eq $expected ] ||
6830                 error "'$cmd' wrong: found $nums, expected $expected"
6831 }
6832 run_test 56k "check lfs find -type f"
6833
6834 test_56l() {
6835         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6836
6837         setup_56_special $dir $NUMFILES $NUMDIRS
6838
6839         local expected=$((NUMDIRS + NUMFILES))
6840         local cmd="$LFS find -type b $dir"
6841         local nums=$($cmd | wc -l)
6842
6843         [ $nums -eq $expected ] ||
6844                 error "'$cmd' wrong: found $nums, expected $expected"
6845 }
6846 run_test 56l "check lfs find -type b"
6847
6848 test_56m() {
6849         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6850
6851         setup_56_special $dir $NUMFILES $NUMDIRS
6852
6853         local expected=$((NUMDIRS + NUMFILES))
6854         local cmd="$LFS find -type c $dir"
6855         local nums=$($cmd | wc -l)
6856         [ $nums -eq $expected ] ||
6857                 error "'$cmd' wrong: found $nums, expected $expected"
6858 }
6859 run_test 56m "check lfs find -type c"
6860
6861 test_56n() {
6862         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6863         setup_56_special $dir $NUMFILES $NUMDIRS
6864
6865         local expected=$((NUMDIRS + NUMFILES))
6866         local cmd="$LFS find -type l $dir"
6867         local nums=$($cmd | wc -l)
6868
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871 }
6872 run_test 56n "check lfs find -type l"
6873
6874 test_56o() {
6875         local dir=$DIR/$tdir
6876
6877         setup_56 $dir $NUMFILES $NUMDIRS
6878         utime $dir/file1 > /dev/null || error "utime (1)"
6879         utime $dir/file2 > /dev/null || error "utime (2)"
6880         utime $dir/dir1 > /dev/null || error "utime (3)"
6881         utime $dir/dir2 > /dev/null || error "utime (4)"
6882         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6883         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6884
6885         local expected=4
6886         local nums=$($LFS find -mtime +0 $dir | wc -l)
6887
6888         [ $nums -eq $expected ] ||
6889                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6890
6891         expected=12
6892         cmd="$LFS find -mtime 0 $dir"
6893         nums=$($cmd | wc -l)
6894         [ $nums -eq $expected ] ||
6895                 error "'$cmd' wrong: found $nums, expected $expected"
6896 }
6897 run_test 56o "check lfs find -mtime for old files"
6898
6899 test_56ob() {
6900         local dir=$DIR/$tdir
6901         local expected=1
6902         local count=0
6903
6904         # just to make sure there is something that won't be found
6905         test_mkdir $dir
6906         touch $dir/$tfile.now
6907
6908         for age in year week day hour min; do
6909                 count=$((count + 1))
6910
6911                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6912                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6913                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6914
6915                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6916                 local nums=$($cmd | wc -l)
6917                 [ $nums -eq $expected ] ||
6918                         error "'$cmd' wrong: found $nums, expected $expected"
6919
6920                 cmd="$LFS find $dir -atime $count${age:0:1}"
6921                 nums=$($cmd | wc -l)
6922                 [ $nums -eq $expected ] ||
6923                         error "'$cmd' wrong: found $nums, expected $expected"
6924         done
6925
6926         sleep 2
6927         cmd="$LFS find $dir -ctime +1s -type f"
6928         nums=$($cmd | wc -l)
6929         (( $nums == $count * 2 + 1)) ||
6930                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6931 }
6932 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6933
6934 test_newerXY_base() {
6935         local x=$1
6936         local y=$2
6937         local dir=$DIR/$tdir
6938         local ref
6939         local negref
6940
6941         if [ $y == "t" ]; then
6942                 if [ $x == "b" ]; then
6943                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6944                 else
6945                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6946                 fi
6947         else
6948                 ref=$DIR/$tfile.newer.$x$y
6949                 touch $ref || error "touch $ref failed"
6950         fi
6951
6952         echo "before = $ref"
6953         sleep 2
6954         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6955         sleep 2
6956         if [ $y == "t" ]; then
6957                 if [ $x == "b" ]; then
6958                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6959                 else
6960                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6961                 fi
6962         else
6963                 negref=$DIR/$tfile.negnewer.$x$y
6964                 touch $negref || error "touch $negref failed"
6965         fi
6966
6967         echo "after = $negref"
6968         local cmd="$LFS find $dir -newer$x$y $ref"
6969         local nums=$(eval $cmd | wc -l)
6970         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6971
6972         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6973                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6974
6975         cmd="$LFS find $dir ! -newer$x$y $negref"
6976         nums=$(eval $cmd | wc -l)
6977         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6978                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6979
6980         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6981         nums=$(eval $cmd | wc -l)
6982         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6983                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6984
6985         rm -rf $DIR/*
6986 }
6987
6988 test_56oc() {
6989         test_newerXY_base "a" "a"
6990         test_newerXY_base "a" "m"
6991         test_newerXY_base "a" "c"
6992         test_newerXY_base "m" "a"
6993         test_newerXY_base "m" "m"
6994         test_newerXY_base "m" "c"
6995         test_newerXY_base "c" "a"
6996         test_newerXY_base "c" "m"
6997         test_newerXY_base "c" "c"
6998
6999         test_newerXY_base "a" "t"
7000         test_newerXY_base "m" "t"
7001         test_newerXY_base "c" "t"
7002
7003         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
7004            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7005                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
7006
7007         test_newerXY_base "b" "b"
7008         test_newerXY_base "b" "t"
7009 }
7010 run_test 56oc "check lfs find -newerXY work"
7011
7012 test_56od() {
7013         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7014                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
7015
7016         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7017                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7018
7019         local dir=$DIR/$tdir
7020         local ref=$DIR/$tfile.ref
7021         local negref=$DIR/$tfile.negref
7022
7023         mkdir $dir || error "mkdir $dir failed"
7024         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7025         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7026         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7027         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7028         touch $ref || error "touch $ref failed"
7029         # sleep 3 seconds at least
7030         sleep 3
7031
7032         local before=$(do_facet mds1 date +%s)
7033         local skew=$(($(date +%s) - before + 1))
7034
7035         if (( skew < 0 && skew > -5 )); then
7036                 sleep $((0 - skew + 1))
7037                 skew=0
7038         fi
7039
7040         # Set the dir stripe params to limit files all on MDT0,
7041         # otherwise we need to calc the max clock skew between
7042         # the client and MDTs.
7043         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7044         sleep 2
7045         touch $negref || error "touch $negref failed"
7046
7047         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7048         local nums=$($cmd | wc -l)
7049         local expected=$(((NUMFILES + 1) * NUMDIRS))
7050
7051         [ $nums -eq $expected ] ||
7052                 error "'$cmd' wrong: found $nums, expected $expected"
7053
7054         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7055         nums=$($cmd | wc -l)
7056         expected=$((NUMFILES + 1))
7057         [ $nums -eq $expected ] ||
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059
7060         [ $skew -lt 0 ] && return
7061
7062         local after=$(do_facet mds1 date +%s)
7063         local age=$((after - before + 1 + skew))
7064
7065         cmd="$LFS find $dir -btime -${age}s -type f"
7066         nums=$($cmd | wc -l)
7067         expected=$(((NUMFILES + 1) * NUMDIRS))
7068
7069         echo "Clock skew between client and server: $skew, age:$age"
7070         [ $nums -eq $expected ] ||
7071                 error "'$cmd' wrong: found $nums, expected $expected"
7072
7073         expected=$(($NUMDIRS + 1))
7074         cmd="$LFS find $dir -btime -${age}s -type d"
7075         nums=$($cmd | wc -l)
7076         [ $nums -eq $expected ] ||
7077                 error "'$cmd' wrong: found $nums, expected $expected"
7078         rm -f $ref $negref || error "Failed to remove $ref $negref"
7079 }
7080 run_test 56od "check lfs find -btime with units"
7081
7082 test_56p() {
7083         [ $RUNAS_ID -eq $UID ] &&
7084                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7085
7086         local dir=$DIR/$tdir
7087
7088         setup_56 $dir $NUMFILES $NUMDIRS
7089         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7090
7091         local expected=$NUMFILES
7092         local cmd="$LFS find -uid $RUNAS_ID $dir"
7093         local nums=$($cmd | wc -l)
7094
7095         [ $nums -eq $expected ] ||
7096                 error "'$cmd' wrong: found $nums, expected $expected"
7097
7098         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7099         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7100         nums=$($cmd | wc -l)
7101         [ $nums -eq $expected ] ||
7102                 error "'$cmd' wrong: found $nums, expected $expected"
7103 }
7104 run_test 56p "check lfs find -uid and ! -uid"
7105
7106 test_56q() {
7107         [ $RUNAS_ID -eq $UID ] &&
7108                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7109
7110         local dir=$DIR/$tdir
7111
7112         setup_56 $dir $NUMFILES $NUMDIRS
7113         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7114
7115         local expected=$NUMFILES
7116         local cmd="$LFS find -gid $RUNAS_GID $dir"
7117         local nums=$($cmd | wc -l)
7118
7119         [ $nums -eq $expected ] ||
7120                 error "'$cmd' wrong: found $nums, expected $expected"
7121
7122         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7123         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7124         nums=$($cmd | wc -l)
7125         [ $nums -eq $expected ] ||
7126                 error "'$cmd' wrong: found $nums, expected $expected"
7127 }
7128 run_test 56q "check lfs find -gid and ! -gid"
7129
7130 test_56r() {
7131         local dir=$DIR/$tdir
7132
7133         setup_56 $dir $NUMFILES $NUMDIRS
7134
7135         local expected=12
7136         local cmd="$LFS find -size 0 -type f -lazy $dir"
7137         local nums=$($cmd | wc -l)
7138
7139         [ $nums -eq $expected ] ||
7140                 error "'$cmd' wrong: found $nums, expected $expected"
7141         cmd="$LFS find -size 0 -type f $dir"
7142         nums=$($cmd | wc -l)
7143         [ $nums -eq $expected ] ||
7144                 error "'$cmd' wrong: found $nums, expected $expected"
7145
7146         expected=0
7147         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7148         nums=$($cmd | wc -l)
7149         [ $nums -eq $expected ] ||
7150                 error "'$cmd' wrong: found $nums, expected $expected"
7151         cmd="$LFS find ! -size 0 -type f $dir"
7152         nums=$($cmd | wc -l)
7153         [ $nums -eq $expected ] ||
7154                 error "'$cmd' wrong: found $nums, expected $expected"
7155
7156         echo "test" > $dir/$tfile
7157         echo "test2" > $dir/$tfile.2 && sync
7158         expected=1
7159         cmd="$LFS find -size 5c -type f -lazy $dir"
7160         nums=$($cmd | wc -l)
7161         [ $nums -eq $expected ] ||
7162                 error "'$cmd' wrong: found $nums, expected $expected"
7163         cmd="$LFS find -size 5c -type f $dir"
7164         nums=$($cmd | wc -l)
7165         [ $nums -eq $expected ] ||
7166                 error "'$cmd' wrong: found $nums, expected $expected"
7167
7168         expected=1
7169         cmd="$LFS find -size +5c -type f -lazy $dir"
7170         nums=$($cmd | wc -l)
7171         [ $nums -eq $expected ] ||
7172                 error "'$cmd' wrong: found $nums, expected $expected"
7173         cmd="$LFS find -size +5c -type f $dir"
7174         nums=$($cmd | wc -l)
7175         [ $nums -eq $expected ] ||
7176                 error "'$cmd' wrong: found $nums, expected $expected"
7177
7178         expected=2
7179         cmd="$LFS find -size +0 -type f -lazy $dir"
7180         nums=$($cmd | wc -l)
7181         [ $nums -eq $expected ] ||
7182                 error "'$cmd' wrong: found $nums, expected $expected"
7183         cmd="$LFS find -size +0 -type f $dir"
7184         nums=$($cmd | wc -l)
7185         [ $nums -eq $expected ] ||
7186                 error "'$cmd' wrong: found $nums, expected $expected"
7187
7188         expected=2
7189         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7190         nums=$($cmd | wc -l)
7191         [ $nums -eq $expected ] ||
7192                 error "'$cmd' wrong: found $nums, expected $expected"
7193         cmd="$LFS find ! -size -5c -type f $dir"
7194         nums=$($cmd | wc -l)
7195         [ $nums -eq $expected ] ||
7196                 error "'$cmd' wrong: found $nums, expected $expected"
7197
7198         expected=12
7199         cmd="$LFS find -size -5c -type f -lazy $dir"
7200         nums=$($cmd | wc -l)
7201         [ $nums -eq $expected ] ||
7202                 error "'$cmd' wrong: found $nums, expected $expected"
7203         cmd="$LFS find -size -5c -type f $dir"
7204         nums=$($cmd | wc -l)
7205         [ $nums -eq $expected ] ||
7206                 error "'$cmd' wrong: found $nums, expected $expected"
7207 }
7208 run_test 56r "check lfs find -size works"
7209
7210 test_56ra_sub() {
7211         local expected=$1
7212         local glimpses=$2
7213         local cmd="$3"
7214
7215         cancel_lru_locks $OSC
7216
7217         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7218         local nums=$($cmd | wc -l)
7219
7220         [ $nums -eq $expected ] ||
7221                 error "'$cmd' wrong: found $nums, expected $expected"
7222
7223         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7224
7225         if (( rpcs_before + glimpses != rpcs_after )); then
7226                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7227                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7228
7229                 if [[ $glimpses == 0 ]]; then
7230                         error "'$cmd' should not send glimpse RPCs to OST"
7231                 else
7232                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7233                 fi
7234         fi
7235 }
7236
7237 test_56ra() {
7238         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7239                 skip "MDS < 2.12.58 doesn't return LSOM data"
7240         local dir=$DIR/$tdir
7241         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7242
7243         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7244
7245         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7246         $LCTL set_param -n llite.*.statahead_agl=0
7247         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7248
7249         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7250         # open and close all files to ensure LSOM is updated
7251         cancel_lru_locks $OSC
7252         find $dir -type f | xargs cat > /dev/null
7253
7254         #   expect_found  glimpse_rpcs  command_to_run
7255         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7256         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7257         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7258         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7259
7260         echo "test" > $dir/$tfile
7261         echo "test2" > $dir/$tfile.2 && sync
7262         cancel_lru_locks $OSC
7263         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7264
7265         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7266         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7267         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7268         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7269
7270         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7271         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7272         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7273         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7274         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7275         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7276 }
7277 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7278
7279 test_56rb() {
7280         local dir=$DIR/$tdir
7281         local tmp=$TMP/$tfile.log
7282         local mdt_idx;
7283
7284         test_mkdir -p $dir || error "failed to mkdir $dir"
7285         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7286                 error "failed to setstripe $dir/$tfile"
7287         mdt_idx=$($LFS getdirstripe -i $dir)
7288         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7289
7290         stack_trap "rm -f $tmp" EXIT
7291         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7292         ! grep -q obd_uuid $tmp ||
7293                 error "failed to find --size +100K --ost 0 $dir"
7294         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7295         ! grep -q obd_uuid $tmp ||
7296                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7297 }
7298 run_test 56rb "check lfs find --size --ost/--mdt works"
7299
7300 test_56rc() {
7301         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7302         local dir=$DIR/$tdir
7303         local found
7304
7305         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7306         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7307         (( $MDSCOUNT > 2 )) &&
7308                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7309         mkdir $dir/$tdir-{1..10}
7310         touch $dir/$tfile-{1..10}
7311
7312         found=$($LFS find $dir --mdt-count 2 | wc -l)
7313         expect=11
7314         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7315
7316         found=$($LFS find $dir -T +1 | wc -l)
7317         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7318         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7319
7320         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7321         expect=11
7322         (( $found == $expect )) || error "found $found all_char, expect $expect"
7323
7324         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7325         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7326         (( $found == $expect )) || error "found $found all_char, expect $expect"
7327 }
7328 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7329
7330 test_56rd() {
7331         local dir=$DIR/$tdir
7332
7333         test_mkdir $dir
7334         rm -f $dir/*
7335
7336         mkfifo $dir/fifo || error "failed to create fifo file"
7337         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7338                 error "should not fail even cannot get projid from pipe file"
7339         found=$($LFS find $dir -t p --printf "%y")
7340         [[ "p" == $found ]] || error "found $found, expect p"
7341
7342         mknod $dir/chardev c 1 5 ||
7343                 error "failed to create character device file"
7344         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7345                 error "should not fail even cannot get projid from chardev file"
7346         found=$($LFS find $dir -t c --printf "%y")
7347         [[ "c" == $found ]] || error "found $found, expect c"
7348
7349         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7350         (( found == 2 )) || error "unable to list all files"
7351 }
7352 run_test 56rd "check lfs find --printf special files"
7353
7354 test_56s() { # LU-611 #LU-9369
7355         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7356
7357         local dir=$DIR/$tdir
7358         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7359
7360         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7361         for i in $(seq $NUMDIRS); do
7362                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7363         done
7364
7365         local expected=$NUMDIRS
7366         local cmd="$LFS find -c $OSTCOUNT $dir"
7367         local nums=$($cmd | wc -l)
7368
7369         [ $nums -eq $expected ] || {
7370                 $LFS getstripe -R $dir
7371                 error "'$cmd' wrong: found $nums, expected $expected"
7372         }
7373
7374         expected=$((NUMDIRS + onestripe))
7375         cmd="$LFS find -stripe-count +0 -type f $dir"
7376         nums=$($cmd | wc -l)
7377         [ $nums -eq $expected ] || {
7378                 $LFS getstripe -R $dir
7379                 error "'$cmd' wrong: found $nums, expected $expected"
7380         }
7381
7382         expected=$onestripe
7383         cmd="$LFS find -stripe-count 1 -type f $dir"
7384         nums=$($cmd | wc -l)
7385         [ $nums -eq $expected ] || {
7386                 $LFS getstripe -R $dir
7387                 error "'$cmd' wrong: found $nums, expected $expected"
7388         }
7389
7390         cmd="$LFS find -stripe-count -2 -type f $dir"
7391         nums=$($cmd | wc -l)
7392         [ $nums -eq $expected ] || {
7393                 $LFS getstripe -R $dir
7394                 error "'$cmd' wrong: found $nums, expected $expected"
7395         }
7396
7397         expected=0
7398         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7399         nums=$($cmd | wc -l)
7400         [ $nums -eq $expected ] || {
7401                 $LFS getstripe -R $dir
7402                 error "'$cmd' wrong: found $nums, expected $expected"
7403         }
7404 }
7405 run_test 56s "check lfs find -stripe-count works"
7406
7407 test_56t() { # LU-611 #LU-9369
7408         local dir=$DIR/$tdir
7409
7410         setup_56 $dir 0 $NUMDIRS
7411         for i in $(seq $NUMDIRS); do
7412                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7413         done
7414
7415         local expected=$NUMDIRS
7416         local cmd="$LFS find -S 8M $dir"
7417         local nums=$($cmd | wc -l)
7418
7419         [ $nums -eq $expected ] || {
7420                 $LFS getstripe -R $dir
7421                 error "'$cmd' wrong: found $nums, expected $expected"
7422         }
7423         rm -rf $dir
7424
7425         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7426
7427         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7428
7429         expected=$(((NUMDIRS + 1) * NUMFILES))
7430         cmd="$LFS find -stripe-size 512k -type f $dir"
7431         nums=$($cmd | wc -l)
7432         [ $nums -eq $expected ] ||
7433                 error "'$cmd' wrong: found $nums, expected $expected"
7434
7435         cmd="$LFS find -stripe-size +320k -type f $dir"
7436         nums=$($cmd | wc -l)
7437         [ $nums -eq $expected ] ||
7438                 error "'$cmd' wrong: found $nums, expected $expected"
7439
7440         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7441         cmd="$LFS find -stripe-size +200k -type f $dir"
7442         nums=$($cmd | wc -l)
7443         [ $nums -eq $expected ] ||
7444                 error "'$cmd' wrong: found $nums, expected $expected"
7445
7446         cmd="$LFS find -stripe-size -640k -type f $dir"
7447         nums=$($cmd | wc -l)
7448         [ $nums -eq $expected ] ||
7449                 error "'$cmd' wrong: found $nums, expected $expected"
7450
7451         expected=4
7452         cmd="$LFS find -stripe-size 256k -type f $dir"
7453         nums=$($cmd | wc -l)
7454         [ $nums -eq $expected ] ||
7455                 error "'$cmd' wrong: found $nums, expected $expected"
7456
7457         cmd="$LFS find -stripe-size -320k -type f $dir"
7458         nums=$($cmd | wc -l)
7459         [ $nums -eq $expected ] ||
7460                 error "'$cmd' wrong: found $nums, expected $expected"
7461
7462         expected=0
7463         cmd="$LFS find -stripe-size 1024k -type f $dir"
7464         nums=$($cmd | wc -l)
7465         [ $nums -eq $expected ] ||
7466                 error "'$cmd' wrong: found $nums, expected $expected"
7467 }
7468 run_test 56t "check lfs find -stripe-size works"
7469
7470 test_56u() { # LU-611
7471         local dir=$DIR/$tdir
7472
7473         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7474
7475         if [[ $OSTCOUNT -gt 1 ]]; then
7476                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7477                 onestripe=4
7478         else
7479                 onestripe=0
7480         fi
7481
7482         local expected=$(((NUMDIRS + 1) * NUMFILES))
7483         local cmd="$LFS find -stripe-index 0 -type f $dir"
7484         local nums=$($cmd | wc -l)
7485
7486         [ $nums -eq $expected ] ||
7487                 error "'$cmd' wrong: found $nums, expected $expected"
7488
7489         expected=$onestripe
7490         cmd="$LFS find -stripe-index 1 -type f $dir"
7491         nums=$($cmd | wc -l)
7492         [ $nums -eq $expected ] ||
7493                 error "'$cmd' wrong: found $nums, expected $expected"
7494
7495         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7496         nums=$($cmd | wc -l)
7497         [ $nums -eq $expected ] ||
7498                 error "'$cmd' wrong: found $nums, expected $expected"
7499
7500         expected=0
7501         # This should produce an error and not return any files
7502         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7503         nums=$($cmd 2>/dev/null | wc -l)
7504         [ $nums -eq $expected ] ||
7505                 error "'$cmd' wrong: found $nums, expected $expected"
7506
7507         if [[ $OSTCOUNT -gt 1 ]]; then
7508                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7509                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7510                 nums=$($cmd | wc -l)
7511                 [ $nums -eq $expected ] ||
7512                         error "'$cmd' wrong: found $nums, expected $expected"
7513         fi
7514 }
7515 run_test 56u "check lfs find -stripe-index works"
7516
7517 test_56v() {
7518         local mdt_idx=0
7519         local dir=$DIR/$tdir
7520
7521         setup_56 $dir $NUMFILES $NUMDIRS
7522
7523         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7524         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7525
7526         for file in $($LFS find -m $UUID $dir); do
7527                 file_midx=$($LFS getstripe -m $file)
7528                 [ $file_midx -eq $mdt_idx ] ||
7529                         error "lfs find -m $UUID != getstripe -m $file_midx"
7530         done
7531 }
7532 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7533
7534 test_56wa() {
7535         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7537
7538         local dir=$DIR/$tdir
7539
7540         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7541         stack_trap "rm -rf $dir"
7542
7543         local stripe_size=$($LFS getstripe -S -d $dir) ||
7544                 error "$LFS getstripe -S -d $dir failed"
7545         stripe_size=${stripe_size%% *}
7546
7547         local file_size=$((stripe_size * OSTCOUNT))
7548         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7549         local required_space=$((file_num * file_size))
7550         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7551                            head -n1)
7552         (( free_space >= required_space / 1024 )) ||
7553                 skip_env "need $required_space, have $free_space kbytes"
7554
7555         local dd_bs=65536
7556         local dd_count=$((file_size / dd_bs))
7557
7558         # write data into the files
7559         local i
7560         local j
7561         local file
7562
7563         for ((i = 1; i <= NUMFILES; i++ )); do
7564                 file=$dir/file$i
7565                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7566                         error "write data into $file failed"
7567         done
7568         for ((i = 1; i <= NUMDIRS; i++ )); do
7569                 for ((j = 1; j <= NUMFILES; j++ )); do
7570                         file=$dir/dir$i/file$j
7571                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7572                                 error "write data into $file failed"
7573                 done
7574         done
7575
7576         # $LFS_MIGRATE will fail if hard link migration is unsupported
7577         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7578                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7579                         error "creating links to $dir/dir1/file1 failed"
7580         fi
7581
7582         local expected=-1
7583
7584         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7585
7586         # lfs_migrate file
7587         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7588
7589         echo "$cmd"
7590         eval $cmd || error "$cmd failed"
7591
7592         check_stripe_count $dir/file1 $expected
7593
7594         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7595                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7596                 # OST 1 if it is on OST 0. This file is small enough to
7597                 # be on only one stripe.
7598                 file=$dir/migr_1_ost
7599                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7600                         error "write data into $file failed"
7601                 local obdidx=$($LFS getstripe -i $file)
7602                 local oldmd5=$(md5sum $file)
7603                 local newobdidx=0
7604
7605                 (( obdidx != 0 )) || newobdidx=1
7606                 cmd="$LFS migrate -i $newobdidx $file"
7607                 echo $cmd
7608                 eval $cmd || error "$cmd failed"
7609
7610                 local realobdix=$($LFS getstripe -i $file)
7611                 local newmd5=$(md5sum $file)
7612
7613                 (( $newobdidx == $realobdix )) ||
7614                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7615                 [[ "$oldmd5" == "$newmd5" ]] ||
7616                         error "md5sum differ: $oldmd5, $newmd5"
7617         fi
7618
7619         # lfs_migrate dir
7620         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7621         echo "$cmd"
7622         eval $cmd || error "$cmd failed"
7623
7624         for (( j = 1; j <= NUMFILES; j++ )); do
7625                 check_stripe_count $dir/dir1/file$j $expected
7626         done
7627
7628         # lfs_migrate works with lfs find
7629         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7630              $LFS_MIGRATE -y -c $expected"
7631         echo "$cmd"
7632         eval $cmd || error "$cmd failed"
7633
7634         for (( i = 2; i <= NUMFILES; i++ )); do
7635                 check_stripe_count $dir/file$i $expected
7636         done
7637         for (( i = 2; i <= NUMDIRS; i++ )); do
7638                 for (( j = 1; j <= NUMFILES; j++ )); do
7639                         check_stripe_count $dir/dir$i/file$j $expected
7640                 done
7641         done
7642 }
7643 run_test 56wa "check lfs_migrate -c stripe_count works"
7644
7645 test_56wb() {
7646         local file1=$DIR/$tdir/file1
7647         local create_pool=false
7648         local initial_pool=$($LFS getstripe -p $DIR)
7649         local pool_list=()
7650         local pool=""
7651
7652         echo -n "Creating test dir..."
7653         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7654         echo "done."
7655
7656         echo -n "Creating test file..."
7657         touch $file1 || error "cannot create file"
7658         echo "done."
7659
7660         echo -n "Detecting existing pools..."
7661         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7662
7663         if [ ${#pool_list[@]} -gt 0 ]; then
7664                 echo "${pool_list[@]}"
7665                 for thispool in "${pool_list[@]}"; do
7666                         if [[ -z "$initial_pool" ||
7667                               "$initial_pool" != "$thispool" ]]; then
7668                                 pool="$thispool"
7669                                 echo "Using existing pool '$pool'"
7670                                 break
7671                         fi
7672                 done
7673         else
7674                 echo "none detected."
7675         fi
7676         if [ -z "$pool" ]; then
7677                 pool=${POOL:-testpool}
7678                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7679                 echo -n "Creating pool '$pool'..."
7680                 create_pool=true
7681                 pool_add $pool &> /dev/null ||
7682                         error "pool_add failed"
7683                 echo "done."
7684
7685                 echo -n "Adding target to pool..."
7686                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7687                         error "pool_add_targets failed"
7688                 echo "done."
7689         fi
7690
7691         echo -n "Setting pool using -p option..."
7692         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7693                 error "migrate failed rc = $?"
7694         echo "done."
7695
7696         echo -n "Verifying test file is in pool after migrating..."
7697         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7698                 error "file was not migrated to pool $pool"
7699         echo "done."
7700
7701         echo -n "Removing test file from pool '$pool'..."
7702         # "lfs migrate $file" won't remove the file from the pool
7703         # until some striping information is changed.
7704         $LFS migrate -c 1 $file1 &> /dev/null ||
7705                 error "cannot remove from pool"
7706         [ "$($LFS getstripe -p $file1)" ] &&
7707                 error "pool still set"
7708         echo "done."
7709
7710         echo -n "Setting pool using --pool option..."
7711         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7712                 error "migrate failed rc = $?"
7713         echo "done."
7714
7715         # Clean up
7716         rm -f $file1
7717         if $create_pool; then
7718                 destroy_test_pools 2> /dev/null ||
7719                         error "destroy test pools failed"
7720         fi
7721 }
7722 run_test 56wb "check lfs_migrate pool support"
7723
7724 test_56wc() {
7725         local file1="$DIR/$tdir/$tfile"
7726         local md5
7727         local parent_ssize
7728         local parent_scount
7729         local cur_ssize
7730         local cur_scount
7731         local orig_ssize
7732         local new_scount
7733         local cur_comp
7734
7735         echo -n "Creating test dir..."
7736         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7737         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7738                 error "cannot set stripe by '-S 1M -c 1'"
7739         echo "done"
7740
7741         echo -n "Setting initial stripe for test file..."
7742         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7743                 error "cannot set stripe"
7744         cur_ssize=$($LFS getstripe -S "$file1")
7745         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7746         echo "done."
7747
7748         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7749         stack_trap "rm -f $file1"
7750         md5="$(md5sum $file1)"
7751
7752         # File currently set to -S 512K -c 1
7753
7754         # Ensure -c and -S options are rejected when -R is set
7755         echo -n "Verifying incompatible options are detected..."
7756         $LFS_MIGRATE -R -c 1 "$file1" &&
7757                 error "incompatible -R and -c options not detected"
7758         $LFS_MIGRATE -R -S 1M "$file1" &&
7759                 error "incompatible -R and -S options not detected"
7760         $LFS_MIGRATE -R -p pool "$file1" &&
7761                 error "incompatible -R and -p options not detected"
7762         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7763                 error "incompatible -R and -E options not detected"
7764         $LFS_MIGRATE -R -A "$file1" &&
7765                 error "incompatible -R and -A options not detected"
7766         $LFS_MIGRATE -A -c 1 "$file1" &&
7767                 error "incompatible -A and -c options not detected"
7768         $LFS_MIGRATE -A -S 1M "$file1" &&
7769                 error "incompatible -A and -S options not detected"
7770         $LFS_MIGRATE -A -p pool "$file1" &&
7771                 error "incompatible -A and -p options not detected"
7772         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7773                 error "incompatible -A and -E options not detected"
7774         echo "done."
7775
7776         # Ensure unrecognized options are passed through to 'lfs migrate'
7777         echo -n "Verifying -S option is passed through to lfs migrate..."
7778         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7779         cur_ssize=$($LFS getstripe -S "$file1")
7780         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7781         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7782         echo "done."
7783
7784         # File currently set to -S 1M -c 1
7785
7786         # Ensure long options are supported
7787         echo -n "Verifying long options supported..."
7788         $LFS_MIGRATE --non-block "$file1" ||
7789                 error "long option without argument not supported"
7790         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7791                 error "long option with argument not supported"
7792         cur_ssize=$($LFS getstripe -S "$file1")
7793         (( cur_ssize == 524288 )) ||
7794                 error "migrate --stripe-size $cur_ssize != 524288"
7795         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7796         echo "done."
7797
7798         # File currently set to -S 512K -c 1
7799
7800         if (( OSTCOUNT > 1 )); then
7801                 echo -n "Verifying explicit stripe count can be set..."
7802                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7803                 cur_scount=$($LFS getstripe -c "$file1")
7804                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7805                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7806                         error "file data has changed (3)"
7807                 echo "done."
7808         fi
7809
7810         # File currently set to -S 512K -c 1 or -S 512K -c 2
7811
7812         # Ensure parent striping is used if -R is set, and no stripe
7813         # count or size is specified
7814         echo -n "Setting stripe for parent directory..."
7815         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7816                 error "cannot set stripe '-S 2M -c 1'"
7817         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7818         echo "done."
7819
7820         echo -n "Verifying restripe option uses parent stripe settings..."
7821         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7822         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7823         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7824         cur_ssize=$($LFS getstripe -S "$file1")
7825         (( cur_ssize == parent_ssize )) ||
7826                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7827         cur_scount=$($LFS getstripe -c "$file1")
7828         (( cur_scount == parent_scount )) ||
7829                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7830         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7831         echo "done."
7832
7833         # File currently set to -S 1M -c 1
7834
7835         # Ensure striping is preserved if -R is not set, and no stripe
7836         # count or size is specified
7837         echo -n "Verifying striping size preserved when not specified..."
7838         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7839         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7840                 error "cannot set stripe on parent directory"
7841         $LFS_MIGRATE "$file1" || error "migrate failed"
7842         cur_ssize=$($LFS getstripe -S "$file1")
7843         (( cur_ssize == orig_ssize )) ||
7844                 error "migrate by default $cur_ssize != $orig_ssize"
7845         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7846         echo "done."
7847
7848         # Ensure file name properly detected when final option has no argument
7849         echo -n "Verifying file name properly detected..."
7850         $LFS_MIGRATE "$file1" ||
7851                 error "file name interpreted as option argument"
7852         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7853         echo "done."
7854
7855         # Ensure PFL arguments are passed through properly
7856         echo -n "Verifying PFL options passed through..."
7857         new_scount=$(((OSTCOUNT + 1) / 2))
7858         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7859                 error "migrate PFL arguments failed"
7860         cur_comp=$($LFS getstripe --comp-count $file1)
7861         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7862         cur_scount=$($LFS getstripe --stripe-count $file1)
7863         (( cur_scount == new_scount)) ||
7864                 error "PFL stripe count $cur_scount != $new_scount"
7865         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7866         echo "done."
7867 }
7868 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7869
7870 test_56wd() {
7871         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7872
7873         local file1=$DIR/$tdir/$tfile
7874
7875         echo -n "Creating test dir..."
7876         test_mkdir $DIR/$tdir || error "cannot create dir"
7877         echo "done."
7878
7879         echo -n "Creating test file..."
7880         echo "$tfile" > $file1
7881         echo "done."
7882
7883         # Ensure 'lfs migrate' will fail by using a non-existent option,
7884         # and make sure rsync is not called to recover
7885         echo -n "Make sure --no-rsync option works..."
7886         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7887                 grep -q 'refusing to fall back to rsync' ||
7888                 error "rsync was called with --no-rsync set"
7889         echo "done."
7890
7891         # Ensure rsync is called without trying 'lfs migrate' first
7892         echo -n "Make sure --rsync option works..."
7893         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7894                 grep -q 'falling back to rsync' &&
7895                 error "lfs migrate was called with --rsync set"
7896         echo "done."
7897 }
7898 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7899
7900 test_56we() {
7901         local td=$DIR/$tdir
7902         local tf=$td/$tfile
7903
7904         test_mkdir $td || error "cannot create $td"
7905         touch $tf || error "cannot touch $tf"
7906
7907         echo -n "Make sure --non-direct|-D works..."
7908         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7909                 grep -q "lfs migrate --non-direct" ||
7910                 error "--non-direct option cannot work correctly"
7911         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7912                 grep -q "lfs migrate -D" ||
7913                 error "-D option cannot work correctly"
7914         echo "done."
7915 }
7916 run_test 56we "check lfs_migrate --non-direct|-D support"
7917
7918 test_56x() {
7919         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7920         check_swap_layouts_support
7921
7922         local dir=$DIR/$tdir
7923         local ref1=/etc/passwd
7924         local file1=$dir/file1
7925
7926         test_mkdir $dir || error "creating dir $dir"
7927         $LFS setstripe -c 2 $file1
7928         cp $ref1 $file1
7929         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7930         stripe=$($LFS getstripe -c $file1)
7931         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7932         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7933
7934         # clean up
7935         rm -f $file1
7936 }
7937 run_test 56x "lfs migration support"
7938
7939 test_56xa() {
7940         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7941         check_swap_layouts_support
7942
7943         local dir=$DIR/$tdir/$testnum
7944
7945         test_mkdir -p $dir
7946
7947         local ref1=/etc/passwd
7948         local file1=$dir/file1
7949
7950         $LFS setstripe -c 2 $file1
7951         cp $ref1 $file1
7952         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7953
7954         local stripe=$($LFS getstripe -c $file1)
7955
7956         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7957         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7958
7959         # clean up
7960         rm -f $file1
7961 }
7962 run_test 56xa "lfs migration --block support"
7963
7964 check_migrate_links() {
7965         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7966         local dir="$1"
7967         local file1="$dir/file1"
7968         local begin="$2"
7969         local count="$3"
7970         local runas="$4"
7971         local total_count=$(($begin + $count - 1))
7972         local symlink_count=10
7973         local uniq_count=10
7974
7975         if [ ! -f "$file1" ]; then
7976                 echo -n "creating initial file..."
7977                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7978                         error "cannot setstripe initial file"
7979                 echo "done"
7980
7981                 echo -n "creating symlinks..."
7982                 for s in $(seq 1 $symlink_count); do
7983                         ln -s "$file1" "$dir/slink$s" ||
7984                                 error "cannot create symlinks"
7985                 done
7986                 echo "done"
7987
7988                 echo -n "creating nonlinked files..."
7989                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7990                         error "cannot create nonlinked files"
7991                 echo "done"
7992         fi
7993
7994         # create hard links
7995         if [ ! -f "$dir/file$total_count" ]; then
7996                 echo -n "creating hard links $begin:$total_count..."
7997                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7998                         /dev/null || error "cannot create hard links"
7999                 echo "done"
8000         fi
8001
8002         echo -n "checking number of hard links listed in xattrs..."
8003         local fid=$($LFS getstripe -F "$file1")
8004         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
8005
8006         echo "${#paths[*]}"
8007         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
8008                         skip "hard link list has unexpected size, skipping test"
8009         fi
8010         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
8011                         error "link names should exceed xattrs size"
8012         fi
8013
8014         echo -n "migrating files..."
8015         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8016         local rc=$?
8017         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8018         echo "done"
8019
8020         # make sure all links have been properly migrated
8021         echo -n "verifying files..."
8022         fid=$($LFS getstripe -F "$file1") ||
8023                 error "cannot get fid for file $file1"
8024         for i in $(seq 2 $total_count); do
8025                 local fid2=$($LFS getstripe -F $dir/file$i)
8026
8027                 [ "$fid2" == "$fid" ] ||
8028                         error "migrated hard link has mismatched FID"
8029         done
8030
8031         # make sure hard links were properly detected, and migration was
8032         # performed only once for the entire link set; nonlinked files should
8033         # also be migrated
8034         local actual=$(grep -c 'done' <<< "$migrate_out")
8035         local expected=$(($uniq_count + 1))
8036
8037         [ "$actual" -eq  "$expected" ] ||
8038                 error "hard links individually migrated ($actual != $expected)"
8039
8040         # make sure the correct number of hard links are present
8041         local hardlinks=$(stat -c '%h' "$file1")
8042
8043         [ $hardlinks -eq $total_count ] ||
8044                 error "num hard links $hardlinks != $total_count"
8045         echo "done"
8046
8047         return 0
8048 }
8049
8050 test_56xb() {
8051         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8052                 skip "Need MDS version at least 2.10.55"
8053
8054         local dir="$DIR/$tdir"
8055
8056         test_mkdir "$dir" || error "cannot create dir $dir"
8057
8058         echo "testing lfs migrate mode when all links fit within xattrs"
8059         check_migrate_links "$dir" 2 99
8060
8061         echo "testing rsync mode when all links fit within xattrs"
8062         check_migrate_links --rsync "$dir" 2 99
8063
8064         echo "testing lfs migrate mode when all links do not fit within xattrs"
8065         check_migrate_links "$dir" 101 100
8066
8067         echo "testing rsync mode when all links do not fit within xattrs"
8068         check_migrate_links --rsync "$dir" 101 100
8069
8070         chown -R $RUNAS_ID $dir
8071         echo "testing non-root lfs migrate mode when not all links are in xattr"
8072         check_migrate_links "$dir" 101 100 "$RUNAS"
8073
8074         # clean up
8075         rm -rf $dir
8076 }
8077 run_test 56xb "lfs migration hard link support"
8078
8079 test_56xc() {
8080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8081
8082         local dir="$DIR/$tdir"
8083
8084         test_mkdir "$dir" || error "cannot create dir $dir"
8085
8086         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8087         echo -n "Setting initial stripe for 20MB test file..."
8088         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8089                 error "cannot setstripe 20MB file"
8090         echo "done"
8091         echo -n "Sizing 20MB test file..."
8092         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8093         echo "done"
8094         echo -n "Verifying small file autostripe count is 1..."
8095         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8096                 error "cannot migrate 20MB file"
8097         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8098                 error "cannot get stripe for $dir/20mb"
8099         [ $stripe_count -eq 1 ] ||
8100                 error "unexpected stripe count $stripe_count for 20MB file"
8101         rm -f "$dir/20mb"
8102         echo "done"
8103
8104         # Test 2: File is small enough to fit within the available space on
8105         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8106         # have at least an additional 1KB for each desired stripe for test 3
8107         echo -n "Setting stripe for 1GB test file..."
8108         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8109         echo "done"
8110         echo -n "Sizing 1GB test file..."
8111         # File size is 1GB + 3KB
8112         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8113         echo "done"
8114
8115         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8116         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8117         if (( avail > 524288 * OSTCOUNT )); then
8118                 echo -n "Migrating 1GB file..."
8119                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8120                         error "cannot migrate 1GB file"
8121                 echo "done"
8122                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8123                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8124                         error "cannot getstripe for 1GB file"
8125                 [ $stripe_count -eq 2 ] ||
8126                         error "unexpected stripe count $stripe_count != 2"
8127                 echo "done"
8128         fi
8129
8130         # Test 3: File is too large to fit within the available space on
8131         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8132         if [ $OSTCOUNT -ge 3 ]; then
8133                 # The required available space is calculated as
8134                 # file size (1GB + 3KB) / OST count (3).
8135                 local kb_per_ost=349526
8136
8137                 echo -n "Migrating 1GB file with limit..."
8138                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8139                         error "cannot migrate 1GB file with limit"
8140                 echo "done"
8141
8142                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8143                 echo -n "Verifying 1GB autostripe count with limited space..."
8144                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8145                         error "unexpected stripe count $stripe_count (min 3)"
8146                 echo "done"
8147         fi
8148
8149         # clean up
8150         rm -rf $dir
8151 }
8152 run_test 56xc "lfs migration autostripe"
8153
8154 test_56xd() {
8155         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8156
8157         local dir=$DIR/$tdir
8158         local f_mgrt=$dir/$tfile.mgrt
8159         local f_yaml=$dir/$tfile.yaml
8160         local f_copy=$dir/$tfile.copy
8161         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8162         local layout_copy="-c 2 -S 2M -i 1"
8163         local yamlfile=$dir/yamlfile
8164         local layout_before;
8165         local layout_after;
8166
8167         test_mkdir "$dir" || error "cannot create dir $dir"
8168         stack_trap "rm -rf $dir"
8169         $LFS setstripe $layout_yaml $f_yaml ||
8170                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8171         $LFS getstripe --yaml $f_yaml > $yamlfile
8172         $LFS setstripe $layout_copy $f_copy ||
8173                 error "cannot setstripe $f_copy with layout $layout_copy"
8174         touch $f_mgrt
8175         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8176
8177         # 1. test option --yaml
8178         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8179                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8180         layout_before=$(get_layout_param $f_yaml)
8181         layout_after=$(get_layout_param $f_mgrt)
8182         [ "$layout_after" == "$layout_before" ] ||
8183                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8184
8185         # 2. test option --copy
8186         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8187                 error "cannot migrate $f_mgrt with --copy $f_copy"
8188         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8189         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8190         [ "$layout_after" == "$layout_before" ] ||
8191                 error "lfs_migrate --copy: $layout_after != $layout_before"
8192 }
8193 run_test 56xd "check lfs_migrate --yaml and --copy support"
8194
8195 test_56xe() {
8196         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8197
8198         local dir=$DIR/$tdir
8199         local f_comp=$dir/$tfile
8200         local layout="-E 1M -S 512K -E 2M -c 2 -E 3M -c 2 -E eof -c $OSTCOUNT"
8201         local layout_before=""
8202         local layout_after=""
8203
8204         test_mkdir "$dir" || error "cannot create dir $dir"
8205         stack_trap "rm -rf $dir"
8206         $LFS setstripe $layout $f_comp ||
8207                 error "cannot setstripe $f_comp with layout $layout"
8208         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8209         dd if=/dev/zero of=$f_comp bs=1M count=4
8210
8211         # 1. migrate a comp layout file by lfs_migrate
8212         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8213         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8214         idx_before=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8215                      tr '\n' ' ')
8216         [ "$layout_before" == "$layout_after" ] ||
8217                 error "lfs_migrate: $layout_before != $layout_after"
8218
8219         # 2. migrate a comp layout file by lfs migrate
8220         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8221         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8222         idx_after=$($LFS getstripe $f_comp | awk '$2 == "0:" { print $5 }' |
8223                      tr '\n' ' ')
8224         [ "$layout_before" == "$layout_after" ] ||
8225                 error "lfs migrate: $layout_before != $layout_after"
8226
8227         # this may not fail every time with a broken lfs migrate, but will fail
8228         # often enough to notice, and will not have false positives very often
8229         [ "$idx_before" != "$idx_after" ] ||
8230                 error "lfs migrate: $idx_before == $idx_after"
8231 }
8232 run_test 56xe "migrate a composite layout file"
8233
8234 test_56xf() {
8235         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8236
8237         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8238                 skip "Need server version at least 2.13.53"
8239
8240         local dir=$DIR/$tdir
8241         local f_comp=$dir/$tfile
8242         local layout="-E 1M -c1 -E -1 -c2"
8243         local fid_before=""
8244         local fid_after=""
8245
8246         test_mkdir "$dir" || error "cannot create dir $dir"
8247         stack_trap "rm -rf $dir"
8248         $LFS setstripe $layout $f_comp ||
8249                 error "cannot setstripe $f_comp with layout $layout"
8250         fid_before=$($LFS getstripe --fid $f_comp)
8251         dd if=/dev/zero of=$f_comp bs=1M count=4
8252
8253         # 1. migrate a comp layout file to a comp layout
8254         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8255         fid_after=$($LFS getstripe --fid $f_comp)
8256         [ "$fid_before" == "$fid_after" ] ||
8257                 error "comp-to-comp migrate: $fid_before != $fid_after"
8258
8259         # 2. migrate a comp layout file to a plain layout
8260         $LFS migrate -c2 $f_comp ||
8261                 error "cannot migrate $f_comp by lfs migrate"
8262         fid_after=$($LFS getstripe --fid $f_comp)
8263         [ "$fid_before" == "$fid_after" ] ||
8264                 error "comp-to-plain migrate: $fid_before != $fid_after"
8265
8266         # 3. migrate a plain layout file to a comp layout
8267         $LFS migrate $layout $f_comp ||
8268                 error "cannot migrate $f_comp by lfs migrate"
8269         fid_after=$($LFS getstripe --fid $f_comp)
8270         [ "$fid_before" == "$fid_after" ] ||
8271                 error "plain-to-comp migrate: $fid_before != $fid_after"
8272 }
8273 run_test 56xf "FID is not lost during migration of a composite layout file"
8274
8275 check_file_ost_range() {
8276         local file="$1"
8277         shift
8278         local range="$*"
8279         local -a file_range
8280         local idx
8281
8282         file_range=($($LFS getstripe -y "$file" |
8283                 awk '/l_ost_idx:/ { print $NF }'))
8284
8285         if [[ "${#file_range[@]}" = 0 ]]; then
8286                 echo "No osts found for $file"
8287                 return 1
8288         fi
8289
8290         for idx in "${file_range[@]}"; do
8291                 [[ " $range " =~ " $idx " ]] ||
8292                         return 1
8293         done
8294
8295         return 0
8296 }
8297
8298 sub_test_56xg() {
8299         local stripe_opt="$1"
8300         local pool="$2"
8301         shift 2
8302         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8303
8304         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8305                 error "Fail to migrate $tfile on $pool"
8306         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8307                 error "$tfile is not in pool $pool"
8308         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8309                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8310 }
8311
8312 test_56xg() {
8313         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8314         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8315         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8316                 skip "Need MDS version newer than 2.14.52"
8317
8318         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8319         local -a pool_ranges=("0 0" "1 1" "0 1")
8320
8321         # init pools
8322         for i in "${!pool_names[@]}"; do
8323                 pool_add ${pool_names[$i]} ||
8324                         error "pool_add failed (pool: ${pool_names[$i]})"
8325                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8326                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8327         done
8328
8329         # init the file to migrate
8330         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8331                 error "Unable to create $tfile on OST1"
8332         stack_trap "rm -f $DIR/$tfile"
8333         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8334                 error "Unable to write on $tfile"
8335
8336         echo "1. migrate $tfile on pool ${pool_names[0]}"
8337         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8338
8339         echo "2. migrate $tfile on pool ${pool_names[2]}"
8340         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8341
8342         echo "3. migrate $tfile on pool ${pool_names[1]}"
8343         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8344
8345         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8346         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8347         echo
8348
8349         # Clean pools
8350         destroy_test_pools ||
8351                 error "pool_destroy failed"
8352 }
8353 run_test 56xg "lfs migrate pool support"
8354
8355 test_56xh() {
8356         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8357
8358         local size_mb=25
8359         local file1=$DIR/$tfile
8360         local tmp1=$TMP/$tfile.tmp
8361
8362         $LFS setstripe -c 2 $file1
8363
8364         stack_trap "rm -f $file1 $tmp1"
8365         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8366                         error "error creating $tmp1"
8367         ls -lsh $tmp1
8368         cp $tmp1 $file1
8369
8370         local start=$SECONDS
8371
8372         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8373                 error "migrate failed rc = $?"
8374
8375         local elapsed=$((SECONDS - start))
8376
8377         # with 1MB/s, elapsed should equal size_mb
8378         (( elapsed >= size_mb * 95 / 100 )) ||
8379                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8380
8381         (( elapsed <= size_mb * 120 / 100 )) ||
8382                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8383
8384         (( elapsed <= size_mb * 350 / 100 )) ||
8385                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8386
8387         stripe=$($LFS getstripe -c $file1)
8388         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8389         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8390
8391         # Clean up file (since it is multiple MB)
8392         rm -f $file1 $tmp1
8393 }
8394 run_test 56xh "lfs migrate bandwidth limitation support"
8395
8396 test_56xi() {
8397         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8398         verify_yaml_available || skip_env "YAML verification not installed"
8399
8400         local size_mb=5
8401         local file1=$DIR/$tfile.1
8402         local file2=$DIR/$tfile.2
8403         local file3=$DIR/$tfile.3
8404         local output_file=$DIR/$tfile.out
8405         local tmp1=$TMP/$tfile.tmp
8406
8407         $LFS setstripe -c 2 $file1
8408         $LFS setstripe -c 2 $file2
8409         $LFS setstripe -c 2 $file3
8410
8411         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8412         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8413                         error "error creating $tmp1"
8414         ls -lsh $tmp1
8415         cp $tmp1 $file1
8416         cp $tmp1 $file2
8417         cp $tmp1 $file3
8418
8419         $LFS migrate --stats --stats-interval=1 \
8420                 -c 1 $file1 $file2 $file3 1> $output_file ||
8421                 error "migrate failed rc = $?"
8422
8423         cat $output_file
8424         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8425
8426         # Clean up file (since it is multiple MB)
8427         rm -f $file1 $file2 $file3 $tmp1 $output_file
8428 }
8429 run_test 56xi "lfs migrate stats support"
8430
8431 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8432         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8433
8434         local file=$DIR/$tfile
8435         local linkdir=$DIR/$tdir
8436
8437         test_mkdir $linkdir || error "fail to create $linkdir"
8438         $LFS setstripe -i 0 -c 1 -S1M $file
8439         stack_trap "rm -rf $file $linkdir"
8440         dd if=/dev/urandom of=$file bs=1M count=10 ||
8441                 error "fail to create $file"
8442
8443         # Create file links
8444         local cpts
8445         local threads_max
8446         local nlinks
8447
8448         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8449         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8450         (( nlinks = thread_max * 3 / 2 / cpts))
8451
8452         echo "create $nlinks hard links of $file"
8453         createmany -l $file $linkdir/link $nlinks
8454
8455         # Parallel migrates (should not block)
8456         local i
8457         for ((i = 0; i < nlinks; i++)); do
8458                 echo $linkdir/link$i
8459         done | xargs -n1 -P $nlinks $LFS migrate -c2
8460
8461         local stripe_count
8462         stripe_count=$($LFS getstripe -c $file) ||
8463                 error "fail to get stripe count on $file"
8464
8465         ((stripe_count == 2)) ||
8466                 error "fail to migrate $file (stripe_count = $stripe_count)"
8467 }
8468 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8469
8470 test_56xk() {
8471         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8472
8473         local size_mb=5
8474         local file1=$DIR/$tfile
8475
8476         stack_trap "rm -f $file1"
8477         $LFS setstripe -c 1 $file1
8478         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8479                 error "error creating $file1"
8480         $LFS mirror extend -N $file1 || error "can't mirror"
8481         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8482                 error "can't dd"
8483         $LFS getstripe $file1 | grep stale ||
8484                 error "one component must be stale"
8485
8486         local start=$SECONDS
8487         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8488                 error "migrate failed rc = $?"
8489         local elapsed=$((SECONDS - start))
8490         $LFS getstripe $file1 | grep stale &&
8491                 error "all components must be sync"
8492
8493         # with 1MB/s, elapsed should equal size_mb
8494         (( elapsed >= size_mb * 95 / 100 )) ||
8495                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8496
8497         (( elapsed <= size_mb * 120 / 100 )) ||
8498                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8499
8500         (( elapsed <= size_mb * 350 / 100 )) ||
8501                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8502 }
8503 run_test 56xk "lfs mirror resync bandwidth limitation support"
8504
8505 test_56xl() {
8506         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8507         verify_yaml_available || skip_env "YAML verification not installed"
8508
8509         local size_mb=5
8510         local file1=$DIR/$tfile.1
8511         local output_file=$DIR/$tfile.out
8512
8513         stack_trap "rm -f $file1"
8514         $LFS setstripe -c 1 $file1
8515         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8516                 error "error creating $file1"
8517         $LFS mirror extend -N $file1 || error "can't mirror"
8518         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8519                 error "can't dd"
8520         $LFS getstripe $file1 | grep stale ||
8521                 error "one component must be stale"
8522         $LFS getstripe $file1
8523
8524         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8525                 error "resync failed rc = $?"
8526         $LFS getstripe $file1 | grep stale &&
8527                 error "all components must be sync"
8528
8529         cat $output_file
8530         cat $output_file | verify_yaml || error "stats is not valid YAML"
8531 }
8532 run_test 56xl "lfs mirror resync stats support"
8533
8534 test_56y() {
8535         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8536                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8537
8538         local res=""
8539         local dir=$DIR/$tdir
8540         local f1=$dir/file1
8541         local f2=$dir/file2
8542
8543         test_mkdir -p $dir || error "creating dir $dir"
8544         touch $f1 || error "creating std file $f1"
8545         $MULTIOP $f2 H2c || error "creating released file $f2"
8546
8547         # a directory can be raid0, so ask only for files
8548         res=$($LFS find $dir -L raid0 -type f | wc -l)
8549         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8550
8551         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8552         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8553
8554         # only files can be released, so no need to force file search
8555         res=$($LFS find $dir -L released)
8556         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8557
8558         res=$($LFS find $dir -type f \! -L released)
8559         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8560 }
8561 run_test 56y "lfs find -L raid0|released"
8562
8563 test_56z() { # LU-4824
8564         # This checks to make sure 'lfs find' continues after errors
8565         # There are two classes of errors that should be caught:
8566         # - If multiple paths are provided, all should be searched even if one
8567         #   errors out
8568         # - If errors are encountered during the search, it should not terminate
8569         #   early
8570         local dir=$DIR/$tdir
8571         local i
8572
8573         test_mkdir $dir
8574         for i in d{0..9}; do
8575                 test_mkdir $dir/$i
8576                 touch $dir/$i/$tfile
8577         done
8578         $LFS find $DIR/non_existent_dir $dir &&
8579                 error "$LFS find did not return an error"
8580         # Make a directory unsearchable. This should NOT be the last entry in
8581         # directory order.  Arbitrarily pick the 6th entry
8582         chmod 700 $($LFS find $dir -type d | sed '6!d')
8583
8584         $RUNAS $LFS find $DIR/non_existent $dir
8585         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8586
8587         # The user should be able to see 10 directories and 9 files
8588         (( count == 19 )) ||
8589                 error "$LFS find found $count != 19 entries after error"
8590 }
8591 run_test 56z "lfs find should continue after an error"
8592
8593 test_56aa() { # LU-5937
8594         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8595
8596         local dir=$DIR/$tdir
8597
8598         mkdir $dir
8599         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8600
8601         createmany -o $dir/striped_dir/${tfile}- 1024
8602         local dirs=$($LFS find --size +8k $dir/)
8603
8604         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8605 }
8606 run_test 56aa "lfs find --size under striped dir"
8607
8608 test_56ab() { # LU-10705
8609         test_mkdir $DIR/$tdir
8610         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8611         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8612         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8613         # Flush writes to ensure valid blocks.  Need to be more thorough for
8614         # ZFS, since blocks are not allocated/returned to client immediately.
8615         sync_all_data
8616         wait_zfs_commit ost1 2
8617         cancel_lru_locks osc
8618         ls -ls $DIR/$tdir
8619
8620         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8621
8622         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8623
8624         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8625         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8626
8627         rm -f $DIR/$tdir/$tfile.[123]
8628 }
8629 run_test 56ab "lfs find --blocks"
8630
8631 # LU-11188
8632 test_56aca() {
8633         local dir="$DIR/$tdir"
8634         local perms=(001 002 003 004 005 006 007
8635                      010 020 030 040 050 060 070
8636                      100 200 300 400 500 600 700
8637                      111 222 333 444 555 666 777)
8638         local perm_minus=(8 8 4 8 4 4 2
8639                           8 8 4 8 4 4 2
8640                           8 8 4 8 4 4 2
8641                           4 4 2 4 2 2 1)
8642         local perm_slash=(8  8 12  8 12 12 14
8643                           8  8 12  8 12 12 14
8644                           8  8 12  8 12 12 14
8645                          16 16 24 16 24 24 28)
8646
8647         test_mkdir "$dir"
8648         for perm in ${perms[*]}; do
8649                 touch "$dir/$tfile.$perm"
8650                 chmod $perm "$dir/$tfile.$perm"
8651         done
8652
8653         for ((i = 0; i < ${#perms[*]}; i++)); do
8654                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8655                 (( $num == 1 )) ||
8656                         error "lfs find -perm ${perms[i]}:"\
8657                               "$num != 1"
8658
8659                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8660                 (( $num == ${perm_minus[i]} )) ||
8661                         error "lfs find -perm -${perms[i]}:"\
8662                               "$num != ${perm_minus[i]}"
8663
8664                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8665                 (( $num == ${perm_slash[i]} )) ||
8666                         error "lfs find -perm /${perms[i]}:"\
8667                               "$num != ${perm_slash[i]}"
8668         done
8669 }
8670 run_test 56aca "check lfs find -perm with octal representation"
8671
8672 test_56acb() {
8673         local dir=$DIR/$tdir
8674         # p is the permission of write and execute for user, group and other
8675         # without the umask. It is used to test +wx.
8676         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8677         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8678         local symbolic=(+t  a+t u+t g+t o+t
8679                         g+s u+s o+s +s o+sr
8680                         o=r,ug+o,u+w
8681                         u+ g+ o+ a+ ugo+
8682                         u- g- o- a- ugo-
8683                         u= g= o= a= ugo=
8684                         o=r,ug+o,u+w u=r,a+u,u+w
8685                         g=r,ugo=g,u+w u+x,+X +X
8686                         u+x,u+X u+X u+x,g+X o+r,+X
8687                         u+x,go+X +wx +rwx)
8688
8689         test_mkdir $dir
8690         for perm in ${perms[*]}; do
8691                 touch "$dir/$tfile.$perm"
8692                 chmod $perm "$dir/$tfile.$perm"
8693         done
8694
8695         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8696                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8697
8698                 (( $num == 1 )) ||
8699                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8700         done
8701 }
8702 run_test 56acb "check lfs find -perm with symbolic representation"
8703
8704 test_56acc() {
8705         local dir=$DIR/$tdir
8706         local tests="17777 787 789 abcd
8707                 ug=uu ug=a ug=gu uo=ou urw
8708                 u+xg+x a=r,u+x,"
8709
8710         test_mkdir $dir
8711         for err in $tests; do
8712                 if $LFS find $dir -perm $err 2>/dev/null; then
8713                         error "lfs find -perm $err: parsing should have failed"
8714                 fi
8715         done
8716 }
8717 run_test 56acc "check parsing error for lfs find -perm"
8718
8719 test_56ba() {
8720         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8721                 skip "Need MDS version at least 2.10.50"
8722
8723         # Create composite files with one component
8724         local dir=$DIR/$tdir
8725
8726         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8727         # Create composite files with three components
8728         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8729         # LU-16904 Create plain layout files
8730         lfs setstripe -c 1 $dir/$tfile-{1..10}
8731
8732         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8733
8734         [[ $nfiles == 10 ]] ||
8735                 error "lfs find -E 1M found $nfiles != 10 files"
8736
8737         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8738         [[ $nfiles == 25 ]] ||
8739                 error "lfs find ! -E 1M found $nfiles != 25 files"
8740
8741         # All files have a component that starts at 0
8742         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8743         [[ $nfiles == 35 ]] ||
8744                 error "lfs find --component-start 0 - $nfiles != 35 files"
8745
8746         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8747         [[ $nfiles == 15 ]] ||
8748                 error "lfs find --component-start 2M - $nfiles != 15 files"
8749
8750         # All files created here have a componenet that does not starts at 2M
8751         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8752         [[ $nfiles == 35 ]] ||
8753                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8754
8755         # Find files with a specified number of components
8756         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8757         [[ $nfiles == 15 ]] ||
8758                 error "lfs find --component-count 3 - $nfiles != 15 files"
8759
8760         # Remember non-composite files have a component count of zero
8761         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8762         [[ $nfiles == 10 ]] ||
8763                 error "lfs find --component-count 0 - $nfiles != 10 files"
8764
8765         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8766         [[ $nfiles == 20 ]] ||
8767                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8768
8769         # All files have a flag called "init"
8770         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8771         [[ $nfiles == 35 ]] ||
8772                 error "lfs find --component-flags init - $nfiles != 35 files"
8773
8774         # Multi-component files will have a component not initialized
8775         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8776         [[ $nfiles == 15 ]] ||
8777                 error "lfs find !--component-flags init - $nfiles != 15 files"
8778
8779         rm -rf $dir
8780
8781 }
8782 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8783
8784 test_56ca() {
8785         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8786                 skip "Need MDS version at least 2.10.57"
8787
8788         local td=$DIR/$tdir
8789         local tf=$td/$tfile
8790         local dir
8791         local nfiles
8792         local cmd
8793         local i
8794         local j
8795
8796         # create mirrored directories and mirrored files
8797         mkdir $td || error "mkdir $td failed"
8798         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8799         createmany -o $tf- 10 || error "create $tf- failed"
8800
8801         for i in $(seq 2); do
8802                 dir=$td/dir$i
8803                 mkdir $dir || error "mkdir $dir failed"
8804                 $LFS mirror create -N$((3 + i)) $dir ||
8805                         error "create mirrored dir $dir failed"
8806                 createmany -o $dir/$tfile- 10 ||
8807                         error "create $dir/$tfile- failed"
8808         done
8809
8810         # change the states of some mirrored files
8811         echo foo > $tf-6
8812         for i in $(seq 2); do
8813                 dir=$td/dir$i
8814                 for j in $(seq 4 9); do
8815                         echo foo > $dir/$tfile-$j
8816                 done
8817         done
8818
8819         # find mirrored files with specific mirror count
8820         cmd="$LFS find --mirror-count 3 --type f $td"
8821         nfiles=$($cmd | wc -l)
8822         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8823
8824         cmd="$LFS find ! --mirror-count 3 --type f $td"
8825         nfiles=$($cmd | wc -l)
8826         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8827
8828         cmd="$LFS find --mirror-count +2 --type f $td"
8829         nfiles=$($cmd | wc -l)
8830         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8831
8832         cmd="$LFS find --mirror-count -6 --type f $td"
8833         nfiles=$($cmd | wc -l)
8834         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8835
8836         # find mirrored files with specific file state
8837         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8838         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8839
8840         cmd="$LFS find --mirror-state=ro --type f $td"
8841         nfiles=$($cmd | wc -l)
8842         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8843
8844         cmd="$LFS find ! --mirror-state=ro --type f $td"
8845         nfiles=$($cmd | wc -l)
8846         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8847
8848         cmd="$LFS find --mirror-state=wp --type f $td"
8849         nfiles=$($cmd | wc -l)
8850         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8851
8852         cmd="$LFS find ! --mirror-state=sp --type f $td"
8853         nfiles=$($cmd | wc -l)
8854         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8855 }
8856 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8857
8858 test_56da() { # LU-14179
8859         local path=$DIR/$tdir
8860
8861         test_mkdir $path
8862         cd $path
8863
8864         local longdir=$(str_repeat 'a' 255)
8865
8866         for i in {1..15}; do
8867                 path=$path/$longdir
8868                 test_mkdir $longdir
8869                 cd $longdir
8870         done
8871
8872         local len=${#path}
8873         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8874
8875         test_mkdir $lastdir
8876         cd $lastdir
8877         # PATH_MAX-1
8878         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8879
8880         # NAME_MAX
8881         touch $(str_repeat 'f' 255)
8882
8883         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8884                 error "lfs find reported an error"
8885
8886         rm -rf $DIR/$tdir
8887 }
8888 run_test 56da "test lfs find with long paths"
8889
8890 test_56ea() { #LU-10378
8891         local path=$DIR/$tdir
8892         local pool=$TESTNAME
8893
8894         # Create ost pool
8895         pool_add $pool || error "pool_add $pool failed"
8896         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8897                 error "adding targets to $pool failed"
8898
8899         # Set default pool on directory before creating file
8900         mkdir $path || error "mkdir $path failed"
8901         $LFS setstripe -p $pool $path ||
8902                 error "set OST pool on $pool failed"
8903         touch $path/$tfile || error "touch $path/$tfile failed"
8904
8905         # Compare basic file attributes from -printf and stat
8906         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8907         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8908
8909         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8910                 error "Attrs from lfs find and stat don't match"
8911
8912         # Compare Lustre attributes from lfs find and lfs getstripe
8913         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8914         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8915         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8916         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8917         local fpool=$($LFS getstripe --pool $path/$tfile)
8918         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8919
8920         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8921                 error "Attrs from lfs find and lfs getstripe don't match"
8922
8923         # Verify behavior for unknown escape/format sequences
8924         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8925
8926         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8927                 error "Escape/format codes don't match"
8928 }
8929 run_test 56ea "test lfs find -printf option"
8930
8931 test_56eb() {
8932         local dir=$DIR/$tdir
8933         local subdir_1=$dir/subdir_1
8934
8935         test_mkdir -p $subdir_1
8936         ln -s subdir_1 $dir/link_1
8937
8938         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8939                 error "symlink is not followed"
8940
8941         $LFS getstripe --no-follow $dir |
8942                 grep "^$dir/link_1 has no stripe info$" ||
8943                 error "symlink should not have stripe info"
8944
8945         touch $dir/testfile
8946         ln -s testfile $dir/file_link_2
8947
8948         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8949                 error "symlink is not followed"
8950
8951         $LFS getstripe --no-follow $dir |
8952                 grep "^$dir/file_link_2 has no stripe info$" ||
8953                 error "symlink should not have stripe info"
8954 }
8955 run_test 56eb "check lfs getstripe on symlink"
8956
8957 test_56ec() {
8958         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8959         local dir=$DIR/$tdir
8960         local srcfile=$dir/srcfile
8961         local srcyaml=$dir/srcyaml
8962         local destfile=$dir/destfile
8963
8964         test_mkdir -p $dir
8965
8966         $LFS setstripe -i 1 $srcfile
8967         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8968         # if the setstripe yaml parsing fails for any reason, the command can
8969         # randomly assign the correct OST index, leading to an erroneous
8970         # success. but the chance of false success is low enough that a
8971         # regression should still be quickly caught.
8972         $LFS setstripe --yaml=$srcyaml $destfile
8973
8974         local srcindex=$($LFS getstripe -i $srcfile)
8975         local destindex=$($LFS getstripe -i $destfile)
8976
8977         if [[ ! $srcindex -eq $destindex ]]; then
8978                 error "setstripe did not set OST index correctly"
8979         fi
8980 }
8981 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8982
8983 test_56eda() {
8984         local dir=$DIR/$tdir
8985         local subdir=$dir/subdir
8986         local file1=$dir/$tfile
8987         local file2=$dir/$tfile\2
8988         local link=$dir/$tfile-link
8989         local nfiles
8990
8991         test_mkdir -p $dir
8992         $LFS setdirstripe -c1 $subdir
8993         touch $file1
8994         touch $file2
8995         ln $file2 $link
8996
8997         nfiles=$($LFS find --links 1 $dir | wc -l)
8998         (( $nfiles == 1 )) ||
8999                 error "lfs find --links expected 1 file, got $nfiles"
9000
9001         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
9002         (( $nfiles == 2 )) ||
9003                 error "lfs find --links expected 2 files, got $nfiles"
9004
9005         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
9006         (( $nfiles == 1 )) ||
9007                 error "lfs find --links expected 1 directory, got $nfiles"
9008 }
9009 run_test 56eda "check lfs find --links"
9010
9011 test_56edb() {
9012         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
9013
9014         local dir=$DIR/$tdir
9015         local stripedir=$dir/stripedir
9016         local nfiles
9017
9018         test_mkdir -p $dir
9019
9020         $LFS setdirstripe -c2 $stripedir
9021
9022         $LFS getdirstripe $stripedir
9023
9024         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9025         (( $nfiles == 1 )) ||
9026                 error "lfs find --links expected 1 directory, got $nfiles"
9027 }
9028 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9029
9030 test_56ef() {
9031         local dir=$DIR/$tdir
9032         local dir1=$dir/d1
9033         local dir2=$dir/d2
9034         local nfiles
9035         local err_msg
9036
9037         test_mkdir -p $dir
9038
9039         mkdir $dir1
9040         mkdir $dir2
9041
9042         touch $dir1/f
9043         touch $dir2/f
9044
9045         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9046         (( $nfiles == 2 )) ||
9047                 error "(1) lfs find expected 2 files, got $nfiles"
9048
9049         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9050         (( $nfiles == 2 )) ||
9051                 error "(2) lfs find expected 2 files, got $nfiles"
9052
9053         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9054         (( $nfiles == 2 )) ||
9055                 error "(3) lfs find expected 2 files, got $nfiles"
9056
9057         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9058         [[ $err_msg =~ "No such file or directory" ]] ||
9059                 error "expected standard error message, got: '$err_msg'"
9060 }
9061 run_test 56ef "lfs find with multiple paths"
9062
9063 test_56eg() {
9064         local dir=$DIR/$tdir
9065         local found
9066
9067         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9068
9069         test_mkdir -p $dir
9070
9071         touch $dir/$tfile
9072         ln -s $dir/$tfile $dir/$tfile.symlink
9073         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9074         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9075                 $dir/$tfile.symlink
9076         setfattr --no-dereference -n "trusted.common" \
9077                 $dir/{$tfile,$tfile.symlink}
9078
9079         found=$($LFS find -xattr "trusted.*=test_target" \
9080                 -xattr "trusted.common" $dir)
9081         [[ "$found" == "$dir/$tfile" ]] || {
9082                 getfattr -d -m trusted.* $dir/$tfile
9083                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9084         }
9085
9086         found=$($LFS find -xattr "trusted.*=test_link" \
9087                 -xattr "trusted.common" $dir)
9088         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9089                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9090                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9091         }
9092
9093         rm -f $dir/*
9094
9095         touch $dir/$tfile.1
9096         touch $dir/$tfile.2
9097         setfattr -n "user.test" -v "1" $dir/$tfile.1
9098         setfattr -n "user.test" -v "2" $dir/$tfile.2
9099         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9100
9101         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9102         [[ "$found" == "$dir/$tfile.1" ]] || {
9103                 getfattr -d $dir/$tfile.1
9104                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9105         }
9106
9107         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9108         [[ "$found" == "$dir/$tfile.2" ]] || {
9109                 getfattr -d $dir/$tfile.2
9110                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9111         }
9112
9113         setfattr -n "user.empty" $dir/$tfile.1
9114         found=$($LFS find -xattr "user.empty" $dir)
9115         [[ "$found" == "$dir/$tfile.1" ]] || {
9116                 getfattr -d $dir/$tfile.1
9117                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9118         }
9119
9120         # setfattr command normally does not store terminating null byte
9121         # when writing a string as an xattr value.
9122         #
9123         # In order to test matching a value string that includes a terminating
9124         # null, explicitly encode the string "test\0" with the null terminator.
9125         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9126         found=$($LFS find -xattr "user.test=test" $dir)
9127         [[ "$found" == "$dir/$tfile.1" ]] || {
9128                 getfattr -d --encoding=hex $dir/$tfile.1
9129                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9130         }
9131 }
9132 run_test 56eg "lfs find -xattr"
9133
9134 test_57a() {
9135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9136         # note test will not do anything if MDS is not local
9137         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9138                 skip_env "ldiskfs only test"
9139         fi
9140         remote_mds_nodsh && skip "remote MDS with nodsh"
9141
9142         local MNTDEV="osd*.*MDT*.mntdev"
9143         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9144         [ -z "$DEV" ] && error "can't access $MNTDEV"
9145         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9146                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9147                         error "can't access $DEV"
9148                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9149                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9150                 rm $TMP/t57a.dump
9151         done
9152 }
9153 run_test 57a "verify MDS filesystem created with large inodes =="
9154
9155 test_57b() {
9156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9157         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9158                 skip_env "ldiskfs only test"
9159         fi
9160         remote_mds_nodsh && skip "remote MDS with nodsh"
9161
9162         local dir=$DIR/$tdir
9163         local filecount=100
9164         local file1=$dir/f1
9165         local fileN=$dir/f$filecount
9166
9167         rm -rf $dir || error "removing $dir"
9168         test_mkdir -c1 $dir
9169         local mdtidx=$($LFS getstripe -m $dir)
9170         local mdtname=MDT$(printf %04x $mdtidx)
9171         local facet=mds$((mdtidx + 1))
9172
9173         echo "mcreating $filecount files"
9174         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9175
9176         # verify that files do not have EAs yet
9177         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9178                 error "$file1 has an EA"
9179         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9180                 error "$fileN has an EA"
9181
9182         sync
9183         sleep 1
9184         df $dir  #make sure we get new statfs data
9185         local mdsfree=$(do_facet $facet \
9186                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9187         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9188         local file
9189
9190         echo "opening files to create objects/EAs"
9191         for file in $(seq -f $dir/f%g 1 $filecount); do
9192                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9193                         error "opening $file"
9194         done
9195
9196         # verify that files have EAs now
9197         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9198                 error "$file1 missing EA"
9199         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9200                 error "$fileN missing EA"
9201
9202         sleep 1  #make sure we get new statfs data
9203         df $dir
9204         local mdsfree2=$(do_facet $facet \
9205                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9206         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9207
9208         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9209                 if [ "$mdsfree" != "$mdsfree2" ]; then
9210                         error "MDC before $mdcfree != after $mdcfree2"
9211                 else
9212                         echo "MDC before $mdcfree != after $mdcfree2"
9213                         echo "unable to confirm if MDS has large inodes"
9214                 fi
9215         fi
9216         rm -rf $dir
9217 }
9218 run_test 57b "default LOV EAs are stored inside large inodes ==="
9219
9220 test_58() {
9221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9222         [ -z "$(which wiretest 2>/dev/null)" ] &&
9223                         skip_env "could not find wiretest"
9224
9225         wiretest
9226 }
9227 run_test 58 "verify cross-platform wire constants =============="
9228
9229 test_59() {
9230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9231
9232         echo "touch 130 files"
9233         createmany -o $DIR/f59- 130
9234         echo "rm 130 files"
9235         unlinkmany $DIR/f59- 130
9236         sync
9237         # wait for commitment of removal
9238         wait_delete_completed
9239 }
9240 run_test 59 "verify cancellation of llog records async ========="
9241
9242 TEST60_HEAD="test_60 run $RANDOM"
9243 test_60a() {
9244         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9245         remote_mgs_nodsh && skip "remote MGS with nodsh"
9246         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9247                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9248                         skip_env "missing subtest run-llog.sh"
9249
9250         log "$TEST60_HEAD - from kernel mode"
9251         do_facet mgs "$LCTL dk > /dev/null"
9252         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9253         do_facet mgs $LCTL dk > $TMP/$tfile
9254
9255         # LU-6388: test llog_reader
9256         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9257         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9258         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9259                         skip_env "missing llog_reader"
9260         local fstype=$(facet_fstype mgs)
9261         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9262                 skip_env "Only for ldiskfs or zfs type mgs"
9263
9264         local mntpt=$(facet_mntpt mgs)
9265         local mgsdev=$(mgsdevname 1)
9266         local fid_list
9267         local fid
9268         local rec_list
9269         local rec
9270         local rec_type
9271         local obj_file
9272         local path
9273         local seq
9274         local oid
9275         local pass=true
9276
9277         #get fid and record list
9278         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9279                 tail -n 4))
9280         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9281                 tail -n 4))
9282         #remount mgs as ldiskfs or zfs type
9283         stop mgs || error "stop mgs failed"
9284         mount_fstype mgs || error "remount mgs failed"
9285         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9286                 fid=${fid_list[i]}
9287                 rec=${rec_list[i]}
9288                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9289                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9290                 oid=$((16#$oid))
9291
9292                 case $fstype in
9293                         ldiskfs )
9294                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9295                         zfs )
9296                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9297                 esac
9298                 echo "obj_file is $obj_file"
9299                 do_facet mgs $llog_reader $obj_file
9300
9301                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9302                         awk '{ print $3 }' | sed -e "s/^type=//g")
9303                 if [ $rec_type != $rec ]; then
9304                         echo "FAILED test_60a wrong record type $rec_type," \
9305                               "should be $rec"
9306                         pass=false
9307                         break
9308                 fi
9309
9310                 #check obj path if record type is LLOG_LOGID_MAGIC
9311                 if [ "$rec" == "1064553b" ]; then
9312                         path=$(do_facet mgs $llog_reader $obj_file |
9313                                 grep "path=" | awk '{ print $NF }' |
9314                                 sed -e "s/^path=//g")
9315                         if [ $obj_file != $mntpt/$path ]; then
9316                                 echo "FAILED test_60a wrong obj path" \
9317                                       "$montpt/$path, should be $obj_file"
9318                                 pass=false
9319                                 break
9320                         fi
9321                 fi
9322         done
9323         rm -f $TMP/$tfile
9324         #restart mgs before "error", otherwise it will block the next test
9325         stop mgs || error "stop mgs failed"
9326         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9327         $pass || error "test failed, see FAILED test_60a messages for specifics"
9328 }
9329 run_test 60a "llog_test run from kernel module and test llog_reader"
9330
9331 test_60b() { # bug 6411
9332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9333
9334         dmesg > $DIR/$tfile
9335         LLOG_COUNT=$(do_facet mgs dmesg |
9336                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9337                           /llog_[a-z]*.c:[0-9]/ {
9338                                 if (marker)
9339                                         from_marker++
9340                                 from_begin++
9341                           }
9342                           END {
9343                                 if (marker)
9344                                         print from_marker
9345                                 else
9346                                         print from_begin
9347                           }")
9348
9349         [[ $LLOG_COUNT -gt 120 ]] &&
9350                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9351 }
9352 run_test 60b "limit repeated messages from CERROR/CWARN"
9353
9354 test_60c() {
9355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9356
9357         echo "create 5000 files"
9358         createmany -o $DIR/f60c- 5000
9359 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9360         lctl set_param fail_loc=0x80000137
9361         unlinkmany $DIR/f60c- 5000
9362         lctl set_param fail_loc=0
9363 }
9364 run_test 60c "unlink file when mds full"
9365
9366 test_60d() {
9367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9368
9369         SAVEPRINTK=$(lctl get_param -n printk)
9370         # verify "lctl mark" is even working"
9371         MESSAGE="test message ID $RANDOM $$"
9372         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9373         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9374
9375         lctl set_param printk=0 || error "set lnet.printk failed"
9376         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9377         MESSAGE="new test message ID $RANDOM $$"
9378         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9379         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9380         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9381
9382         lctl set_param -n printk="$SAVEPRINTK"
9383 }
9384 run_test 60d "test printk console message masking"
9385
9386 test_60e() {
9387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9388         remote_mds_nodsh && skip "remote MDS with nodsh"
9389
9390         touch $DIR/$tfile
9391 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9392         do_facet mds1 lctl set_param fail_loc=0x15b
9393         rm $DIR/$tfile
9394 }
9395 run_test 60e "no space while new llog is being created"
9396
9397 test_60f() {
9398         local old_path=$($LCTL get_param -n debug_path)
9399
9400         stack_trap "$LCTL set_param debug_path=$old_path"
9401         stack_trap "rm -f $TMP/$tfile*"
9402         rm -f $TMP/$tfile* 2> /dev/null
9403         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9404         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9405         test_mkdir $DIR/$tdir
9406         # retry in case the open is cached and not released
9407         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9408                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9409                 sleep 0.1
9410         done
9411         ls $TMP/$tfile*
9412         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9413 }
9414 run_test 60f "change debug_path works"
9415
9416 test_60g() {
9417         local pid
9418         local i
9419
9420         test_mkdir -c $MDSCOUNT $DIR/$tdir
9421
9422         (
9423                 local index=0
9424                 while true; do
9425                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9426                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9427                                 2>/dev/null
9428                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9429                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9430                         index=$((index + 1))
9431                 done
9432         ) &
9433
9434         pid=$!
9435
9436         for i in {0..100}; do
9437                 # define OBD_FAIL_OSD_TXN_START    0x19a
9438                 local index=$((i % MDSCOUNT + 1))
9439
9440                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9441                         > /dev/null
9442                 sleep 0.01
9443         done
9444
9445         kill -9 $pid
9446
9447         for i in $(seq $MDSCOUNT); do
9448                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9449         done
9450
9451         mkdir $DIR/$tdir/new || error "mkdir failed"
9452         rmdir $DIR/$tdir/new || error "rmdir failed"
9453
9454         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9455                 -t namespace
9456         for i in $(seq $MDSCOUNT); do
9457                 wait_update_facet mds$i "$LCTL get_param -n \
9458                         mdd.$(facet_svc mds$i).lfsck_namespace |
9459                         awk '/^status/ { print \\\$2 }'" "completed"
9460         done
9461
9462         ls -R $DIR/$tdir
9463         rm -rf $DIR/$tdir || error "rmdir failed"
9464 }
9465 run_test 60g "transaction abort won't cause MDT hung"
9466
9467 test_60h() {
9468         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9469                 skip "Need MDS version at least 2.12.52"
9470         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9471
9472         local f
9473
9474         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9475         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9476         for fail_loc in 0x80000188 0x80000189; do
9477                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9478                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9479                         error "mkdir $dir-$fail_loc failed"
9480                 for i in {0..10}; do
9481                         # create may fail on missing stripe
9482                         echo $i > $DIR/$tdir-$fail_loc/$i
9483                 done
9484                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9485                         error "getdirstripe $tdir-$fail_loc failed"
9486                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9487                         error "migrate $tdir-$fail_loc failed"
9488                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9489                         error "getdirstripe $tdir-$fail_loc failed"
9490                 pushd $DIR/$tdir-$fail_loc
9491                 for f in *; do
9492                         echo $f | cmp $f - || error "$f data mismatch"
9493                 done
9494                 popd
9495                 rm -rf $DIR/$tdir-$fail_loc
9496         done
9497 }
9498 run_test 60h "striped directory with missing stripes can be accessed"
9499
9500 function t60i_load() {
9501         mkdir $DIR/$tdir
9502         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9503         $LCTL set_param fail_loc=0x131c fail_val=1
9504         for ((i=0; i<5000; i++)); do
9505                 touch $DIR/$tdir/f$i
9506         done
9507 }
9508
9509 test_60i() {
9510         changelog_register || error "changelog_register failed"
9511         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9512         changelog_users $SINGLEMDS | grep -q $cl_user ||
9513                 error "User $cl_user not found in changelog_users"
9514         changelog_chmask "ALL"
9515         t60i_load &
9516         local PID=$!
9517         for((i=0; i<100; i++)); do
9518                 changelog_dump >/dev/null ||
9519                         error "can't read changelog"
9520         done
9521         kill $PID
9522         wait $PID
9523         changelog_deregister || error "changelog_deregister failed"
9524         $LCTL set_param fail_loc=0
9525 }
9526 run_test 60i "llog: new record vs reader race"
9527
9528 test_60j() {
9529         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9530                 skip "need MDS version at least 2.15.50"
9531         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9532         remote_mds_nodsh && skip "remote MDS with nodsh"
9533         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9534
9535         changelog_users $SINGLEMDS | grep "^cl" &&
9536                 skip "active changelog user"
9537
9538         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9539
9540         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9541                 skip_env "missing llog_reader"
9542
9543         mkdir_on_mdt0 $DIR/$tdir
9544
9545         local f=$DIR/$tdir/$tfile
9546         local mdt_dev
9547         local tmpfile
9548         local plain
9549
9550         changelog_register || error "cannot register changelog user"
9551
9552         # set changelog_mask to ALL
9553         changelog_chmask "ALL"
9554         changelog_clear
9555
9556         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9557         unlinkmany ${f}- 100 || error "unlinkmany failed"
9558
9559         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9560         mdt_dev=$(facet_device $SINGLEMDS)
9561
9562         do_facet $SINGLEMDS sync
9563         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9564                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9565                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9566
9567         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9568
9569         # if $tmpfile is not on EXT3 filesystem for some reason
9570         [[ ${plain:0:1} == 'O' ]] ||
9571                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9572
9573         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9574                 $mdt_dev; stat -c %s $tmpfile")
9575         echo "Truncate llog from $size to $((size - size % 8192))"
9576         size=$((size - size % 8192))
9577         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9578         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9579                 grep -c 'in bitmap only')
9580         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9581
9582         size=$((size - 9000))
9583         echo "Corrupt llog in the middle at $size"
9584         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9585                 count=333 conv=notrunc
9586         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9587                 grep -c 'next chunk')
9588         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9589 }
9590 run_test 60j "llog_reader reports corruptions"
9591
9592 test_61a() {
9593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9594
9595         f="$DIR/f61"
9596         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9597         cancel_lru_locks osc
9598         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9599         sync
9600 }
9601 run_test 61a "mmap() writes don't make sync hang ================"
9602
9603 test_61b() {
9604         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9605 }
9606 run_test 61b "mmap() of unstriped file is successful"
9607
9608 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9609 # Though this test is irrelevant anymore, it helped to reveal some
9610 # other grant bugs (LU-4482), let's keep it.
9611 test_63a() {   # was test_63
9612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9613
9614         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9615
9616         for i in `seq 10` ; do
9617                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9618                 sleep 5
9619                 kill $!
9620                 sleep 1
9621         done
9622
9623         rm -f $DIR/f63 || true
9624 }
9625 run_test 63a "Verify oig_wait interruption does not crash ======="
9626
9627 # bug 2248 - async write errors didn't return to application on sync
9628 # bug 3677 - async write errors left page locked
9629 test_63b() {
9630         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9631
9632         debugsave
9633         lctl set_param debug=-1
9634
9635         # ensure we have a grant to do async writes
9636         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9637         rm $DIR/$tfile
9638
9639         sync    # sync lest earlier test intercept the fail_loc
9640
9641         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9642         lctl set_param fail_loc=0x80000406
9643         $MULTIOP $DIR/$tfile Owy && \
9644                 error "sync didn't return ENOMEM"
9645         sync; sleep 2; sync     # do a real sync this time to flush page
9646         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9647                 error "locked page left in cache after async error" || true
9648         debugrestore
9649 }
9650 run_test 63b "async write errors should be returned to fsync ==="
9651
9652 test_64a () {
9653         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9654
9655         lfs df $DIR
9656         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9657 }
9658 run_test 64a "verify filter grant calculations (in kernel) ====="
9659
9660 test_64b () {
9661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9662
9663         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9664 }
9665 run_test 64b "check out-of-space detection on client"
9666
9667 test_64c() {
9668         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9669 }
9670 run_test 64c "verify grant shrink"
9671
9672 import_param() {
9673         local tgt=$1
9674         local param=$2
9675
9676         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9677 }
9678
9679 # this does exactly what osc_request.c:osc_announce_cached() does in
9680 # order to calculate max amount of grants to ask from server
9681 want_grant() {
9682         local tgt=$1
9683
9684         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9685         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9686
9687         ((rpc_in_flight++));
9688         nrpages=$((nrpages * rpc_in_flight))
9689
9690         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9691
9692         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9693
9694         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9695         local undirty=$((nrpages * PAGE_SIZE))
9696
9697         local max_extent_pages
9698         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9699         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9700         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9701         local grant_extent_tax
9702         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9703
9704         undirty=$((undirty + nrextents * grant_extent_tax))
9705
9706         echo $undirty
9707 }
9708
9709 # this is size of unit for grant allocation. It should be equal to
9710 # what tgt_grant.c:tgt_grant_chunk() calculates
9711 grant_chunk() {
9712         local tgt=$1
9713         local max_brw_size
9714         local grant_extent_tax
9715
9716         max_brw_size=$(import_param $tgt max_brw_size)
9717
9718         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9719
9720         echo $(((max_brw_size + grant_extent_tax) * 2))
9721 }
9722
9723 test_64d() {
9724         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9725                 skip "OST < 2.10.55 doesn't limit grants enough"
9726
9727         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9728
9729         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9730                 skip "no grant_param connect flag"
9731
9732         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9733
9734         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9735         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9736
9737
9738         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9739         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9740
9741         $LFS setstripe $DIR/$tfile -i 0 -c 1
9742         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9743         ddpid=$!
9744
9745         while kill -0 $ddpid; do
9746                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9747
9748                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9749                         kill $ddpid
9750                         error "cur_grant $cur_grant > $max_cur_granted"
9751                 fi
9752
9753                 sleep 1
9754         done
9755 }
9756 run_test 64d "check grant limit exceed"
9757
9758 check_grants() {
9759         local tgt=$1
9760         local expected=$2
9761         local msg=$3
9762         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9763
9764         ((cur_grants == expected)) ||
9765                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9766 }
9767
9768 round_up_p2() {
9769         echo $((($1 + $2 - 1) & ~($2 - 1)))
9770 }
9771
9772 test_64e() {
9773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9774         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9775                 skip "Need OSS version at least 2.11.56"
9776
9777         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9778         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9779         $LCTL set_param debug=+cache
9780
9781         # Remount client to reset grant
9782         remount_client $MOUNT || error "failed to remount client"
9783         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9784
9785         local init_grants=$(import_param $osc_tgt initial_grant)
9786
9787         check_grants $osc_tgt $init_grants "init grants"
9788
9789         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9790         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9791         local gbs=$(import_param $osc_tgt grant_block_size)
9792
9793         # write random number of bytes from max_brw_size / 4 to max_brw_size
9794         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9795         # align for direct io
9796         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9797         # round to grant consumption unit
9798         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9799
9800         local grants=$((wb_round_up + extent_tax))
9801
9802         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9803         stack_trap "rm -f $DIR/$tfile"
9804
9805         # define OBD_FAIL_TGT_NO_GRANT 0x725
9806         # make the server not grant more back
9807         do_facet ost1 $LCTL set_param fail_loc=0x725
9808         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9809
9810         do_facet ost1 $LCTL set_param fail_loc=0
9811
9812         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9813
9814         rm -f $DIR/$tfile || error "rm failed"
9815
9816         # Remount client to reset grant
9817         remount_client $MOUNT || error "failed to remount client"
9818         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9819
9820         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9821
9822         # define OBD_FAIL_TGT_NO_GRANT 0x725
9823         # make the server not grant more back
9824         do_facet ost1 $LCTL set_param fail_loc=0x725
9825         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9826         do_facet ost1 $LCTL set_param fail_loc=0
9827
9828         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9829 }
9830 run_test 64e "check grant consumption (no grant allocation)"
9831
9832 test_64f() {
9833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9834
9835         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9836         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9837         $LCTL set_param debug=+cache
9838
9839         # Remount client to reset grant
9840         remount_client $MOUNT || error "failed to remount client"
9841         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9842
9843         local init_grants=$(import_param $osc_tgt initial_grant)
9844         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9845         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9846         local gbs=$(import_param $osc_tgt grant_block_size)
9847         local chunk=$(grant_chunk $osc_tgt)
9848
9849         # write random number of bytes from max_brw_size / 4 to max_brw_size
9850         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9851         # align for direct io
9852         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9853         # round to grant consumption unit
9854         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9855
9856         local grants=$((wb_round_up + extent_tax))
9857
9858         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9859         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9860                 error "error writing to $DIR/$tfile"
9861
9862         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9863                 "direct io with grant allocation"
9864
9865         rm -f $DIR/$tfile || error "rm failed"
9866
9867         # Remount client to reset grant
9868         remount_client $MOUNT || error "failed to remount client"
9869         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9870
9871         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9872
9873         # Testing that buffered IO consumes grant on the client
9874
9875         # Delay the RPC on the server so it's guaranteed to not complete even
9876         # if the RPC is sent from the client
9877         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9878         $LCTL set_param fail_loc=0x50a fail_val=3
9879         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9880                 error "error writing to $DIR/$tfile with buffered IO"
9881
9882         check_grants $osc_tgt $((init_grants - grants)) \
9883                 "buffered io, not write rpc"
9884
9885         # Clear the fail loc and do a sync on the client
9886         $LCTL set_param fail_loc=0 fail_val=0
9887         sync
9888
9889         # RPC is now known to have sent
9890         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9891                 "buffered io, one RPC"
9892 }
9893 run_test 64f "check grant consumption (with grant allocation)"
9894
9895 test_64g() {
9896         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9897                 skip "Need MDS version at least 2.14.56"
9898
9899         local mdts=$(comma_list $(mdts_nodes))
9900
9901         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9902                         tr '\n' ' ')
9903         stack_trap "$LCTL set_param $old"
9904
9905         # generate dirty pages and increase dirty granted on MDT
9906         stack_trap "rm -f $DIR/$tfile-*"
9907         for (( i = 0; i < 10; i++)); do
9908                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9909                         error "can't set stripe"
9910                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9911                         error "can't dd"
9912                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9913                         $LFS getstripe $DIR/$tfile-$i
9914                         error "not DoM file"
9915                 }
9916         done
9917
9918         # flush dirty pages
9919         sync
9920
9921         # wait until grant shrink reset grant dirty on MDTs
9922         for ((i = 0; i < 120; i++)); do
9923                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9924                         awk '{sum=sum+$1} END {print sum}')
9925                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9926                 echo "$grant_dirty grants, $vm_dirty pages"
9927                 (( grant_dirty + vm_dirty == 0 )) && break
9928                 (( i == 3 )) && sync &&
9929                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9930                 sleep 1
9931         done
9932
9933         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9934                 awk '{sum=sum+$1} END {print sum}')
9935         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9936 }
9937 run_test 64g "grant shrink on MDT"
9938
9939 test_64h() {
9940         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9941                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9942
9943         local instance=$($LFS getname -i $DIR)
9944         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9945         local num_exps=$(do_facet ost1 \
9946             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9947         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9948         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9949         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9950
9951         # 10MiB is for file to be written, max_brw_size * 16 *
9952         # num_exps is space reserve so that tgt_grant_shrink() decided
9953         # to not shrink
9954         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9955         (( avail * 1024 < expect )) &&
9956                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9957
9958         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9959         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9960         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9961         $LCTL set_param osc.*OST0000*.grant_shrink=1
9962         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9963
9964         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9965         stack_trap "rm -f $DIR/$tfile"
9966         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9967
9968         # drop cache so that coming read would do rpc
9969         cancel_lru_locks osc
9970
9971         # shrink interval is set to 10, pause for 7 seconds so that
9972         # grant thread did not wake up yet but coming read entered
9973         # shrink mode for rpc (osc_should_shrink_grant())
9974         sleep 7
9975
9976         declare -a cur_grant_bytes
9977         declare -a tot_granted
9978         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9979         tot_granted[0]=$(do_facet ost1 \
9980             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9981
9982         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9983
9984         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9985         tot_granted[1]=$(do_facet ost1 \
9986             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9987
9988         # grant change should be equal on both sides
9989         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9990                 tot_granted[0] - tot_granted[1])) ||
9991                 error "grant change mismatch, "                                \
9992                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9993                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9994 }
9995 run_test 64h "grant shrink on read"
9996
9997 test_64i() {
9998         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9999                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
10000
10001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10002         remote_ost_nodsh && skip "remote OSTs with nodsh"
10003
10004         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10005         stack_trap "rm -f $DIR/$tfile"
10006
10007         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
10008
10009         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
10010         local instance=$($LFS getname -i $DIR)
10011
10012         local osc_tgt="$FSNAME-OST0000-osc-$instance"
10013         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
10014
10015         # shrink grants and simulate rpc loss
10016         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10017         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10018         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10019
10020         fail ost1
10021
10022         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10023
10024         local testid=$(echo $TESTNAME | tr '_' ' ')
10025
10026         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10027                 grep "GRANT, real grant" &&
10028                 error "client has more grants then it owns" || true
10029 }
10030 run_test 64i "shrink on reconnect"
10031
10032 # bug 1414 - set/get directories' stripe info
10033 test_65a() {
10034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10035
10036         test_mkdir $DIR/$tdir
10037         touch $DIR/$tdir/f1
10038         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10039 }
10040 run_test 65a "directory with no stripe info"
10041
10042 test_65b() {
10043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10044
10045         test_mkdir $DIR/$tdir
10046         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10047
10048         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10049                                                 error "setstripe"
10050         touch $DIR/$tdir/f2
10051         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10052 }
10053 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10054
10055 test_65c() {
10056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10057         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10058
10059         test_mkdir $DIR/$tdir
10060         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10061
10062         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10063                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10064         touch $DIR/$tdir/f3
10065         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10066 }
10067 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10068
10069 test_65d() {
10070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10071
10072         test_mkdir $DIR/$tdir
10073         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10074         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10075
10076         if [[ $STRIPECOUNT -le 0 ]]; then
10077                 sc=1
10078         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10079                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10080                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10081         else
10082                 sc=$(($STRIPECOUNT - 1))
10083         fi
10084         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10085         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10086         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10087                 error "lverify failed"
10088 }
10089 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10090
10091 test_65e() {
10092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10093
10094         # LU-16904 delete layout when root is set as PFL layout
10095         save_layout_restore_at_exit $MOUNT
10096         $LFS setstripe -d $MOUNT || error "setstripe failed"
10097
10098         test_mkdir $DIR/$tdir
10099
10100         $LFS setstripe $DIR/$tdir || error "setstripe"
10101         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10102                                         error "no stripe info failed"
10103         touch $DIR/$tdir/f6
10104         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10105 }
10106 run_test 65e "directory setstripe defaults"
10107
10108 test_65f() {
10109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10110
10111         test_mkdir $DIR/${tdir}f
10112         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10113                 error "setstripe succeeded" || true
10114 }
10115 run_test 65f "dir setstripe permission (should return error) ==="
10116
10117 test_65g() {
10118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10119
10120         # LU-16904 delete layout when root is set as PFL layout
10121         save_layout_restore_at_exit $MOUNT
10122         $LFS setstripe -d $MOUNT || error "setstripe failed"
10123
10124         test_mkdir $DIR/$tdir
10125         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10126
10127         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10128                 error "setstripe -S failed"
10129         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10130         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10131                 error "delete default stripe failed"
10132 }
10133 run_test 65g "directory setstripe -d"
10134
10135 test_65h() {
10136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10137
10138         test_mkdir $DIR/$tdir
10139         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10140
10141         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10142                 error "setstripe -S failed"
10143         test_mkdir $DIR/$tdir/dd1
10144         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10145                 error "stripe info inherit failed"
10146 }
10147 run_test 65h "directory stripe info inherit ===================="
10148
10149 test_65i() {
10150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10151
10152         save_layout_restore_at_exit $MOUNT
10153
10154         # bug6367: set non-default striping on root directory
10155         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10156
10157         # bug12836: getstripe on -1 default directory striping
10158         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10159
10160         # bug12836: getstripe -v on -1 default directory striping
10161         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10162
10163         # bug12836: new find on -1 default directory striping
10164         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10165 }
10166 run_test 65i "various tests to set root directory striping"
10167
10168 test_65j() { # bug6367
10169         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10170
10171         sync; sleep 1
10172
10173         # if we aren't already remounting for each test, do so for this test
10174         if [ "$I_MOUNTED" = "yes" ]; then
10175                 cleanup || error "failed to unmount"
10176                 setup
10177         fi
10178
10179         save_layout_restore_at_exit $MOUNT
10180
10181         $LFS setstripe -d $MOUNT || error "setstripe failed"
10182 }
10183 run_test 65j "set default striping on root directory (bug 6367)="
10184
10185 cleanup_65k() {
10186         rm -rf $DIR/$tdir
10187         wait_delete_completed
10188         do_facet $SINGLEMDS "lctl set_param -n \
10189                 osp.$ost*MDT0000.max_create_count=$max_count"
10190         do_facet $SINGLEMDS "lctl set_param -n \
10191                 osp.$ost*MDT0000.create_count=$count"
10192         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10193         echo $INACTIVE_OSC "is Activate"
10194
10195         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10196 }
10197
10198 test_65k() { # bug11679
10199         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10200         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10201         remote_mds_nodsh && skip "remote MDS with nodsh"
10202
10203         local disable_precreate=true
10204         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10205                 disable_precreate=false
10206
10207         echo "Check OST status: "
10208         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10209                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10210
10211         for OSC in $MDS_OSCS; do
10212                 echo $OSC "is active"
10213                 do_facet $SINGLEMDS lctl --device %$OSC activate
10214         done
10215
10216         for INACTIVE_OSC in $MDS_OSCS; do
10217                 local ost=$(osc_to_ost $INACTIVE_OSC)
10218                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10219                                lov.*md*.target_obd |
10220                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10221
10222                 mkdir -p $DIR/$tdir
10223                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10224                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10225
10226                 echo "Deactivate: " $INACTIVE_OSC
10227                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10228
10229                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10230                               osp.$ost*MDT0000.create_count")
10231                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10232                                   osp.$ost*MDT0000.max_create_count")
10233                 $disable_precreate &&
10234                         do_facet $SINGLEMDS "lctl set_param -n \
10235                                 osp.$ost*MDT0000.max_create_count=0"
10236
10237                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10238                         [ -f $DIR/$tdir/$idx ] && continue
10239                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10240                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10241                                 { cleanup_65k;
10242                                   error "setstripe $idx should succeed"; }
10243                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10244                 done
10245                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10246                 rmdir $DIR/$tdir
10247
10248                 do_facet $SINGLEMDS "lctl set_param -n \
10249                         osp.$ost*MDT0000.max_create_count=$max_count"
10250                 do_facet $SINGLEMDS "lctl set_param -n \
10251                         osp.$ost*MDT0000.create_count=$count"
10252                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10253                 echo $INACTIVE_OSC "is Activate"
10254
10255                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10256         done
10257 }
10258 run_test 65k "validate manual striping works properly with deactivated OSCs"
10259
10260 test_65l() { # bug 12836
10261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10262
10263         test_mkdir -p $DIR/$tdir/test_dir
10264         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10265         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10266 }
10267 run_test 65l "lfs find on -1 stripe dir ========================"
10268
10269 test_65m() {
10270         local layout=$(save_layout $MOUNT)
10271         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10272                 restore_layout $MOUNT $layout
10273                 error "setstripe should fail by non-root users"
10274         }
10275         true
10276 }
10277 run_test 65m "normal user can't set filesystem default stripe"
10278
10279 test_65n() {
10280         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10281         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10282                 skip "Need MDS version at least 2.12.50"
10283         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10284
10285         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10286         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10287         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10288
10289         save_layout_restore_at_exit $MOUNT
10290
10291         # new subdirectory under root directory should not inherit
10292         # the default layout from root
10293         # LU-16904 check if the root is set as PFL layout
10294         local numcomp=$($LFS getstripe --component-count $MOUNT)
10295
10296         if [[ $numcomp -eq 0 ]]; then
10297                 local dir1=$MOUNT/$tdir-1
10298                 mkdir $dir1 || error "mkdir $dir1 failed"
10299                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10300                         error "$dir1 shouldn't have LOV EA"
10301         fi
10302
10303         # delete the default layout on root directory
10304         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10305
10306         local dir2=$MOUNT/$tdir-2
10307         mkdir $dir2 || error "mkdir $dir2 failed"
10308         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10309                 error "$dir2 shouldn't have LOV EA"
10310
10311         # set a new striping pattern on root directory
10312         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10313         local new_def_stripe_size=$((def_stripe_size * 2))
10314         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10315                 error "set stripe size on $MOUNT failed"
10316
10317         # new file created in $dir2 should inherit the new stripe size from
10318         # the filesystem default
10319         local file2=$dir2/$tfile-2
10320         touch $file2 || error "touch $file2 failed"
10321
10322         local file2_stripe_size=$($LFS getstripe -S $file2)
10323         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10324         {
10325                 echo "file2_stripe_size: '$file2_stripe_size'"
10326                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10327                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10328         }
10329
10330         local dir3=$MOUNT/$tdir-3
10331         mkdir $dir3 || error "mkdir $dir3 failed"
10332         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10333         # the root layout, which is the actual default layout that will be used
10334         # when new files are created in $dir3.
10335         local dir3_layout=$(get_layout_param $dir3)
10336         local root_dir_layout=$(get_layout_param $MOUNT)
10337         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10338         {
10339                 echo "dir3_layout: '$dir3_layout'"
10340                 echo "root_dir_layout: '$root_dir_layout'"
10341                 error "$dir3 should show the default layout from $MOUNT"
10342         }
10343
10344         # set OST pool on root directory
10345         local pool=$TESTNAME
10346         pool_add $pool || error "add $pool failed"
10347         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10348                 error "add targets to $pool failed"
10349
10350         $LFS setstripe -p $pool $MOUNT ||
10351                 error "set OST pool on $MOUNT failed"
10352
10353         # new file created in $dir3 should inherit the pool from
10354         # the filesystem default
10355         local file3=$dir3/$tfile-3
10356         touch $file3 || error "touch $file3 failed"
10357
10358         local file3_pool=$($LFS getstripe -p $file3)
10359         [[ "$file3_pool" = "$pool" ]] ||
10360                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10361
10362         local dir4=$MOUNT/$tdir-4
10363         mkdir $dir4 || error "mkdir $dir4 failed"
10364         local dir4_layout=$(get_layout_param $dir4)
10365         root_dir_layout=$(get_layout_param $MOUNT)
10366         echo "$LFS getstripe -d $dir4"
10367         $LFS getstripe -d $dir4
10368         echo "$LFS getstripe -d $MOUNT"
10369         $LFS getstripe -d $MOUNT
10370         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10371         {
10372                 echo "dir4_layout: '$dir4_layout'"
10373                 echo "root_dir_layout: '$root_dir_layout'"
10374                 error "$dir4 should show the default layout from $MOUNT"
10375         }
10376
10377         # new file created in $dir4 should inherit the pool from
10378         # the filesystem default
10379         local file4=$dir4/$tfile-4
10380         touch $file4 || error "touch $file4 failed"
10381
10382         local file4_pool=$($LFS getstripe -p $file4)
10383         [[ "$file4_pool" = "$pool" ]] ||
10384                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10385
10386         # new subdirectory under non-root directory should inherit
10387         # the default layout from its parent directory
10388         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10389                 error "set directory layout on $dir4 failed"
10390
10391         local dir5=$dir4/$tdir-5
10392         mkdir $dir5 || error "mkdir $dir5 failed"
10393
10394         dir4_layout=$(get_layout_param $dir4)
10395         local dir5_layout=$(get_layout_param $dir5)
10396         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10397         {
10398                 echo "dir4_layout: '$dir4_layout'"
10399                 echo "dir5_layout: '$dir5_layout'"
10400                 error "$dir5 should inherit the default layout from $dir4"
10401         }
10402
10403         # though subdir under ROOT doesn't inherit default layout, but
10404         # its sub dir/file should be created with default layout.
10405         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10406         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10407                 skip "Need MDS version at least 2.12.59"
10408
10409         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10410         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10411         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10412
10413         if [ $default_lmv_hash == "none" ]; then
10414                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10415         else
10416                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10417                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10418         fi
10419
10420         $LFS setdirstripe -D -c 2 $MOUNT ||
10421                 error "setdirstripe -D -c 2 failed"
10422         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10423         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10424         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10425
10426         # $dir4 layout includes pool
10427         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10428         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10429                 error "pool lost on setstripe"
10430         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10431         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10432                 error "pool lost on compound layout setstripe"
10433 }
10434 run_test 65n "don't inherit default layout from root for new subdirectories"
10435
10436 test_65o() {
10437         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10438                 skip "need MDS version at least 2.14.57"
10439
10440         # set OST pool on root directory
10441         local pool=$TESTNAME
10442
10443         pool_add $pool || error "add $pool failed"
10444         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10445                 error "add targets to $pool failed"
10446
10447         local dir1=$MOUNT/$tdir
10448
10449         mkdir $dir1 || error "mkdir $dir1 failed"
10450
10451         # set a new striping pattern on root directory
10452         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10453
10454         $LFS setstripe -p $pool $dir1 ||
10455                 error "set directory layout on $dir1 failed"
10456
10457         # $dir1 layout includes pool
10458         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10459         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10460                 error "pool lost on setstripe"
10461         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10462         $LFS getstripe $dir1
10463         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10464                 error "pool lost on compound layout setstripe"
10465
10466         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10467                 error "setdirstripe failed on sub-dir with inherited pool"
10468         $LFS getstripe $dir1/dir2
10469         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10470                 error "pool lost on compound layout setdirstripe"
10471
10472         $LFS setstripe -E -1 -c 1 $dir1
10473         $LFS getstripe -d $dir1
10474         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10475                 error "pool lost on setstripe"
10476 }
10477 run_test 65o "pool inheritance for mdt component"
10478
10479 test_65p () { # LU-16152
10480         local src_dir=$DIR/$tdir/src_dir
10481         local dst_dir=$DIR/$tdir/dst_dir
10482         local yaml_file=$DIR/$tdir/layout.yaml
10483         local border
10484
10485         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10486                 skip "Need at least version 2.15.51"
10487
10488         test_mkdir -p $src_dir
10489         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10490                 error "failed to setstripe"
10491         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10492                 error "failed to getstripe"
10493
10494         test_mkdir -p $dst_dir
10495         $LFS setstripe --yaml $yaml_file $dst_dir ||
10496                 error "failed to setstripe with yaml file"
10497         border=$($LFS getstripe -d $dst_dir |
10498                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10499                 error "failed to getstripe"
10500
10501         # 2048M is 0x80000000, or 2147483648
10502         (( $border == 2147483648 )) ||
10503                 error "failed to handle huge number in yaml layout"
10504 }
10505 run_test 65p "setstripe with yaml file and huge number"
10506
10507 test_65q () { # LU-16194
10508         local src_dir=$DIR/$tdir/src_dir
10509
10510         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) &&
10511         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
10512                 skip "Need at least version 2.15.51"
10513
10514         test_mkdir -p $src_dir
10515         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10516         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10517                 error "should fail if extent start/end >=8E"
10518
10519         # EOF should work as before
10520         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10521                 error "failed to setstripe normally"
10522 }
10523 run_test 65q "setstripe with >=8E offset should fail"
10524
10525 # bug 2543 - update blocks count on client
10526 test_66() {
10527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10528
10529         local COUNT=${COUNT:-8}
10530         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10531         sync; sync_all_data; sync; sync_all_data
10532         cancel_lru_locks osc
10533         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10534         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10535 }
10536 run_test 66 "update inode blocks count on client ==============="
10537
10538 meminfo() {
10539         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10540 }
10541
10542 swap_used() {
10543         swapon -s | awk '($1 == "'$1'") { print $4 }'
10544 }
10545
10546 # bug5265, obdfilter oa2dentry return -ENOENT
10547 # #define OBD_FAIL_SRV_ENOENT 0x217
10548 test_69() {
10549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10550         remote_ost_nodsh && skip "remote OST with nodsh"
10551
10552         f="$DIR/$tfile"
10553         $LFS setstripe -c 1 -i 0 $f
10554         stack_trap "rm -f $f ${f}.2"
10555
10556         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10557
10558         do_facet ost1 lctl set_param fail_loc=0x217
10559         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10560         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10561
10562         do_facet ost1 lctl set_param fail_loc=0
10563         $DIRECTIO write $f 0 2 || error "write error"
10564
10565         cancel_lru_locks osc
10566         $DIRECTIO read $f 0 1 || error "read error"
10567
10568         do_facet ost1 lctl set_param fail_loc=0x217
10569         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10570
10571         do_facet ost1 lctl set_param fail_loc=0
10572 }
10573 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10574
10575 test_70a() {
10576         # Perform a really simple test of health write and health check
10577         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10578                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10579
10580         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10581
10582         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10583
10584         # Test with health write off
10585         do_facet ost1 $LCTL set_param enable_health_write off ||
10586                 error "can't set enable_health_write off"
10587         do_facet ost1 $LCTL get_param enable_health_write ||
10588                 error "can't get enable_health_write"
10589
10590         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10591                 error "not healthy (1)"
10592
10593         # Test with health write on
10594         do_facet ost1 $LCTL set_param enable_health_write on ||
10595                 error "can't set enable_health_write on"
10596         do_facet ost1 $LCTL get_param enable_health_write ||
10597                 error "can't get enable_health_write"
10598
10599         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10600                 error "not healthy (2)"
10601 }
10602 run_test 70a "verify health_check, health_write don't explode (on OST)"
10603
10604 test_71() {
10605         test_mkdir $DIR/$tdir
10606         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10607         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10608 }
10609 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10610
10611 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10613         [ "$RUNAS_ID" = "$UID" ] &&
10614                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10615         # Check that testing environment is properly set up. Skip if not
10616         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10617                 skip_env "User $RUNAS_ID does not exist - skipping"
10618
10619         touch $DIR/$tfile
10620         chmod 777 $DIR/$tfile
10621         chmod ug+s $DIR/$tfile
10622         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10623                 error "$RUNAS dd $DIR/$tfile failed"
10624         # See if we are still setuid/sgid
10625         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10626                 error "S/gid is not dropped on write"
10627         # Now test that MDS is updated too
10628         cancel_lru_locks mdc
10629         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10630                 error "S/gid is not dropped on MDS"
10631         rm -f $DIR/$tfile
10632 }
10633 run_test 72a "Test that remove suid works properly (bug5695) ===="
10634
10635 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10636         local perm
10637
10638         [ "$RUNAS_ID" = "$UID" ] &&
10639                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10640         [ "$RUNAS_ID" -eq 0 ] &&
10641                 skip_env "RUNAS_ID = 0 -- skipping"
10642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10643         # Check that testing environment is properly set up. Skip if not
10644         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10645                 skip_env "User $RUNAS_ID does not exist - skipping"
10646
10647         touch $DIR/${tfile}-f{g,u}
10648         test_mkdir $DIR/${tfile}-dg
10649         test_mkdir $DIR/${tfile}-du
10650         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10651         chmod g+s $DIR/${tfile}-{f,d}g
10652         chmod u+s $DIR/${tfile}-{f,d}u
10653         for perm in 777 2777 4777; do
10654                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10655                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10656                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10657                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10658         done
10659         true
10660 }
10661 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10662
10663 # bug 3462 - multiple simultaneous MDC requests
10664 test_73() {
10665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10666
10667         test_mkdir $DIR/d73-1
10668         test_mkdir $DIR/d73-2
10669         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10670         pid1=$!
10671
10672         lctl set_param fail_loc=0x80000129
10673         $MULTIOP $DIR/d73-1/f73-2 Oc &
10674         sleep 1
10675         lctl set_param fail_loc=0
10676
10677         $MULTIOP $DIR/d73-2/f73-3 Oc &
10678         pid3=$!
10679
10680         kill -USR1 $pid1
10681         wait $pid1 || return 1
10682
10683         sleep 25
10684
10685         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10686         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10687         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10688
10689         rm -rf $DIR/d73-*
10690 }
10691 run_test 73 "multiple MDC requests (should not deadlock)"
10692
10693 test_74a() { # bug 6149, 6184
10694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10695
10696         touch $DIR/f74a
10697         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10698         #
10699         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10700         # will spin in a tight reconnection loop
10701         $LCTL set_param fail_loc=0x8000030e
10702         # get any lock that won't be difficult - lookup works.
10703         ls $DIR/f74a
10704         $LCTL set_param fail_loc=0
10705         rm -f $DIR/f74a
10706         true
10707 }
10708 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10709
10710 test_74b() { # bug 13310
10711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10712
10713         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10714         #
10715         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10716         # will spin in a tight reconnection loop
10717         $LCTL set_param fail_loc=0x8000030e
10718         # get a "difficult" lock
10719         touch $DIR/f74b
10720         $LCTL set_param fail_loc=0
10721         rm -f $DIR/f74b
10722         true
10723 }
10724 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10725
10726 test_74c() {
10727         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10728
10729         #define OBD_FAIL_LDLM_NEW_LOCK
10730         $LCTL set_param fail_loc=0x319
10731         touch $DIR/$tfile && error "touch successful"
10732         $LCTL set_param fail_loc=0
10733         true
10734 }
10735 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10736
10737 slab_lic=/sys/kernel/slab/lustre_inode_cache
10738 num_objects() {
10739         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10740         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10741                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10742 }
10743
10744 test_76a() { # Now for b=20433, added originally in b=1443
10745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10746
10747         cancel_lru_locks osc
10748         # there may be some slab objects cached per core
10749         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10750         local before=$(num_objects)
10751         local count=$((512 * cpus))
10752         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10753         local margin=$((count / 10))
10754         if [[ -f $slab_lic/aliases ]]; then
10755                 local aliases=$(cat $slab_lic/aliases)
10756                 (( aliases > 0 )) && margin=$((margin * aliases))
10757         fi
10758
10759         echo "before slab objects: $before"
10760         for i in $(seq $count); do
10761                 touch $DIR/$tfile
10762                 rm -f $DIR/$tfile
10763         done
10764         cancel_lru_locks osc
10765         local after=$(num_objects)
10766         echo "created: $count, after slab objects: $after"
10767         # shared slab counts are not very accurate, allow significant margin
10768         # the main goal is that the cache growth is not permanently > $count
10769         while (( after > before + margin )); do
10770                 sleep 1
10771                 after=$(num_objects)
10772                 wait=$((wait + 1))
10773                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10774                 if (( wait > 60 )); then
10775                         error "inode slab grew from $before+$margin to $after"
10776                 fi
10777         done
10778 }
10779 run_test 76a "confirm clients recycle inodes properly ===="
10780
10781 test_76b() {
10782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10783         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10784
10785         local count=512
10786         local before=$(num_objects)
10787
10788         for i in $(seq $count); do
10789                 mkdir $DIR/$tdir
10790                 rmdir $DIR/$tdir
10791         done
10792
10793         local after=$(num_objects)
10794         local wait=0
10795
10796         while (( after > before )); do
10797                 sleep 1
10798                 after=$(num_objects)
10799                 wait=$((wait + 1))
10800                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10801                 if (( wait > 60 )); then
10802                         error "inode slab grew from $before to $after"
10803                 fi
10804         done
10805
10806         echo "slab objects before: $before, after: $after"
10807 }
10808 run_test 76b "confirm clients recycle directory inodes properly ===="
10809
10810 export ORIG_CSUM=""
10811 set_checksums()
10812 {
10813         # Note: in sptlrpc modes which enable its own bulk checksum, the
10814         # original crc32_le bulk checksum will be automatically disabled,
10815         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10816         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10817         # In this case set_checksums() will not be no-op, because sptlrpc
10818         # bulk checksum will be enabled all through the test.
10819
10820         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10821         lctl set_param -n osc.*.checksums $1
10822         return 0
10823 }
10824
10825 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10826                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10827 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10828                              tr -d [] | head -n1)}
10829 set_checksum_type()
10830 {
10831         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10832         rc=$?
10833         log "set checksum type to $1, rc = $rc"
10834         return $rc
10835 }
10836
10837 get_osc_checksum_type()
10838 {
10839         # arugment 1: OST name, like OST0000
10840         ost=$1
10841         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10842                         sed 's/.*\[\(.*\)\].*/\1/g')
10843         rc=$?
10844         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10845         echo $checksum_type
10846 }
10847
10848 F77_TMP=$TMP/f77-temp
10849 F77SZ=8
10850 setup_f77() {
10851         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10852                 error "error writing to $F77_TMP"
10853 }
10854
10855 test_77a() { # bug 10889
10856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10857         $GSS && skip_env "could not run with gss"
10858
10859         [ ! -f $F77_TMP ] && setup_f77
10860         set_checksums 1
10861         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10862         set_checksums 0
10863         rm -f $DIR/$tfile
10864 }
10865 run_test 77a "normal checksum read/write operation"
10866
10867 test_77b() { # bug 10889
10868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10869         $GSS && skip_env "could not run with gss"
10870
10871         [ ! -f $F77_TMP ] && setup_f77
10872         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10873         $LCTL set_param fail_loc=0x80000409
10874         set_checksums 1
10875
10876         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10877                 error "dd error: $?"
10878         $LCTL set_param fail_loc=0
10879
10880         for algo in $CKSUM_TYPES; do
10881                 cancel_lru_locks osc
10882                 set_checksum_type $algo
10883                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10884                 $LCTL set_param fail_loc=0x80000408
10885                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10886                 $LCTL set_param fail_loc=0
10887         done
10888         set_checksums 0
10889         set_checksum_type $ORIG_CSUM_TYPE
10890         rm -f $DIR/$tfile
10891 }
10892 run_test 77b "checksum error on client write, read"
10893
10894 cleanup_77c() {
10895         trap 0
10896         set_checksums 0
10897         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10898         $check_ost &&
10899                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10900         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10901         $check_ost && [ -n "$ost_file_prefix" ] &&
10902                 do_facet ost1 rm -f ${ost_file_prefix}\*
10903 }
10904
10905 test_77c() {
10906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10907         $GSS && skip_env "could not run with gss"
10908         remote_ost_nodsh && skip "remote OST with nodsh"
10909
10910         local bad1
10911         local osc_file_prefix
10912         local osc_file
10913         local check_ost=false
10914         local ost_file_prefix
10915         local ost_file
10916         local orig_cksum
10917         local dump_cksum
10918         local fid
10919
10920         # ensure corruption will occur on first OSS/OST
10921         $LFS setstripe -i 0 $DIR/$tfile
10922
10923         [ ! -f $F77_TMP ] && setup_f77
10924         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10925                 error "dd write error: $?"
10926         fid=$($LFS path2fid $DIR/$tfile)
10927
10928         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10929         then
10930                 check_ost=true
10931                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10932                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10933         else
10934                 echo "OSS do not support bulk pages dump upon error"
10935         fi
10936
10937         osc_file_prefix=$($LCTL get_param -n debug_path)
10938         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10939
10940         trap cleanup_77c EXIT
10941
10942         set_checksums 1
10943         # enable bulk pages dump upon error on Client
10944         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10945         # enable bulk pages dump upon error on OSS
10946         $check_ost &&
10947                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10948
10949         # flush Client cache to allow next read to reach OSS
10950         cancel_lru_locks osc
10951
10952         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10953         $LCTL set_param fail_loc=0x80000408
10954         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10955         $LCTL set_param fail_loc=0
10956
10957         rm -f $DIR/$tfile
10958
10959         # check cksum dump on Client
10960         osc_file=$(ls ${osc_file_prefix}*)
10961         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10962         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10963         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10964         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10965         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10966                      cksum)
10967         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10968         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10969                 error "dump content does not match on Client"
10970
10971         $check_ost || skip "No need to check cksum dump on OSS"
10972
10973         # check cksum dump on OSS
10974         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10975         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10976         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10977         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10978         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10979                 error "dump content does not match on OSS"
10980
10981         cleanup_77c
10982 }
10983 run_test 77c "checksum error on client read with debug"
10984
10985 test_77d() { # bug 10889
10986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10987         $GSS && skip_env "could not run with gss"
10988
10989         stack_trap "rm -f $DIR/$tfile"
10990         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10991         $LCTL set_param fail_loc=0x80000409
10992         set_checksums 1
10993         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10994                 error "direct write: rc=$?"
10995         $LCTL set_param fail_loc=0
10996         set_checksums 0
10997
10998         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10999         $LCTL set_param fail_loc=0x80000408
11000         set_checksums 1
11001         cancel_lru_locks osc
11002         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
11003                 error "direct read: rc=$?"
11004         $LCTL set_param fail_loc=0
11005         set_checksums 0
11006 }
11007 run_test 77d "checksum error on OST direct write, read"
11008
11009 test_77f() { # bug 10889
11010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11011         $GSS && skip_env "could not run with gss"
11012
11013         set_checksums 1
11014         stack_trap "rm -f $DIR/$tfile"
11015         for algo in $CKSUM_TYPES; do
11016                 cancel_lru_locks osc
11017                 set_checksum_type $algo
11018                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11019                 $LCTL set_param fail_loc=0x409
11020                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11021                         error "direct write succeeded"
11022                 $LCTL set_param fail_loc=0
11023         done
11024         set_checksum_type $ORIG_CSUM_TYPE
11025         set_checksums 0
11026 }
11027 run_test 77f "repeat checksum error on write (expect error)"
11028
11029 test_77g() { # bug 10889
11030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11031         $GSS && skip_env "could not run with gss"
11032         remote_ost_nodsh && skip "remote OST with nodsh"
11033
11034         [ ! -f $F77_TMP ] && setup_f77
11035
11036         local file=$DIR/$tfile
11037         stack_trap "rm -f $file" EXIT
11038
11039         $LFS setstripe -c 1 -i 0 $file
11040         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11041         do_facet ost1 lctl set_param fail_loc=0x8000021a
11042         set_checksums 1
11043         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11044                 error "write error: rc=$?"
11045         do_facet ost1 lctl set_param fail_loc=0
11046         set_checksums 0
11047
11048         cancel_lru_locks osc
11049         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11050         do_facet ost1 lctl set_param fail_loc=0x8000021b
11051         set_checksums 1
11052         cmp $F77_TMP $file || error "file compare failed"
11053         do_facet ost1 lctl set_param fail_loc=0
11054         set_checksums 0
11055 }
11056 run_test 77g "checksum error on OST write, read"
11057
11058 test_77k() { # LU-10906
11059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11060         $GSS && skip_env "could not run with gss"
11061
11062         local cksum_param="osc.$FSNAME*.checksums"
11063         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11064         local checksum
11065         local i
11066
11067         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11068         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11069         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11070
11071         for i in 0 1; do
11072                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11073                         error "failed to set checksum=$i on MGS"
11074                 wait_update $HOSTNAME "$get_checksum" $i
11075                 #remount
11076                 echo "remount client, checksum should be $i"
11077                 remount_client $MOUNT || error "failed to remount client"
11078                 checksum=$(eval $get_checksum)
11079                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11080         done
11081         # remove persistent param to avoid races with checksum mountopt below
11082         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11083                 error "failed to delete checksum on MGS"
11084
11085         for opt in "checksum" "nochecksum"; do
11086                 #remount with mount option
11087                 echo "remount client with option $opt, checksum should be $i"
11088                 umount_client $MOUNT || error "failed to umount client"
11089                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11090                         error "failed to mount client with option '$opt'"
11091                 checksum=$(eval $get_checksum)
11092                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11093                 i=$((i - 1))
11094         done
11095
11096         remount_client $MOUNT || error "failed to remount client"
11097 }
11098 run_test 77k "enable/disable checksum correctly"
11099
11100 test_77l() {
11101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11102         $GSS && skip_env "could not run with gss"
11103
11104         set_checksums 1
11105         stack_trap "set_checksums $ORIG_CSUM" EXIT
11106         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11107         local old
11108
11109         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
11110         $LCTL set_param osc.*.idle_timeout=10
11111         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
11112
11113         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11114
11115         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11116         for algo in $CKSUM_TYPES; do
11117                 set_checksum_type $algo || error "fail to set checksum type $algo"
11118                 osc_algo=$(get_osc_checksum_type OST0000)
11119                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11120
11121                 # no locks, no reqs to let the connection idle
11122                 cancel_lru_locks osc
11123                 lru_resize_disable osc
11124                 wait_osc_import_state client ost1 IDLE
11125
11126                 # ensure ost1 is connected
11127                 stat $DIR/$tfile >/dev/null || error "can't stat"
11128                 wait_osc_import_state client ost1 FULL
11129
11130                 osc_algo=$(get_osc_checksum_type OST0000)
11131                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11132         done
11133         return 0
11134 }
11135 run_test 77l "preferred checksum type is remembered after reconnected"
11136
11137 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11138 rm -f $F77_TMP
11139 unset F77_TMP
11140
11141 test_77m() {
11142         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11143                 skip "Need at least version 2.14.52"
11144         local param=checksum_speed
11145
11146         $LCTL get_param $param || error "reading $param failed"
11147
11148         csum_speeds=$($LCTL get_param -n $param)
11149
11150         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11151                 error "known checksum types are missing"
11152 }
11153 run_test 77m "Verify checksum_speed is correctly read"
11154
11155 check_filefrag_77n() {
11156         local nr_ext=0
11157         local starts=()
11158         local ends=()
11159
11160         while read extidx a b start end rest; do
11161                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11162                         nr_ext=$(( $nr_ext + 1 ))
11163                         starts+=( ${start%..} )
11164                         ends+=( ${end%:} )
11165                 fi
11166         done < <( filefrag -sv $1 )
11167
11168         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11169         return 1
11170 }
11171
11172 test_77n() {
11173         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11174
11175         touch $DIR/$tfile
11176         $TRUNCATE $DIR/$tfile 0
11177         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11178         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11179         check_filefrag_77n $DIR/$tfile ||
11180                 skip "$tfile blocks not contiguous around hole"
11181
11182         set_checksums 1
11183         stack_trap "set_checksums $ORIG_CSUM" EXIT
11184         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11185         stack_trap "rm -f $DIR/$tfile"
11186
11187         for algo in $CKSUM_TYPES; do
11188                 if [[ "$algo" =~ ^t10 ]]; then
11189                         set_checksum_type $algo ||
11190                                 error "fail to set checksum type $algo"
11191                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11192                                 error "fail to read $tfile with $algo"
11193                 fi
11194         done
11195         rm -f $DIR/$tfile
11196         return 0
11197 }
11198 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11199
11200 test_77o() {
11201         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11202                 skip "Need MDS version at least 2.14.55"
11203         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11204                 skip "Need OST version at least 2.14.55"
11205         local ofd=obdfilter
11206         local mdt=mdt
11207
11208         # print OST checksum_type
11209         echo "$ofd.$FSNAME-*.checksum_type:"
11210         do_nodes $(comma_list $(osts_nodes)) \
11211                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11212
11213         # print MDT checksum_type
11214         echo "$mdt.$FSNAME-*.checksum_type:"
11215         do_nodes $(comma_list $(mdts_nodes)) \
11216                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11217
11218         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11219                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11220
11221         (( $o_count == $OSTCOUNT )) ||
11222                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11223
11224         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11225                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11226
11227         (( $m_count == $MDSCOUNT )) ||
11228                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11229 }
11230 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11231
11232 cleanup_test_78() {
11233         trap 0
11234         rm -f $DIR/$tfile
11235 }
11236
11237 test_78() { # bug 10901
11238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11239         remote_ost || skip_env "local OST"
11240
11241         NSEQ=5
11242         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11243         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11244         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11245         echo "MemTotal: $MEMTOTAL"
11246
11247         # reserve 256MB of memory for the kernel and other running processes,
11248         # and then take 1/2 of the remaining memory for the read/write buffers.
11249         if [ $MEMTOTAL -gt 512 ] ;then
11250                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11251         else
11252                 # for those poor memory-starved high-end clusters...
11253                 MEMTOTAL=$((MEMTOTAL / 2))
11254         fi
11255         echo "Mem to use for directio: $MEMTOTAL"
11256
11257         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11258         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11259         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11260         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11261                 head -n1)
11262         echo "Smallest OST: $SMALLESTOST"
11263         [[ $SMALLESTOST -lt 10240 ]] &&
11264                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11265
11266         trap cleanup_test_78 EXIT
11267
11268         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11269                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11270
11271         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11272         echo "File size: $F78SIZE"
11273         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11274         for i in $(seq 1 $NSEQ); do
11275                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11276                 echo directIO rdwr round $i of $NSEQ
11277                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11278         done
11279
11280         cleanup_test_78
11281 }
11282 run_test 78 "handle large O_DIRECT writes correctly ============"
11283
11284 test_79() { # bug 12743
11285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11286
11287         wait_delete_completed
11288
11289         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11290         BKFREE=$(calc_osc_kbytes kbytesfree)
11291         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11292
11293         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11294         DFTOTAL=`echo $STRING | cut -d, -f1`
11295         DFUSED=`echo $STRING  | cut -d, -f2`
11296         DFAVAIL=`echo $STRING | cut -d, -f3`
11297         DFFREE=$(($DFTOTAL - $DFUSED))
11298
11299         ALLOWANCE=$((64 * $OSTCOUNT))
11300
11301         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11302            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11303                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11304         fi
11305         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11306            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11307                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11308         fi
11309         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11310            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11311                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11312         fi
11313 }
11314 run_test 79 "df report consistency check ======================="
11315
11316 test_80() { # bug 10718
11317         remote_ost_nodsh && skip "remote OST with nodsh"
11318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11319
11320         # relax strong synchronous semantics for slow backends like ZFS
11321         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11322                 local soc="obdfilter.*.sync_lock_cancel"
11323                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11324
11325                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11326                 if [ -z "$save" ]; then
11327                         soc="obdfilter.*.sync_on_lock_cancel"
11328                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11329                 fi
11330
11331                 if [ "$save" != "never" ]; then
11332                         local hosts=$(comma_list $(osts_nodes))
11333
11334                         do_nodes $hosts $LCTL set_param $soc=never
11335                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11336                 fi
11337         fi
11338
11339         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11340         sync; sleep 1; sync
11341         local before=$(date +%s)
11342         cancel_lru_locks osc
11343         local after=$(date +%s)
11344         local diff=$((after - before))
11345         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11346
11347         rm -f $DIR/$tfile
11348 }
11349 run_test 80 "Page eviction is equally fast at high offsets too"
11350
11351 test_81a() { # LU-456
11352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11353         remote_ost_nodsh && skip "remote OST with nodsh"
11354
11355         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11356         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11357         do_facet ost1 lctl set_param fail_loc=0x80000228
11358
11359         # write should trigger a retry and success
11360         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11361         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11362         RC=$?
11363         if [ $RC -ne 0 ] ; then
11364                 error "write should success, but failed for $RC"
11365         fi
11366 }
11367 run_test 81a "OST should retry write when get -ENOSPC ==============="
11368
11369 test_81b() { # LU-456
11370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11371         remote_ost_nodsh && skip "remote OST with nodsh"
11372
11373         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11374         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11375         do_facet ost1 lctl set_param fail_loc=0x228
11376
11377         # write should retry several times and return -ENOSPC finally
11378         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11379         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11380         RC=$?
11381         ENOSPC=28
11382         if [ $RC -ne $ENOSPC ] ; then
11383                 error "dd should fail for -ENOSPC, but succeed."
11384         fi
11385 }
11386 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11387
11388 test_99() {
11389         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11390
11391         test_mkdir $DIR/$tdir.cvsroot
11392         chown $RUNAS_ID $DIR/$tdir.cvsroot
11393
11394         cd $TMP
11395         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11396
11397         cd /etc/init.d
11398         # some versions of cvs import exit(1) when asked to import links or
11399         # files they can't read.  ignore those files.
11400         local toignore=$(find . -type l -printf '-I %f\n' -o \
11401                          ! -perm /4 -printf '-I %f\n')
11402         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11403                 $tdir.reposname vtag rtag
11404
11405         cd $DIR
11406         test_mkdir $DIR/$tdir.reposname
11407         chown $RUNAS_ID $DIR/$tdir.reposname
11408         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11409
11410         cd $DIR/$tdir.reposname
11411         $RUNAS touch foo99
11412         $RUNAS cvs add -m 'addmsg' foo99
11413         $RUNAS cvs update
11414         $RUNAS cvs commit -m 'nomsg' foo99
11415         rm -fr $DIR/$tdir.cvsroot
11416 }
11417 run_test 99 "cvs strange file/directory operations"
11418
11419 test_100() {
11420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11421         [[ "$NETTYPE" =~ tcp ]] ||
11422                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11423         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11424         remote_ost_nodsh && skip "remote OST with nodsh"
11425         remote_mds_nodsh && skip "remote MDS with nodsh"
11426         remote_servers || skip "useless for local single node setup"
11427
11428         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11429                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11430
11431                 rc=0
11432                 if (( ${LOCAL/*:/} >= 1024 )); then
11433                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11434                         ss -tna
11435                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11436                 fi
11437         done
11438         (( $rc == 0 )) || error "privileged port not found" )
11439 }
11440 run_test 100 "check local port using privileged port"
11441
11442 function get_named_value()
11443 {
11444     local tag=$1
11445
11446     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11447 }
11448
11449 test_101a() {
11450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11451
11452         local s
11453         local discard
11454         local nreads=10000
11455         local cache_limit=32
11456
11457         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11458         $LCTL set_param -n llite.*.read_ahead_stats=0
11459         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11460                               awk '/^max_cached_mb/ { print $2 }')
11461         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11462         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11463
11464         #
11465         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11466         #
11467         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11468         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11469
11470         discard=0
11471         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11472                    get_named_value 'read.but.discarded'); do
11473                         discard=$(($discard + $s))
11474         done
11475
11476         $LCTL get_param osc.*-osc*.rpc_stats
11477         $LCTL get_param llite.*.read_ahead_stats
11478
11479         # Discard is generally zero, but sometimes a few random reads line up
11480         # and trigger larger readahead, which is wasted & leads to discards.
11481         if [[ $(($discard)) -gt $nreads ]]; then
11482                 error "too many ($discard) discarded pages"
11483         fi
11484         rm -f $DIR/$tfile || true
11485 }
11486 run_test 101a "check read-ahead for random reads"
11487
11488 setup_test101bc() {
11489         test_mkdir $DIR/$tdir
11490         local ssize=$1
11491         local FILE_LENGTH=$2
11492         STRIPE_OFFSET=0
11493
11494         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11495
11496         local list=$(comma_list $(osts_nodes))
11497         set_osd_param $list '' read_cache_enable 0
11498         set_osd_param $list '' writethrough_cache_enable 0
11499
11500         trap cleanup_test101bc EXIT
11501         # prepare the read-ahead file
11502         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11503
11504         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11505                                 count=$FILE_SIZE_MB 2> /dev/null
11506
11507 }
11508
11509 cleanup_test101bc() {
11510         trap 0
11511         rm -rf $DIR/$tdir
11512         rm -f $DIR/$tfile
11513
11514         local list=$(comma_list $(osts_nodes))
11515         set_osd_param $list '' read_cache_enable 1
11516         set_osd_param $list '' writethrough_cache_enable 1
11517 }
11518
11519 ra_check_101() {
11520         local read_size=$1
11521         local stripe_size=$2
11522         local stride_length=$((stripe_size / read_size))
11523         local stride_width=$((stride_length * OSTCOUNT))
11524         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11525                                 (stride_width - stride_length) ))
11526         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11527                   get_named_value 'read.but.discarded' | calc_sum)
11528
11529         if [[ $discard -gt $discard_limit ]]; then
11530                 $LCTL get_param llite.*.read_ahead_stats
11531                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11532         else
11533                 echo "Read-ahead success for size ${read_size}"
11534         fi
11535 }
11536
11537 test_101b() {
11538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11539         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11540
11541         local STRIPE_SIZE=1048576
11542         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11543
11544         if [ $SLOW == "yes" ]; then
11545                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11546         else
11547                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11548         fi
11549
11550         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11551
11552         # prepare the read-ahead file
11553         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11554         cancel_lru_locks osc
11555         for BIDX in 2 4 8 16 32 64 128 256
11556         do
11557                 local BSIZE=$((BIDX*4096))
11558                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11559                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11560                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11561                 $LCTL set_param -n llite.*.read_ahead_stats=0
11562                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11563                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11564                 cancel_lru_locks osc
11565                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11566         done
11567         cleanup_test101bc
11568         true
11569 }
11570 run_test 101b "check stride-io mode read-ahead ================="
11571
11572 test_101c() {
11573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11574
11575         local STRIPE_SIZE=1048576
11576         local FILE_LENGTH=$((STRIPE_SIZE*100))
11577         local nreads=10000
11578         local rsize=65536
11579         local osc_rpc_stats
11580
11581         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11582
11583         cancel_lru_locks osc
11584         $LCTL set_param osc.*.rpc_stats=0
11585         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11586         $LCTL get_param osc.*.rpc_stats
11587         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11588                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11589                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11590                 local size
11591
11592                 if [ $lines -le 20 ]; then
11593                         echo "continue debug"
11594                         continue
11595                 fi
11596                 for size in 1 2 4 8; do
11597                         local rpc=$(echo "$stats" |
11598                                     awk '($1 == "'$size':") {print $2; exit; }')
11599                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11600                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11601                 done
11602                 echo "$osc_rpc_stats check passed!"
11603         done
11604         cleanup_test101bc
11605         true
11606 }
11607 run_test 101c "check stripe_size aligned read-ahead"
11608
11609 test_101d() {
11610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11611
11612         local file=$DIR/$tfile
11613         local sz_MB=${FILESIZE_101d:-80}
11614         local ra_MB=${READAHEAD_MB:-40}
11615
11616         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11617         [ $free_MB -lt $sz_MB ] &&
11618                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11619
11620         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11621         $LFS setstripe -c -1 $file || error "setstripe failed"
11622
11623         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11624         echo Cancel LRU locks on lustre client to flush the client cache
11625         cancel_lru_locks osc
11626
11627         echo Disable read-ahead
11628         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11629         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11630         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11631         $LCTL get_param -n llite.*.max_read_ahead_mb
11632
11633         echo "Reading the test file $file with read-ahead disabled"
11634         local sz_KB=$((sz_MB * 1024 / 4))
11635         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11636         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11637         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11638         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11639                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11640
11641         echo "Cancel LRU locks on lustre client to flush the client cache"
11642         cancel_lru_locks osc
11643         echo Enable read-ahead with ${ra_MB}MB
11644         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11645
11646         echo "Reading the test file $file with read-ahead enabled"
11647         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11648                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11649
11650         echo "read-ahead disabled time read '$raOFF'"
11651         echo "read-ahead enabled time read '$raON'"
11652
11653         rm -f $file
11654         wait_delete_completed
11655
11656         # use awk for this check instead of bash because it handles decimals
11657         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11658                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11659 }
11660 run_test 101d "file read with and without read-ahead enabled"
11661
11662 test_101e() {
11663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11664
11665         local file=$DIR/$tfile
11666         local size_KB=500  #KB
11667         local count=100
11668         local bsize=1024
11669
11670         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11671         local need_KB=$((count * size_KB))
11672         [[ $free_KB -le $need_KB ]] &&
11673                 skip_env "Need free space $need_KB, have $free_KB"
11674
11675         echo "Creating $count ${size_KB}K test files"
11676         for ((i = 0; i < $count; i++)); do
11677                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11678         done
11679
11680         echo "Cancel LRU locks on lustre client to flush the client cache"
11681         cancel_lru_locks $OSC
11682
11683         echo "Reset readahead stats"
11684         $LCTL set_param -n llite.*.read_ahead_stats=0
11685
11686         for ((i = 0; i < $count; i++)); do
11687                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11688         done
11689
11690         $LCTL get_param llite.*.max_cached_mb
11691         $LCTL get_param llite.*.read_ahead_stats
11692         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11693                      get_named_value 'misses' | calc_sum)
11694
11695         for ((i = 0; i < $count; i++)); do
11696                 rm -rf $file.$i 2>/dev/null
11697         done
11698
11699         #10000 means 20% reads are missing in readahead
11700         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11701 }
11702 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11703
11704 test_101f() {
11705         which iozone || skip_env "no iozone installed"
11706
11707         local old_debug=$($LCTL get_param debug)
11708         old_debug=${old_debug#*=}
11709         $LCTL set_param debug="reada mmap"
11710
11711         # create a test file
11712         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11713
11714         echo Cancel LRU locks on lustre client to flush the client cache
11715         cancel_lru_locks osc
11716
11717         echo Reset readahead stats
11718         $LCTL set_param -n llite.*.read_ahead_stats=0
11719
11720         echo mmap read the file with small block size
11721         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11722                 > /dev/null 2>&1
11723
11724         echo checking missing pages
11725         $LCTL get_param llite.*.read_ahead_stats
11726         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11727                         get_named_value 'misses' | calc_sum)
11728
11729         $LCTL set_param debug="$old_debug"
11730         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11731         rm -f $DIR/$tfile
11732 }
11733 run_test 101f "check mmap read performance"
11734
11735 test_101g_brw_size_test() {
11736         local mb=$1
11737         local pages=$((mb * 1048576 / PAGE_SIZE))
11738         local file=$DIR/$tfile
11739
11740         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11741                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11742         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11743                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11744                         return 2
11745         done
11746
11747         stack_trap "rm -f $file" EXIT
11748         $LCTL set_param -n osc.*.rpc_stats=0
11749
11750         # 10 RPCs should be enough for the test
11751         local count=10
11752         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11753                 { error "dd write ${mb} MB blocks failed"; return 3; }
11754         cancel_lru_locks osc
11755         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11756                 { error "dd write ${mb} MB blocks failed"; return 4; }
11757
11758         # calculate number of full-sized read and write RPCs
11759         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11760                 sed -n '/pages per rpc/,/^$/p' |
11761                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11762                 END { print reads,writes }'))
11763         # allow one extra full-sized read RPC for async readahead
11764         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11765                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11766         [[ ${rpcs[1]} == $count ]] ||
11767                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11768 }
11769
11770 test_101g() {
11771         remote_ost_nodsh && skip "remote OST with nodsh"
11772
11773         local rpcs
11774         local osts=$(get_facets OST)
11775         local list=$(comma_list $(osts_nodes))
11776         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11777         local brw_size="obdfilter.*.brw_size"
11778
11779         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11780
11781         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11782
11783         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11784                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11785                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11786            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11787                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11788                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11789
11790                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11791                         suffix="M"
11792
11793                 if [[ $orig_mb -lt 16 ]]; then
11794                         save_lustre_params $osts "$brw_size" > $p
11795                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11796                                 error "set 16MB RPC size failed"
11797
11798                         echo "remount client to enable new RPC size"
11799                         remount_client $MOUNT || error "remount_client failed"
11800                 fi
11801
11802                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11803                 # should be able to set brw_size=12, but no rpc_stats for that
11804                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11805         fi
11806
11807         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11808
11809         if [[ $orig_mb -lt 16 ]]; then
11810                 restore_lustre_params < $p
11811                 remount_client $MOUNT || error "remount_client restore failed"
11812         fi
11813
11814         rm -f $p $DIR/$tfile
11815 }
11816 run_test 101g "Big bulk(4/16 MiB) readahead"
11817
11818 test_101h() {
11819         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11820
11821         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11822                 error "dd 70M file failed"
11823         echo Cancel LRU locks on lustre client to flush the client cache
11824         cancel_lru_locks osc
11825
11826         echo "Reset readahead stats"
11827         $LCTL set_param -n llite.*.read_ahead_stats 0
11828
11829         echo "Read 10M of data but cross 64M bundary"
11830         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11831         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11832                      get_named_value 'misses' | calc_sum)
11833         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11834         rm -f $p $DIR/$tfile
11835 }
11836 run_test 101h "Readahead should cover current read window"
11837
11838 test_101i() {
11839         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11840                 error "dd 10M file failed"
11841
11842         local max_per_file_mb=$($LCTL get_param -n \
11843                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11844         cancel_lru_locks osc
11845         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11846         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11847                 error "set max_read_ahead_per_file_mb to 1 failed"
11848
11849         echo "Reset readahead stats"
11850         $LCTL set_param llite.*.read_ahead_stats=0
11851
11852         dd if=$DIR/$tfile of=/dev/null bs=2M
11853
11854         $LCTL get_param llite.*.read_ahead_stats
11855         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11856                      awk '/misses/ { print $2 }')
11857         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11858         rm -f $DIR/$tfile
11859 }
11860 run_test 101i "allow current readahead to exceed reservation"
11861
11862 test_101j() {
11863         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11864                 error "setstripe $DIR/$tfile failed"
11865         local file_size=$((1048576 * 16))
11866         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11867         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11868
11869         echo Disable read-ahead
11870         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11871
11872         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11873         for blk in $PAGE_SIZE 1048576 $file_size; do
11874                 cancel_lru_locks osc
11875                 echo "Reset readahead stats"
11876                 $LCTL set_param -n llite.*.read_ahead_stats=0
11877                 local count=$(($file_size / $blk))
11878                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11879                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11880                              get_named_value 'failed.to.fast.read' | calc_sum)
11881                 $LCTL get_param -n llite.*.read_ahead_stats
11882                 [ $miss -eq $count ] || error "expected $count got $miss"
11883         done
11884
11885         rm -f $p $DIR/$tfile
11886 }
11887 run_test 101j "A complete read block should be submitted when no RA"
11888
11889 test_readahead_base() {
11890         local file=$DIR/$tfile
11891         local size=$1
11892         local iosz
11893         local ramax
11894         local ranum
11895
11896         $LCTL set_param -n llite.*.read_ahead_stats=0
11897         # The first page is not accounted into readahead
11898         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11899         iosz=$(((size + 1048575) / 1048576 * 1048576))
11900         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11901
11902         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11903         fallocate -l $size $file || error "failed to fallocate $file"
11904         cancel_lru_locks osc
11905         $MULTIOP $file or${iosz}c || error "failed to read $file"
11906         $LCTL get_param -n llite.*.read_ahead_stats
11907         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11908                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11909         (( $ranum <= $ramax )) ||
11910                 error "read-ahead pages is $ranum more than $ramax"
11911         rm -rf $file || error "failed to remove $file"
11912 }
11913
11914 test_101m()
11915 {
11916         local file=$DIR/$tfile
11917         local ramax
11918         local ranum
11919         local size
11920         local iosz
11921
11922         check_set_fallocate_or_skip
11923         stack_trap "rm -f $file" EXIT
11924
11925         test_readahead_base 4096
11926
11927         # file size: 16K = 16384
11928         test_readahead_base 16384
11929         test_readahead_base 16385
11930         test_readahead_base 16383
11931
11932         # file size: 1M + 1 = 1048576 + 1
11933         test_readahead_base 1048577
11934         # file size: 1M + 16K
11935         test_readahead_base $((1048576 + 16384))
11936
11937         # file size: stripe_size * (stripe_count - 1) + 16K
11938         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11939         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11940         # file size: stripe_size * stripe_count + 16K
11941         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11942         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11943         # file size: 2 * stripe_size * stripe_count + 16K
11944         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11945         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11946 }
11947 run_test 101m "read ahead for small file and last stripe of the file"
11948
11949 setup_test102() {
11950         test_mkdir $DIR/$tdir
11951         chown $RUNAS_ID $DIR/$tdir
11952         STRIPE_SIZE=65536
11953         STRIPE_OFFSET=1
11954         STRIPE_COUNT=$OSTCOUNT
11955         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11956
11957         trap cleanup_test102 EXIT
11958         cd $DIR
11959         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11960         cd $DIR/$tdir
11961         for num in 1 2 3 4; do
11962                 for count in $(seq 1 $STRIPE_COUNT); do
11963                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11964                                 local size=`expr $STRIPE_SIZE \* $num`
11965                                 local file=file"$num-$idx-$count"
11966                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11967                         done
11968                 done
11969         done
11970
11971         cd $DIR
11972         $1 tar cf $TMP/f102.tar $tdir --xattrs
11973 }
11974
11975 cleanup_test102() {
11976         trap 0
11977         rm -f $TMP/f102.tar
11978         rm -rf $DIR/d0.sanity/d102
11979 }
11980
11981 test_102a() {
11982         [ "$UID" != 0 ] && skip "must run as root"
11983         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11984                 skip_env "must have user_xattr"
11985
11986         [ -z "$(which setfattr 2>/dev/null)" ] &&
11987                 skip_env "could not find setfattr"
11988
11989         local testfile=$DIR/$tfile
11990
11991         touch $testfile
11992         echo "set/get xattr..."
11993         setfattr -n trusted.name1 -v value1 $testfile ||
11994                 error "setfattr -n trusted.name1=value1 $testfile failed"
11995         getfattr -n trusted.name1 $testfile 2> /dev/null |
11996           grep "trusted.name1=.value1" ||
11997                 error "$testfile missing trusted.name1=value1"
11998
11999         setfattr -n user.author1 -v author1 $testfile ||
12000                 error "setfattr -n user.author1=author1 $testfile failed"
12001         getfattr -n user.author1 $testfile 2> /dev/null |
12002           grep "user.author1=.author1" ||
12003                 error "$testfile missing trusted.author1=author1"
12004
12005         echo "listxattr..."
12006         setfattr -n trusted.name2 -v value2 $testfile ||
12007                 error "$testfile unable to set trusted.name2"
12008         setfattr -n trusted.name3 -v value3 $testfile ||
12009                 error "$testfile unable to set trusted.name3"
12010         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
12011             grep "trusted.name" | wc -l) -eq 3 ] ||
12012                 error "$testfile missing 3 trusted.name xattrs"
12013
12014         setfattr -n user.author2 -v author2 $testfile ||
12015                 error "$testfile unable to set user.author2"
12016         setfattr -n user.author3 -v author3 $testfile ||
12017                 error "$testfile unable to set user.author3"
12018         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12019             grep "user.author" | wc -l) -eq 3 ] ||
12020                 error "$testfile missing 3 user.author xattrs"
12021
12022         echo "remove xattr..."
12023         setfattr -x trusted.name1 $testfile ||
12024                 error "$testfile error deleting trusted.name1"
12025         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12026                 error "$testfile did not delete trusted.name1 xattr"
12027
12028         setfattr -x user.author1 $testfile ||
12029                 error "$testfile error deleting user.author1"
12030         echo "set lustre special xattr ..."
12031         $LFS setstripe -c1 $testfile
12032         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12033                 awk -F "=" '/trusted.lov/ { print $2 }' )
12034         setfattr -n "trusted.lov" -v $lovea $testfile ||
12035                 error "$testfile doesn't ignore setting trusted.lov again"
12036         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12037                 error "$testfile allow setting invalid trusted.lov"
12038         rm -f $testfile
12039 }
12040 run_test 102a "user xattr test =================================="
12041
12042 check_102b_layout() {
12043         local layout="$*"
12044         local testfile=$DIR/$tfile
12045
12046         echo "test layout '$layout'"
12047         $LFS setstripe $layout $testfile || error "setstripe failed"
12048         $LFS getstripe -y $testfile
12049
12050         echo "get/set/list trusted.lov xattr ..." # b=10930
12051         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12052         [[ "$value" =~ "trusted.lov" ]] ||
12053                 error "can't get trusted.lov from $testfile"
12054         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12055                 error "getstripe failed"
12056
12057         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12058
12059         value=$(cut -d= -f2 <<<$value)
12060         # LU-13168: truncated xattr should fail if short lov_user_md header
12061         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12062                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12063         for len in $lens; do
12064                 echo "setfattr $len $testfile.2"
12065                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12066                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12067         done
12068         local stripe_size=$($LFS getstripe -S $testfile.2)
12069         local stripe_count=$($LFS getstripe -c $testfile.2)
12070         [[ $stripe_size -eq 65536 ]] ||
12071                 error "stripe size $stripe_size != 65536"
12072         [[ $stripe_count -eq $stripe_count_orig ]] ||
12073                 error "stripe count $stripe_count != $stripe_count_orig"
12074         rm $testfile $testfile.2
12075 }
12076
12077 test_102b() {
12078         [ -z "$(which setfattr 2>/dev/null)" ] &&
12079                 skip_env "could not find setfattr"
12080         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12081
12082         # check plain layout
12083         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12084
12085         # and also check composite layout
12086         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12087
12088 }
12089 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12090
12091 test_102c() {
12092         [ -z "$(which setfattr 2>/dev/null)" ] &&
12093                 skip_env "could not find setfattr"
12094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12095
12096         # b10930: get/set/list lustre.lov xattr
12097         echo "get/set/list lustre.lov xattr ..."
12098         test_mkdir $DIR/$tdir
12099         chown $RUNAS_ID $DIR/$tdir
12100         local testfile=$DIR/$tdir/$tfile
12101         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12102                 error "setstripe failed"
12103         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12104                 error "getstripe failed"
12105         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12106         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12107
12108         local testfile2=${testfile}2
12109         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12110                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12111
12112         $RUNAS $MCREATE $testfile2
12113         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12114         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12115         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12116         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12117         [ $stripe_count -eq $STRIPECOUNT ] ||
12118                 error "stripe count $stripe_count != $STRIPECOUNT"
12119 }
12120 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12121
12122 compare_stripe_info1() {
12123         local stripe_index_all_zero=true
12124
12125         for num in 1 2 3 4; do
12126                 for count in $(seq 1 $STRIPE_COUNT); do
12127                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12128                                 local size=$((STRIPE_SIZE * num))
12129                                 local file=file"$num-$offset-$count"
12130                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12131                                 [[ $stripe_size -ne $size ]] &&
12132                                     error "$file: size $stripe_size != $size"
12133                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12134                                 # allow fewer stripes to be created, ORI-601
12135                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12136                                     error "$file: count $stripe_count != $count"
12137                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12138                                 [[ $stripe_index -ne 0 ]] &&
12139                                         stripe_index_all_zero=false
12140                         done
12141                 done
12142         done
12143         $stripe_index_all_zero &&
12144                 error "all files are being extracted starting from OST index 0"
12145         return 0
12146 }
12147
12148 have_xattrs_include() {
12149         tar --help | grep -q xattrs-include &&
12150                 echo --xattrs-include="lustre.*"
12151 }
12152
12153 test_102d() {
12154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12155         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12156
12157         XINC=$(have_xattrs_include)
12158         setup_test102
12159         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12160         cd $DIR/$tdir/$tdir
12161         compare_stripe_info1
12162 }
12163 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12164
12165 test_102f() {
12166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12167         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12168
12169         XINC=$(have_xattrs_include)
12170         setup_test102
12171         test_mkdir $DIR/$tdir.restore
12172         cd $DIR
12173         tar cf - --xattrs $tdir | tar xf - \
12174                 -C $DIR/$tdir.restore --xattrs $XINC
12175         cd $DIR/$tdir.restore/$tdir
12176         compare_stripe_info1
12177 }
12178 run_test 102f "tar copy files, not keep osts"
12179
12180 grow_xattr() {
12181         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12182                 skip "must have user_xattr"
12183         [ -z "$(which setfattr 2>/dev/null)" ] &&
12184                 skip_env "could not find setfattr"
12185         [ -z "$(which getfattr 2>/dev/null)" ] &&
12186                 skip_env "could not find getfattr"
12187
12188         local xsize=${1:-1024}  # in bytes
12189         local file=$DIR/$tfile
12190         local value="$(generate_string $xsize)"
12191         local xbig=trusted.big
12192         local toobig=$2
12193
12194         touch $file
12195         log "save $xbig on $file"
12196         if [ -z "$toobig" ]
12197         then
12198                 setfattr -n $xbig -v $value $file ||
12199                         error "saving $xbig on $file failed"
12200         else
12201                 setfattr -n $xbig -v $value $file &&
12202                         error "saving $xbig on $file succeeded"
12203                 return 0
12204         fi
12205
12206         local orig=$(get_xattr_value $xbig $file)
12207         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12208
12209         local xsml=trusted.sml
12210         log "save $xsml on $file"
12211         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12212
12213         local new=$(get_xattr_value $xbig $file)
12214         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12215
12216         log "grow $xsml on $file"
12217         setfattr -n $xsml -v "$value" $file ||
12218                 error "growing $xsml on $file failed"
12219
12220         new=$(get_xattr_value $xbig $file)
12221         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12222         log "$xbig still valid after growing $xsml"
12223
12224         rm -f $file
12225 }
12226
12227 test_102h() { # bug 15777
12228         grow_xattr 1024
12229 }
12230 run_test 102h "grow xattr from inside inode to external block"
12231
12232 test_102ha() {
12233         large_xattr_enabled || skip_env "ea_inode feature disabled"
12234
12235         echo "setting xattr of max xattr size: $(max_xattr_size)"
12236         grow_xattr $(max_xattr_size)
12237
12238         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12239         echo "This should fail:"
12240         grow_xattr $(($(max_xattr_size) + 10)) 1
12241 }
12242 run_test 102ha "grow xattr from inside inode to external inode"
12243
12244 test_102i() { # bug 17038
12245         [ -z "$(which getfattr 2>/dev/null)" ] &&
12246                 skip "could not find getfattr"
12247
12248         touch $DIR/$tfile
12249         ln -s $DIR/$tfile $DIR/${tfile}link
12250         getfattr -n trusted.lov $DIR/$tfile ||
12251                 error "lgetxattr on $DIR/$tfile failed"
12252         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12253                 grep -i "no such attr" ||
12254                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12255         rm -f $DIR/$tfile $DIR/${tfile}link
12256 }
12257 run_test 102i "lgetxattr test on symbolic link ============"
12258
12259 test_102j() {
12260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12261         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12262
12263         XINC=$(have_xattrs_include)
12264         setup_test102 "$RUNAS"
12265         chown $RUNAS_ID $DIR/$tdir
12266         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12267         cd $DIR/$tdir/$tdir
12268         compare_stripe_info1 "$RUNAS"
12269 }
12270 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12271
12272 test_102k() {
12273         [ -z "$(which setfattr 2>/dev/null)" ] &&
12274                 skip "could not find setfattr"
12275
12276         touch $DIR/$tfile
12277         # b22187 just check that does not crash for regular file.
12278         setfattr -n trusted.lov $DIR/$tfile
12279         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12280         local test_kdir=$DIR/$tdir
12281         test_mkdir $test_kdir
12282         local default_size=$($LFS getstripe -S $test_kdir)
12283         local default_count=$($LFS getstripe -c $test_kdir)
12284         local default_offset=$($LFS getstripe -i $test_kdir)
12285         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12286                 error 'dir setstripe failed'
12287         setfattr -n trusted.lov $test_kdir
12288         local stripe_size=$($LFS getstripe -S $test_kdir)
12289         local stripe_count=$($LFS getstripe -c $test_kdir)
12290         local stripe_offset=$($LFS getstripe -i $test_kdir)
12291         [ $stripe_size -eq $default_size ] ||
12292                 error "stripe size $stripe_size != $default_size"
12293         [ $stripe_count -eq $default_count ] ||
12294                 error "stripe count $stripe_count != $default_count"
12295         [ $stripe_offset -eq $default_offset ] ||
12296                 error "stripe offset $stripe_offset != $default_offset"
12297         rm -rf $DIR/$tfile $test_kdir
12298 }
12299 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12300
12301 test_102l() {
12302         [ -z "$(which getfattr 2>/dev/null)" ] &&
12303                 skip "could not find getfattr"
12304
12305         # LU-532 trusted. xattr is invisible to non-root
12306         local testfile=$DIR/$tfile
12307
12308         touch $testfile
12309
12310         echo "listxattr as user..."
12311         chown $RUNAS_ID $testfile
12312         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12313             grep -q "trusted" &&
12314                 error "$testfile trusted xattrs are user visible"
12315
12316         return 0;
12317 }
12318 run_test 102l "listxattr size test =================================="
12319
12320 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12321         local path=$DIR/$tfile
12322         touch $path
12323
12324         listxattr_size_check $path || error "listattr_size_check $path failed"
12325 }
12326 run_test 102m "Ensure listxattr fails on small bufffer ========"
12327
12328 cleanup_test102
12329
12330 getxattr() { # getxattr path name
12331         # Return the base64 encoding of the value of xattr name on path.
12332         local path=$1
12333         local name=$2
12334
12335         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12336         # file: $path
12337         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12338         #
12339         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12340
12341         getfattr --absolute-names --encoding=base64 --name=$name $path |
12342                 awk -F= -v name=$name '$1 == name {
12343                         print substr($0, index($0, "=") + 1);
12344         }'
12345 }
12346
12347 test_102n() { # LU-4101 mdt: protect internal xattrs
12348         [ -z "$(which setfattr 2>/dev/null)" ] &&
12349                 skip "could not find setfattr"
12350         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12351         then
12352                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12353         fi
12354
12355         local file0=$DIR/$tfile.0
12356         local file1=$DIR/$tfile.1
12357         local xattr0=$TMP/$tfile.0
12358         local xattr1=$TMP/$tfile.1
12359         local namelist="lov lma lmv link fid version som hsm"
12360         local name
12361         local value
12362
12363         rm -rf $file0 $file1 $xattr0 $xattr1
12364         touch $file0 $file1
12365
12366         # Get 'before' xattrs of $file1.
12367         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12368
12369         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12370                 namelist+=" lfsck_namespace"
12371         for name in $namelist; do
12372                 # Try to copy xattr from $file0 to $file1.
12373                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12374
12375                 setfattr --name=trusted.$name --value="$value" $file1 ||
12376                         error "setxattr 'trusted.$name' failed"
12377
12378                 # Try to set a garbage xattr.
12379                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12380
12381                 if [[ x$name == "xlov" ]]; then
12382                         setfattr --name=trusted.lov --value="$value" $file1 &&
12383                         error "setxattr invalid 'trusted.lov' success"
12384                 else
12385                         setfattr --name=trusted.$name --value="$value" $file1 ||
12386                                 error "setxattr invalid 'trusted.$name' failed"
12387                 fi
12388
12389                 # Try to remove the xattr from $file1. We don't care if this
12390                 # appears to succeed or fail, we just don't want there to be
12391                 # any changes or crashes.
12392                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12393         done
12394
12395         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12396         then
12397                 name="lfsck_ns"
12398                 # Try to copy xattr from $file0 to $file1.
12399                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12400
12401                 setfattr --name=trusted.$name --value="$value" $file1 ||
12402                         error "setxattr 'trusted.$name' failed"
12403
12404                 # Try to set a garbage xattr.
12405                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12406
12407                 setfattr --name=trusted.$name --value="$value" $file1 ||
12408                         error "setxattr 'trusted.$name' failed"
12409
12410                 # Try to remove the xattr from $file1. We don't care if this
12411                 # appears to succeed or fail, we just don't want there to be
12412                 # any changes or crashes.
12413                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12414         fi
12415
12416         # Get 'after' xattrs of file1.
12417         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12418
12419         if ! diff $xattr0 $xattr1; then
12420                 error "before and after xattrs of '$file1' differ"
12421         fi
12422
12423         rm -rf $file0 $file1 $xattr0 $xattr1
12424
12425         return 0
12426 }
12427 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12428
12429 test_102p() { # LU-4703 setxattr did not check ownership
12430         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12431                 skip "MDS needs to be at least 2.5.56"
12432
12433         local testfile=$DIR/$tfile
12434
12435         touch $testfile
12436
12437         echo "setfacl as user..."
12438         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12439         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12440
12441         echo "setfattr as user..."
12442         setfacl -m "u:$RUNAS_ID:---" $testfile
12443         $RUNAS setfattr -x system.posix_acl_access $testfile
12444         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12445 }
12446 run_test 102p "check setxattr(2) correctly fails without permission"
12447
12448 test_102q() {
12449         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12450                 skip "MDS needs to be at least 2.6.92"
12451
12452         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12453 }
12454 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12455
12456 test_102r() {
12457         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12458                 skip "MDS needs to be at least 2.6.93"
12459
12460         touch $DIR/$tfile || error "touch"
12461         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12462         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12463         rm $DIR/$tfile || error "rm"
12464
12465         #normal directory
12466         mkdir -p $DIR/$tdir || error "mkdir"
12467         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12468         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12469         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12470                 error "$testfile error deleting user.author1"
12471         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12472                 grep "user.$(basename $tdir)" &&
12473                 error "$tdir did not delete user.$(basename $tdir)"
12474         rmdir $DIR/$tdir || error "rmdir"
12475
12476         #striped directory
12477         test_mkdir $DIR/$tdir
12478         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12479         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12480         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12481                 error "$testfile error deleting user.author1"
12482         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12483                 grep "user.$(basename $tdir)" &&
12484                 error "$tdir did not delete user.$(basename $tdir)"
12485         rmdir $DIR/$tdir || error "rm striped dir"
12486 }
12487 run_test 102r "set EAs with empty values"
12488
12489 test_102s() {
12490         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12491                 skip "MDS needs to be at least 2.11.52"
12492
12493         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12494
12495         save_lustre_params client "llite.*.xattr_cache" > $save
12496
12497         for cache in 0 1; do
12498                 lctl set_param llite.*.xattr_cache=$cache
12499
12500                 rm -f $DIR/$tfile
12501                 touch $DIR/$tfile || error "touch"
12502                 for prefix in lustre security system trusted user; do
12503                         # Note getxattr() may fail with 'Operation not
12504                         # supported' or 'No such attribute' depending
12505                         # on prefix and cache.
12506                         getfattr -n $prefix.n102s $DIR/$tfile &&
12507                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12508                 done
12509         done
12510
12511         restore_lustre_params < $save
12512 }
12513 run_test 102s "getting nonexistent xattrs should fail"
12514
12515 test_102t() {
12516         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12517                 skip "MDS needs to be at least 2.11.52"
12518
12519         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12520
12521         save_lustre_params client "llite.*.xattr_cache" > $save
12522
12523         for cache in 0 1; do
12524                 lctl set_param llite.*.xattr_cache=$cache
12525
12526                 for buf_size in 0 256; do
12527                         rm -f $DIR/$tfile
12528                         touch $DIR/$tfile || error "touch"
12529                         setfattr -n user.multiop $DIR/$tfile
12530                         $MULTIOP $DIR/$tfile oa$buf_size ||
12531                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12532                 done
12533         done
12534
12535         restore_lustre_params < $save
12536 }
12537 run_test 102t "zero length xattr values handled correctly"
12538
12539 run_acl_subtest()
12540 {
12541         local test=$LUSTRE/tests/acl/$1.test
12542         local tmp=$(mktemp -t $1-XXXXXX).test
12543         local bin=$2
12544         local dmn=$3
12545         local grp=$4
12546         local nbd=$5
12547         export LANG=C
12548
12549
12550         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12551         local sedgroups="-e s/:users/:$grp/g"
12552         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12553
12554         sed $sedusers $sedgroups < $test > $tmp
12555         stack_trap "rm -f $tmp"
12556         [[ -s $tmp ]] || error "sed failed to create test script"
12557
12558         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12559         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12560 }
12561
12562 test_103a() {
12563         [ "$UID" != 0 ] && skip "must run as root"
12564         $GSS && skip_env "could not run under gss"
12565         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12566                 skip_env "must have acl enabled"
12567         which setfacl || skip_env "could not find setfacl"
12568         remote_mds_nodsh && skip "remote MDS with nodsh"
12569
12570         local mdts=$(comma_list $(mdts_nodes))
12571         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12572
12573         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12574         stack_trap "[[ -z \"$saved\" ]] || \
12575                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12576
12577         ACLBIN=${ACLBIN:-"bin"}
12578         ACLDMN=${ACLDMN:-"daemon"}
12579         ACLGRP=${ACLGRP:-"users"}
12580         ACLNBD=${ACLNBD:-"nobody"}
12581
12582         if ! id $ACLBIN ||
12583            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12584                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12585                 ACLBIN=$USER0
12586                 if ! id $ACLBIN ; then
12587                         cat /etc/passwd
12588                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12589                 fi
12590         fi
12591         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12592            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12593                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12594                 ACLDMN=$USER1
12595                 if ! id $ACLDMN ; then
12596                         cat /etc/passwd
12597                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12598                 fi
12599         fi
12600         if ! getent group $ACLGRP; then
12601                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12602                 ACLGRP="$TSTUSR"
12603                 if ! getent group $ACLGRP; then
12604                         echo "cannot find group '$ACLGRP', adding it"
12605                         cat /etc/group
12606                         add_group 60000 $ACLGRP
12607                 fi
12608         fi
12609
12610         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12611         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12612         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12613
12614         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12615                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12616                 ACLGRP="$TSTUSR"
12617                 if ! getent group $ACLGRP; then
12618                         echo "cannot find group '$ACLGRP', adding it"
12619                         cat /etc/group
12620                         add_group 60000 $ACLGRP
12621                 fi
12622                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12623                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12624                         cat /etc/group
12625                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12626                 fi
12627         fi
12628
12629         gpasswd -a $ACLDMN $ACLBIN ||
12630                 error "setting client group failed"             # LU-5641
12631         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12632                 error "setting MDS group failed"                # LU-5641
12633
12634         declare -a identity_old
12635
12636         for ((num = 1; num <= $MDSCOUNT; num++)); do
12637                 switch_identity $num true || identity_old[$num]=$?
12638         done
12639
12640         SAVE_UMASK=$(umask)
12641         umask 0022
12642         mkdir -p $DIR/$tdir
12643         cd $DIR/$tdir
12644
12645         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12646         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12647         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12648         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12649         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12650         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12651         if ! id -u $ACLNBD ||
12652            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12653                 ACLNBD="nfsnobody"
12654                 if ! id -u $ACLNBD; then
12655                         ACLNBD=""
12656                 fi
12657         fi
12658         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12659                 add_group $(id -u $ACLNBD) $ACLNBD
12660                 if ! getent group $ACLNBD; then
12661                         ACLNBD=""
12662                 fi
12663         fi
12664         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12665            [[ -n "$ACLNBD" ]] && which setfattr; then
12666                 run_acl_subtest permissions_xattr \
12667                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12668         elif [[ -z "$ACLNBD" ]]; then
12669                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12670         else
12671                 echo "skip 'permission_xattr' test - missing setfattr command"
12672         fi
12673         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12674
12675         # inheritance test got from HP
12676         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12677         chmod +x make-tree || error "chmod +x failed"
12678         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12679         rm -f make-tree
12680
12681         echo "LU-974 ignore umask when acl is enabled..."
12682         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12683         if [ $MDSCOUNT -ge 2 ]; then
12684                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12685         fi
12686
12687         echo "LU-2561 newly created file is same size as directory..."
12688         if [ "$mds1_FSTYPE" != "zfs" ]; then
12689                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12690         else
12691                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12692         fi
12693
12694         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12695
12696         cd $SAVE_PWD
12697         umask $SAVE_UMASK
12698
12699         for ((num = 1; num <= $MDSCOUNT; num++)); do
12700                 if [[ "${identity_old[$num]}" == 1 ]]; then
12701                         switch_identity $num false || identity_old[$num]=$?
12702                 fi
12703         done
12704 }
12705 run_test 103a "acl test"
12706
12707 test_103b() {
12708         declare -a pids
12709         local U
12710
12711         stack_trap "rm -f $DIR/$tfile.*"
12712         for U in {0..511}; do
12713                 {
12714                 local O=$(printf "%04o" $U)
12715
12716                 umask $(printf "%04o" $((511 ^ $O)))
12717                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12718                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12719
12720                 (( $S == ($O & 0666) )) ||
12721                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12722
12723                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12724                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12725                 (( $S == ($O & 0666) )) ||
12726                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12727
12728                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12729                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12730                 (( $S == ($O & 0666) )) ||
12731                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12732                 rm -f $DIR/$tfile.[smp]$0
12733                 } &
12734                 local pid=$!
12735
12736                 # limit the concurrently running threads to 64. LU-11878
12737                 local idx=$((U % 64))
12738                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12739                 pids[idx]=$pid
12740         done
12741         wait
12742 }
12743 run_test 103b "umask lfs setstripe"
12744
12745 test_103c() {
12746         mkdir -p $DIR/$tdir
12747         cp -rp $DIR/$tdir $DIR/$tdir.bak
12748
12749         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12750                 error "$DIR/$tdir shouldn't contain default ACL"
12751         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12752                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12753         true
12754 }
12755 run_test 103c "'cp -rp' won't set empty acl"
12756
12757 test_103e() {
12758         local numacl
12759         local fileacl
12760         local saved_debug=$($LCTL get_param -n debug)
12761
12762         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12763                 skip "MDS needs to be at least 2.14.52"
12764
12765         large_xattr_enabled || skip_env "ea_inode feature disabled"
12766
12767         mkdir -p $DIR/$tdir
12768         # add big LOV EA to cause reply buffer overflow earlier
12769         $LFS setstripe -C 1000 $DIR/$tdir
12770         lctl set_param mdc.*-mdc*.stats=clear
12771
12772         $LCTL set_param debug=0
12773         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12774         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12775
12776         # add a large number of default ACLs (expect 8000+ for 2.13+)
12777         for U in {2..7000}; do
12778                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12779                         error "Able to add just $U default ACLs"
12780         done
12781         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12782         echo "$numacl default ACLs created"
12783
12784         stat $DIR/$tdir || error "Cannot stat directory"
12785         # check file creation
12786         touch $DIR/$tdir/$tfile ||
12787                 error "failed to create $tfile with $numacl default ACLs"
12788         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12789         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12790         echo "$fileacl ACLs were inherited"
12791         (( $fileacl == $numacl )) ||
12792                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12793         # check that new ACLs creation adds new ACLs to inherited ACLs
12794         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12795                 error "Cannot set new ACL"
12796         numacl=$((numacl + 1))
12797         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12798         (( $fileacl == $numacl )) ||
12799                 error "failed to add new ACL: $fileacl != $numacl as expected"
12800         # adds more ACLs to a file to reach their maximum at 8000+
12801         numacl=0
12802         for U in {20000..25000}; do
12803                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12804                 numacl=$((numacl + 1))
12805         done
12806         echo "Added $numacl more ACLs to the file"
12807         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12808         echo "Total $fileacl ACLs in file"
12809         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12810         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12811         rmdir $DIR/$tdir || error "Cannot remove directory"
12812 }
12813 run_test 103e "inheritance of big amount of default ACLs"
12814
12815 test_103f() {
12816         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12817                 skip "MDS needs to be at least 2.14.51"
12818
12819         large_xattr_enabled || skip_env "ea_inode feature disabled"
12820
12821         # enable changelog to consume more internal MDD buffers
12822         changelog_register
12823
12824         mkdir -p $DIR/$tdir
12825         # add big LOV EA
12826         $LFS setstripe -C 1000 $DIR/$tdir
12827         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12828         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12829         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12830         rmdir $DIR/$tdir || error "Cannot remove directory"
12831 }
12832 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12833
12834 test_104a() {
12835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12836
12837         touch $DIR/$tfile
12838         lfs df || error "lfs df failed"
12839         lfs df -ih || error "lfs df -ih failed"
12840         lfs df -h $DIR || error "lfs df -h $DIR failed"
12841         lfs df -i $DIR || error "lfs df -i $DIR failed"
12842         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12843         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12844
12845         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12846         lctl --device %$OSC deactivate
12847         lfs df || error "lfs df with deactivated OSC failed"
12848         lctl --device %$OSC activate
12849         # wait the osc back to normal
12850         wait_osc_import_ready client ost
12851
12852         lfs df || error "lfs df with reactivated OSC failed"
12853         rm -f $DIR/$tfile
12854 }
12855 run_test 104a "lfs df [-ih] [path] test ========================="
12856
12857 test_104b() {
12858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12859         [ $RUNAS_ID -eq $UID ] &&
12860                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12861
12862         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12863                         grep "Permission denied" | wc -l)))
12864         if [ $denied_cnt -ne 0 ]; then
12865                 error "lfs check servers test failed"
12866         fi
12867 }
12868 run_test 104b "$RUNAS lfs check servers test ===================="
12869
12870 #
12871 # Verify $1 is within range of $2.
12872 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12873 # $1 is <= 2% of $2. Else Fail.
12874 #
12875 value_in_range() {
12876         # Strip all units (M, G, T)
12877         actual=$(echo $1 | tr -d A-Z)
12878         expect=$(echo $2 | tr -d A-Z)
12879
12880         expect_lo=$(($expect * 98 / 100)) # 2% below
12881         expect_hi=$(($expect * 102 / 100)) # 2% above
12882
12883         # permit 2% drift above and below
12884         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12885 }
12886
12887 test_104c() {
12888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12889         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12890
12891         local ost_param="osd-zfs.$FSNAME-OST0000."
12892         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12893         local ofacets=$(get_facets OST)
12894         local mfacets=$(get_facets MDS)
12895         local saved_ost_blocks=
12896         local saved_mdt_blocks=
12897
12898         echo "Before recordsize change"
12899         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12900         df=($(df -h | grep "$MOUNT"$))
12901
12902         # For checking.
12903         echo "lfs output : ${lfs_df[*]}"
12904         echo "df  output : ${df[*]}"
12905
12906         for facet in ${ofacets//,/ }; do
12907                 if [ -z $saved_ost_blocks ]; then
12908                         saved_ost_blocks=$(do_facet $facet \
12909                                 lctl get_param -n $ost_param.blocksize)
12910                         echo "OST Blocksize: $saved_ost_blocks"
12911                 fi
12912                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12913                 do_facet $facet zfs set recordsize=32768 $ost
12914         done
12915
12916         # BS too small. Sufficient for functional testing.
12917         for facet in ${mfacets//,/ }; do
12918                 if [ -z $saved_mdt_blocks ]; then
12919                         saved_mdt_blocks=$(do_facet $facet \
12920                                 lctl get_param -n $mdt_param.blocksize)
12921                         echo "MDT Blocksize: $saved_mdt_blocks"
12922                 fi
12923                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12924                 do_facet $facet zfs set recordsize=32768 $mdt
12925         done
12926
12927         # Give new values chance to reflect change
12928         sleep 2
12929
12930         echo "After recordsize change"
12931         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12932         df_after=($(df -h | grep "$MOUNT"$))
12933
12934         # For checking.
12935         echo "lfs output : ${lfs_df_after[*]}"
12936         echo "df  output : ${df_after[*]}"
12937
12938         # Verify lfs df
12939         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12940                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12941         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12942                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12943         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12944                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12945
12946         # Verify df
12947         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12948                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12949         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12950                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12951         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12952                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12953
12954         # Restore MDT recordize back to original
12955         for facet in ${mfacets//,/ }; do
12956                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12957                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12958         done
12959
12960         # Restore OST recordize back to original
12961         for facet in ${ofacets//,/ }; do
12962                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12963                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12964         done
12965
12966         return 0
12967 }
12968 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12969
12970 test_104d() {
12971         (( $RUNAS_ID != $UID )) ||
12972                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12973
12974         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12975                 skip "lustre version doesn't support lctl dl with non-root"
12976
12977         # debugfs only allows root users to access files, so the
12978         # previous move of the "devices" file to debugfs broke
12979         # "lctl dl" for non-root users. The LU-9680 Netlink
12980         # interface again allows non-root users to list devices.
12981         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12982                 error "lctl dl doesn't work for non root"
12983
12984         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12985         [ "$ost_count" -eq $OSTCOUNT ]  ||
12986                 error "lctl dl reports wrong number of OST devices"
12987
12988         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12989         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12990                 error "lctl dl reports wrong number of MDT devices"
12991 }
12992 run_test 104d "$RUNAS lctl dl test"
12993
12994 test_105a() {
12995         # doesn't work on 2.4 kernels
12996         touch $DIR/$tfile
12997         if $(flock_is_enabled); then
12998                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12999         else
13000                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
13001         fi
13002         rm -f $DIR/$tfile
13003 }
13004 run_test 105a "flock when mounted without -o flock test ========"
13005
13006 test_105b() {
13007         touch $DIR/$tfile
13008         if $(flock_is_enabled); then
13009                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
13010         else
13011                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
13012         fi
13013         rm -f $DIR/$tfile
13014 }
13015 run_test 105b "fcntl when mounted without -o flock test ========"
13016
13017 test_105c() {
13018         touch $DIR/$tfile
13019         if $(flock_is_enabled); then
13020                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13021         else
13022                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13023         fi
13024         rm -f $DIR/$tfile
13025 }
13026 run_test 105c "lockf when mounted without -o flock test"
13027
13028 test_105d() { # bug 15924
13029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13030
13031         test_mkdir $DIR/$tdir
13032         flock_is_enabled || skip_env "mount w/o flock enabled"
13033         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13034         $LCTL set_param fail_loc=0x80000315
13035         flocks_test 2 $DIR/$tdir
13036 }
13037 run_test 105d "flock race (should not freeze) ========"
13038
13039 test_105e() { # bug 22660 && 22040
13040         flock_is_enabled || skip_env "mount w/o flock enabled"
13041
13042         touch $DIR/$tfile
13043         flocks_test 3 $DIR/$tfile
13044 }
13045 run_test 105e "Two conflicting flocks from same process"
13046
13047 wait_end() {
13048         echo $*
13049         while :; do
13050                 [ -f $TMP/${tfile}_sTOP ] && return
13051                 sleep 1
13052         done
13053 }
13054
13055 test_105f() {
13056         flock_is_enabled || skip_env "mount w/o flock enabled"
13057
13058         local pmax=$(ulimit -u)
13059         local i=0
13060         touch $DIR/$tfile
13061         [ $pmax -gt 20 ] && pmax=20
13062         for((i=0; i <= $pmax; i++)) {
13063                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13064         }
13065         for((i=0; i <= 10; i++)) {
13066                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13067                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13068                 [ $locks -ge $pmax ] && break
13069                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13070                 sleep 1
13071         }
13072         touch $TMP/${tfile}_sTOP
13073         wait
13074         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13075 }
13076 run_test 105f "Enqueue same range flocks"
13077
13078 test_106() { #bug 10921
13079         test_mkdir $DIR/$tdir
13080         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13081         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13082 }
13083 run_test 106 "attempt exec of dir followed by chown of that dir"
13084
13085 test_107() {
13086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13087
13088         CDIR=`pwd`
13089         local file=core
13090
13091         cd $DIR
13092         rm -f $file
13093
13094         local save_pattern=$(sysctl -n kernel.core_pattern)
13095         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13096         sysctl -w kernel.core_pattern=$file
13097         sysctl -w kernel.core_uses_pid=0
13098
13099         ulimit -c unlimited
13100         sleep 60 &
13101         SLEEPPID=$!
13102
13103         sleep 1
13104
13105         kill -s 11 $SLEEPPID
13106         wait $SLEEPPID
13107         if [ -e $file ]; then
13108                 size=`stat -c%s $file`
13109                 [ $size -eq 0 ] && error "Fail to create core file $file"
13110         else
13111                 error "Fail to create core file $file"
13112         fi
13113         rm -f $file
13114         sysctl -w kernel.core_pattern=$save_pattern
13115         sysctl -w kernel.core_uses_pid=$save_uses_pid
13116         cd $CDIR
13117 }
13118 run_test 107 "Coredump on SIG"
13119
13120 test_110() {
13121         test_mkdir $DIR/$tdir
13122         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13123         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13124                 error "mkdir with 256 char should fail, but did not"
13125         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13126                 error "create with 255 char failed"
13127         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13128                 error "create with 256 char should fail, but did not"
13129
13130         ls -l $DIR/$tdir
13131         rm -rf $DIR/$tdir
13132 }
13133 run_test 110 "filename length checking"
13134
13135 test_116a() { # was previously test_116()
13136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13137         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13138         remote_mds_nodsh && skip "remote MDS with nodsh"
13139
13140         echo -n "Free space priority "
13141         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13142                 head -n1
13143         declare -a AVAIL
13144         free_min_max
13145
13146         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13147         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13148         stack_trap simple_cleanup_common
13149
13150         # Check if we need to generate uneven OSTs
13151         test_mkdir -p $DIR/$tdir/OST${MINI}
13152         local FILL=$((MINV / 4))
13153         local DIFF=$((MAXV - MINV))
13154         local DIFF2=$((DIFF * 100 / MINV))
13155
13156         local threshold=$(do_facet $SINGLEMDS \
13157                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13158         threshold=${threshold%%%}
13159         echo -n "Check for uneven OSTs: "
13160         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13161
13162         if [[ $DIFF2 -gt $threshold ]]; then
13163                 echo "ok"
13164                 echo "Don't need to fill OST$MINI"
13165         else
13166                 # generate uneven OSTs. Write 2% over the QOS threshold value
13167                 echo "no"
13168                 DIFF=$((threshold - DIFF2 + 2))
13169                 DIFF2=$((MINV * DIFF / 100))
13170                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13171                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13172                         error "setstripe failed"
13173                 DIFF=$((DIFF2 / 2048))
13174                 i=0
13175                 while [ $i -lt $DIFF ]; do
13176                         i=$((i + 1))
13177                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13178                                 bs=2M count=1 2>/dev/null
13179                         echo -n .
13180                 done
13181                 echo .
13182                 sync
13183                 sleep_maxage
13184                 free_min_max
13185         fi
13186
13187         DIFF=$((MAXV - MINV))
13188         DIFF2=$((DIFF * 100 / MINV))
13189         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13190         if [ $DIFF2 -gt $threshold ]; then
13191                 echo "ok"
13192         else
13193                 skip "QOS imbalance criteria not met"
13194         fi
13195
13196         MINI1=$MINI
13197         MINV1=$MINV
13198         MAXI1=$MAXI
13199         MAXV1=$MAXV
13200
13201         # now fill using QOS
13202         $LFS setstripe -c 1 $DIR/$tdir
13203         FILL=$((FILL / 200))
13204         if [ $FILL -gt 600 ]; then
13205                 FILL=600
13206         fi
13207         echo "writing $FILL files to QOS-assigned OSTs"
13208         i=0
13209         while [ $i -lt $FILL ]; do
13210                 i=$((i + 1))
13211                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13212                         count=1 2>/dev/null
13213                 echo -n .
13214         done
13215         echo "wrote $i 200k files"
13216         sync
13217         sleep_maxage
13218
13219         echo "Note: free space may not be updated, so measurements might be off"
13220         free_min_max
13221         DIFF2=$((MAXV - MINV))
13222         echo "free space delta: orig $DIFF final $DIFF2"
13223         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13224         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13225         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13226         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13227         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13228         if [[ $DIFF -gt 0 ]]; then
13229                 FILL=$((DIFF2 * 100 / DIFF - 100))
13230                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13231         fi
13232
13233         # Figure out which files were written where
13234         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13235                awk '/'$MINI1': / {print $2; exit}')
13236         echo $UUID
13237         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13238         echo "$MINC files created on smaller OST $MINI1"
13239         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13240                awk '/'$MAXI1': / {print $2; exit}')
13241         echo $UUID
13242         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13243         echo "$MAXC files created on larger OST $MAXI1"
13244         if [[ $MINC -gt 0 ]]; then
13245                 FILL=$((MAXC * 100 / MINC - 100))
13246                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13247         fi
13248         [[ $MAXC -gt $MINC ]] ||
13249                 error_ignore LU-9 "stripe QOS didn't balance free space"
13250 }
13251 run_test 116a "stripe QOS: free space balance ==================="
13252
13253 test_116b() { # LU-2093
13254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13255         remote_mds_nodsh && skip "remote MDS with nodsh"
13256
13257 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13258         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13259                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13260         [ -z "$old_rr" ] && skip "no QOS"
13261         do_facet $SINGLEMDS lctl set_param \
13262                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13263         mkdir -p $DIR/$tdir
13264         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13265         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13266         do_facet $SINGLEMDS lctl set_param fail_loc=0
13267         rm -rf $DIR/$tdir
13268         do_facet $SINGLEMDS lctl set_param \
13269                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13270 }
13271 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13272
13273 test_117() # bug 10891
13274 {
13275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13276
13277         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13278         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13279         lctl set_param fail_loc=0x21e
13280         > $DIR/$tfile || error "truncate failed"
13281         lctl set_param fail_loc=0
13282         echo "Truncate succeeded."
13283         rm -f $DIR/$tfile
13284 }
13285 run_test 117 "verify osd extend =========="
13286
13287 NO_SLOW_RESENDCOUNT=4
13288 export OLD_RESENDCOUNT=""
13289 set_resend_count () {
13290         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13291         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13292         lctl set_param -n $PROC_RESENDCOUNT $1
13293         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13294 }
13295
13296 # for reduce test_118* time (b=14842)
13297 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13298
13299 # Reset async IO behavior after error case
13300 reset_async() {
13301         FILE=$DIR/reset_async
13302
13303         # Ensure all OSCs are cleared
13304         $LFS setstripe -c -1 $FILE
13305         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13306         sync
13307         rm $FILE
13308 }
13309
13310 test_118a() #bug 11710
13311 {
13312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13313
13314         reset_async
13315
13316         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13317         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13318         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13319
13320         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13321                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13322                 return 1;
13323         fi
13324         rm -f $DIR/$tfile
13325 }
13326 run_test 118a "verify O_SYNC works =========="
13327
13328 test_118b()
13329 {
13330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13331         remote_ost_nodsh && skip "remote OST with nodsh"
13332
13333         reset_async
13334
13335         #define OBD_FAIL_SRV_ENOENT 0x217
13336         set_nodes_failloc "$(osts_nodes)" 0x217
13337         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13338         RC=$?
13339         set_nodes_failloc "$(osts_nodes)" 0
13340         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13341         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13342                     grep -c writeback)
13343
13344         if [[ $RC -eq 0 ]]; then
13345                 error "Must return error due to dropped pages, rc=$RC"
13346                 return 1;
13347         fi
13348
13349         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13350                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13351                 return 1;
13352         fi
13353
13354         echo "Dirty pages not leaked on ENOENT"
13355
13356         # Due to the above error the OSC will issue all RPCs syncronously
13357         # until a subsequent RPC completes successfully without error.
13358         $MULTIOP $DIR/$tfile Ow4096yc
13359         rm -f $DIR/$tfile
13360
13361         return 0
13362 }
13363 run_test 118b "Reclaim dirty pages on fatal error =========="
13364
13365 test_118c()
13366 {
13367         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13368
13369         # for 118c, restore the original resend count, LU-1940
13370         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13371                                 set_resend_count $OLD_RESENDCOUNT
13372         remote_ost_nodsh && skip "remote OST with nodsh"
13373
13374         reset_async
13375
13376         #define OBD_FAIL_OST_EROFS               0x216
13377         set_nodes_failloc "$(osts_nodes)" 0x216
13378
13379         # multiop should block due to fsync until pages are written
13380         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13381         MULTIPID=$!
13382         sleep 1
13383
13384         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13385                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13386         fi
13387
13388         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13389                     grep -c writeback)
13390         if [[ $WRITEBACK -eq 0 ]]; then
13391                 error "No page in writeback, writeback=$WRITEBACK"
13392         fi
13393
13394         set_nodes_failloc "$(osts_nodes)" 0
13395         wait $MULTIPID
13396         RC=$?
13397         if [[ $RC -ne 0 ]]; then
13398                 error "Multiop fsync failed, rc=$RC"
13399         fi
13400
13401         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13402         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13403                     grep -c writeback)
13404         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13405                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13406         fi
13407
13408         rm -f $DIR/$tfile
13409         echo "Dirty pages flushed via fsync on EROFS"
13410         return 0
13411 }
13412 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13413
13414 # continue to use small resend count to reduce test_118* time (b=14842)
13415 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13416
13417 test_118d()
13418 {
13419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13420         remote_ost_nodsh && skip "remote OST with nodsh"
13421
13422         reset_async
13423
13424         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13425         set_nodes_failloc "$(osts_nodes)" 0x214
13426         # multiop should block due to fsync until pages are written
13427         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13428         MULTIPID=$!
13429         sleep 1
13430
13431         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13432                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13433         fi
13434
13435         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13436                     grep -c writeback)
13437         if [[ $WRITEBACK -eq 0 ]]; then
13438                 error "No page in writeback, writeback=$WRITEBACK"
13439         fi
13440
13441         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13442         set_nodes_failloc "$(osts_nodes)" 0
13443
13444         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13445         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13446                     grep -c writeback)
13447         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13448                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13449         fi
13450
13451         rm -f $DIR/$tfile
13452         echo "Dirty pages gaurenteed flushed via fsync"
13453         return 0
13454 }
13455 run_test 118d "Fsync validation inject a delay of the bulk =========="
13456
13457 test_118f() {
13458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13459
13460         reset_async
13461
13462         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13463         lctl set_param fail_loc=0x8000040a
13464
13465         # Should simulate EINVAL error which is fatal
13466         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13467         RC=$?
13468         if [[ $RC -eq 0 ]]; then
13469                 error "Must return error due to dropped pages, rc=$RC"
13470         fi
13471
13472         lctl set_param fail_loc=0x0
13473
13474         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13475         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13476         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13477                     grep -c writeback)
13478         if [[ $LOCKED -ne 0 ]]; then
13479                 error "Locked pages remain in cache, locked=$LOCKED"
13480         fi
13481
13482         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13483                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13484         fi
13485
13486         rm -f $DIR/$tfile
13487         echo "No pages locked after fsync"
13488
13489         reset_async
13490         return 0
13491 }
13492 run_test 118f "Simulate unrecoverable OSC side error =========="
13493
13494 test_118g() {
13495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13496
13497         reset_async
13498
13499         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13500         lctl set_param fail_loc=0x406
13501
13502         # simulate local -ENOMEM
13503         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13504         RC=$?
13505
13506         lctl set_param fail_loc=0
13507         if [[ $RC -eq 0 ]]; then
13508                 error "Must return error due to dropped pages, rc=$RC"
13509         fi
13510
13511         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13512         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13513         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13514                         grep -c writeback)
13515         if [[ $LOCKED -ne 0 ]]; then
13516                 error "Locked pages remain in cache, locked=$LOCKED"
13517         fi
13518
13519         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13520                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13521         fi
13522
13523         rm -f $DIR/$tfile
13524         echo "No pages locked after fsync"
13525
13526         reset_async
13527         return 0
13528 }
13529 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13530
13531 test_118h() {
13532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13533         remote_ost_nodsh && skip "remote OST with nodsh"
13534
13535         reset_async
13536
13537         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13538         set_nodes_failloc "$(osts_nodes)" 0x20e
13539         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13540         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13541         RC=$?
13542
13543         set_nodes_failloc "$(osts_nodes)" 0
13544         if [[ $RC -eq 0 ]]; then
13545                 error "Must return error due to dropped pages, rc=$RC"
13546         fi
13547
13548         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13549         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13550         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13551                     grep -c writeback)
13552         if [[ $LOCKED -ne 0 ]]; then
13553                 error "Locked pages remain in cache, locked=$LOCKED"
13554         fi
13555
13556         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13557                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13558         fi
13559
13560         rm -f $DIR/$tfile
13561         echo "No pages locked after fsync"
13562
13563         return 0
13564 }
13565 run_test 118h "Verify timeout in handling recoverables errors  =========="
13566
13567 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13568
13569 test_118i() {
13570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13571         remote_ost_nodsh && skip "remote OST with nodsh"
13572
13573         reset_async
13574
13575         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13576         set_nodes_failloc "$(osts_nodes)" 0x20e
13577
13578         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13579         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13580         PID=$!
13581         sleep 5
13582         set_nodes_failloc "$(osts_nodes)" 0
13583
13584         wait $PID
13585         RC=$?
13586         if [[ $RC -ne 0 ]]; then
13587                 error "got error, but should be not, rc=$RC"
13588         fi
13589
13590         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13591         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13592         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13593         if [[ $LOCKED -ne 0 ]]; then
13594                 error "Locked pages remain in cache, locked=$LOCKED"
13595         fi
13596
13597         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13598                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13599         fi
13600
13601         rm -f $DIR/$tfile
13602         echo "No pages locked after fsync"
13603
13604         return 0
13605 }
13606 run_test 118i "Fix error before timeout in recoverable error  =========="
13607
13608 [ "$SLOW" = "no" ] && set_resend_count 4
13609
13610 test_118j() {
13611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13612         remote_ost_nodsh && skip "remote OST with nodsh"
13613
13614         reset_async
13615
13616         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13617         set_nodes_failloc "$(osts_nodes)" 0x220
13618
13619         # return -EIO from OST
13620         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13621         RC=$?
13622         set_nodes_failloc "$(osts_nodes)" 0x0
13623         if [[ $RC -eq 0 ]]; then
13624                 error "Must return error due to dropped pages, rc=$RC"
13625         fi
13626
13627         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13628         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13629         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13630         if [[ $LOCKED -ne 0 ]]; then
13631                 error "Locked pages remain in cache, locked=$LOCKED"
13632         fi
13633
13634         # in recoverable error on OST we want resend and stay until it finished
13635         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13636                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13637         fi
13638
13639         rm -f $DIR/$tfile
13640         echo "No pages locked after fsync"
13641
13642         return 0
13643 }
13644 run_test 118j "Simulate unrecoverable OST side error =========="
13645
13646 test_118k()
13647 {
13648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13649         remote_ost_nodsh && skip "remote OSTs with nodsh"
13650
13651         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13652         set_nodes_failloc "$(osts_nodes)" 0x20e
13653         test_mkdir $DIR/$tdir
13654
13655         for ((i=0;i<10;i++)); do
13656                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13657                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13658                 SLEEPPID=$!
13659                 sleep 0.500s
13660                 kill $SLEEPPID
13661                 wait $SLEEPPID
13662         done
13663
13664         set_nodes_failloc "$(osts_nodes)" 0
13665         rm -rf $DIR/$tdir
13666 }
13667 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13668
13669 test_118l() # LU-646
13670 {
13671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13672
13673         test_mkdir $DIR/$tdir
13674         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13675         rm -rf $DIR/$tdir
13676 }
13677 run_test 118l "fsync dir"
13678
13679 test_118m() # LU-3066
13680 {
13681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13682
13683         test_mkdir $DIR/$tdir
13684         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13685         rm -rf $DIR/$tdir
13686 }
13687 run_test 118m "fdatasync dir ========="
13688
13689 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13690
13691 test_118n()
13692 {
13693         local begin
13694         local end
13695
13696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13697         remote_ost_nodsh && skip "remote OSTs with nodsh"
13698
13699         # Sleep to avoid a cached response.
13700         #define OBD_STATFS_CACHE_SECONDS 1
13701         sleep 2
13702
13703         # Inject a 10 second delay in the OST_STATFS handler.
13704         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13705         set_nodes_failloc "$(osts_nodes)" 0x242
13706
13707         begin=$SECONDS
13708         stat --file-system $MOUNT > /dev/null
13709         end=$SECONDS
13710
13711         set_nodes_failloc "$(osts_nodes)" 0
13712
13713         if ((end - begin > 20)); then
13714             error "statfs took $((end - begin)) seconds, expected 10"
13715         fi
13716 }
13717 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13718
13719 test_119a() # bug 11737
13720 {
13721         BSIZE=$((512 * 1024))
13722         directio write $DIR/$tfile 0 1 $BSIZE
13723         # We ask to read two blocks, which is more than a file size.
13724         # directio will indicate an error when requested and actual
13725         # sizes aren't equeal (a normal situation in this case) and
13726         # print actual read amount.
13727         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13728         if [ "$NOB" != "$BSIZE" ]; then
13729                 error "read $NOB bytes instead of $BSIZE"
13730         fi
13731         rm -f $DIR/$tfile
13732 }
13733 run_test 119a "Short directIO read must return actual read amount"
13734
13735 test_119b() # bug 11737
13736 {
13737         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13738
13739         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13740         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13741         sync
13742         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13743                 error "direct read failed"
13744         rm -f $DIR/$tfile
13745 }
13746 run_test 119b "Sparse directIO read must return actual read amount"
13747
13748 test_119c() # bug 13099
13749 {
13750         BSIZE=1048576
13751         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13752         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13753         rm -f $DIR/$tfile
13754 }
13755 run_test 119c "Testing for direct read hitting hole"
13756
13757 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13758 # Maloo test history
13759
13760 test_119e()
13761 {
13762         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13763                 skip "Need server version at least 2.15.58"
13764         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13765
13766         local stripe_size=$((1024 * 1024)) #1 MiB
13767         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13768         local file_size=$((25 * stripe_size))
13769         local bsizes
13770
13771         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13772         stack_trap "rm -f $DIR/$tfile*"
13773
13774         # Just a bit bigger than the largest size in the test set below
13775         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13776                 error "buffered i/o to create file failed"
13777
13778         # trivial test of unaligned DIO
13779         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13780                 iflag=direct oflag=direct ||
13781                 error "trivial unaligned dio failed"
13782
13783         # Test of disabling unaligned DIO support
13784         $LCTL set_param llite.*.unaligned_dio=0
13785         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13786         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13787         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13788                 iflag=direct oflag=direct &&
13789                 error "unaligned dio succeeded when disabled"
13790         $LCTL set_param llite.*.unaligned_dio=1
13791
13792         # Clean up before next part of test
13793         rm -f $DIR/$tfile.2
13794
13795         if zfs_or_rotational; then
13796                 # DIO on ZFS can take up to 2 seconds per IO
13797                 # rotational is better, but still slow.
13798                 # Limit testing on those media to larger sizes
13799                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13800                         $((stripe_size + 1024))"
13801         else
13802                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13803                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13804                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13805                         $((stripe_size - 1)) $stripe_size \
13806                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13807                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13808         fi
13809
13810         for bs in $bsizes; do
13811                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13812                 echo "Read/write with DIO at size $bs"
13813                 # Read and write with DIO from source to dest
13814                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13815                         iflag=direct oflag=direct ||
13816                         error "dio failed"
13817
13818                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13819                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13820                         error "size incorrect, file copy read/write bsize: $bs"
13821                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13822                         error "files differ, bsize $bs"
13823                 rm -f $DIR/$tfile.2
13824         done
13825 }
13826 run_test 119e "Basic tests of dio read and write at various sizes"
13827
13828 test_119f()
13829 {
13830         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13831
13832         local stripe_size=$((1024 * 1024)) #1 MiB
13833         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13834         local file_size=$((25 * stripe_size))
13835         local bsizes
13836
13837         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13838         stack_trap "rm -f $DIR/$tfile*"
13839
13840         # Just a bit bigger than the largest size in the test set below
13841         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13842                 error "buffered i/o to create file failed"
13843
13844         if zfs_or_rotational; then
13845                 # DIO on ZFS can take up to 2 seconds per IO
13846                 # rotational is better, but still slow.
13847                 # Limit testing on those media to larger sizes
13848                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13849                         $((stripe_size + 1024))"
13850         else
13851                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13852                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13853                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13854                         $((stripe_size - 1)) $stripe_size \
13855                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13856                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13857         fi
13858
13859         for bs in $bsizes; do
13860                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13861                 # Read and write with DIO from source to dest in two
13862                 # threads - should give correct copy of file
13863
13864                 echo "bs: $bs"
13865                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13866                         oflag=direct conv=notrunc &
13867                 pid_dio1=$!
13868                 # Note block size is different here for a more interesting race
13869                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13870                         iflag=direct oflag=direct conv=notrunc &
13871                 pid_dio2=$!
13872                 wait $pid_dio1
13873                 rc1=$?
13874                 wait $pid_dio2
13875                 rc2=$?
13876                 if (( rc1 != 0 )); then
13877                         error "dio copy 1 w/bsize $bs failed: $rc1"
13878                 fi
13879                 if (( rc2 != 0 )); then
13880                         error "dio copy 2 w/bsize $bs failed: $rc2"
13881                 fi
13882
13883
13884                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13885                         error "size incorrect, file copy read/write bsize: $bs"
13886                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13887                         error "files differ, bsize $bs"
13888                 rm -f $DIR/$tfile.2
13889         done
13890 }
13891 run_test 119f "dio vs dio race"
13892
13893 test_119g()
13894 {
13895         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13896
13897         local stripe_size=$((1024 * 1024)) #1 MiB
13898         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13899         local file_size=$((25 * stripe_size))
13900         local bsizes
13901
13902         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13903         stack_trap "rm -f $DIR/$tfile*"
13904
13905         # Just a bit bigger than the largest size in the test set below
13906         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13907                 error "buffered i/o to create file failed"
13908
13909         if zfs_or_rotational; then
13910                 # DIO on ZFS can take up to 2 seconds per IO
13911                 # rotational is better, but still slow.
13912                 # Limit testing on those media to larger sizes
13913                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13914                         $((stripe_size + 1024))"
13915         else
13916                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13917                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13918                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13919                         $((stripe_size - 1)) $stripe_size \
13920                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13921                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13922         fi
13923
13924         for bs in $bsizes; do
13925                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13926                 echo "bs: $bs"
13927                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13928                         oflag=direct conv=notrunc &
13929                 pid_dio1=$!
13930                 # Buffered I/O with similar but not the same block size
13931                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13932                 pid_bio2=$!
13933                 wait $pid_dio1
13934                 rc1=$?
13935                 wait $pid_bio2
13936                 rc2=$?
13937                 if (( rc1 != 0 )); then
13938                         error "dio copy 1 w/bsize $bs failed: $rc1"
13939                 fi
13940                 if (( rc2 != 0 )); then
13941                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13942                 fi
13943
13944                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13945                         error "size incorrect"
13946                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13947                         error "files differ, bsize $bs"
13948                 rm -f $DIR/$tfile.2
13949         done
13950 }
13951 run_test 119g "dio vs buffered I/O race"
13952
13953 test_119h()
13954 {
13955         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13956
13957         local stripe_size=$((1024 * 1024)) #1 MiB
13958         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13959         local file_size=$((25 * stripe_size))
13960         local bsizes
13961
13962         stack_trap "rm -f $DIR/$tfile.*"
13963
13964         if zfs_or_rotational; then
13965                 # DIO on ZFS can take up to 2 seconds per IO
13966                 # rotational is better, but still slow.
13967                 # Limit testing on those media to larger sizes
13968                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13969                         $((stripe_size + 1024))"
13970         else
13971                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13972                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13973                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13974                         $((stripe_size - 1)) $stripe_size \
13975                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13976                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13977         fi
13978
13979         for bs in $bsizes; do
13980                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13981                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13982                 echo "unaligned writes of blocksize: $bs"
13983                 # Write a file with unaligned DIO and regular DIO, and compare
13984                 # them
13985                 # with 'u', multiop randomly unaligns the io from the buffer
13986                 $MULTIOP $DIR/$tfile.1 \
13987                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13988                         error "multiop memory unaligned write failed, $bs"
13989                 $MULTIOP $DIR/$tfile.2 \
13990                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13991                         error "multiop memory aligned write failed, $bs"
13992
13993                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13994                         error "files differ, bsize $bs"
13995                 rm -f $DIR/$tfile.*
13996         done
13997
13998         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13999         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
14000                 error "dd to create source file for read failed"
14001
14002         # Just a few quick tests to make sure unaligned DIO reads don't crash
14003         for bs in $bsizes; do
14004
14005                 echo "unaligned reads of blocksize: $bs"
14006                 # with 'u', multiop randomly unaligns the io from the buffer
14007                 $MULTIOP $DIR/$tfile.1 \
14008                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
14009                         error "multiop memory unaligned read failed, $bs"
14010
14011         done
14012         rm -f $DIR/$tfile*
14013 }
14014 run_test 119h "basic tests of memory unaligned dio"
14015
14016 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14017 test_119i()
14018 {
14019         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14020         which aiocp || skip_env "no aiocp installed"
14021
14022         local stripe_size=$((1024 * 1024)) #1 MiB
14023         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14024         local file_size=$((25 * stripe_size))
14025         local bsizes
14026
14027         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14028         stack_trap "rm -f $DIR/$tfile.*"
14029
14030         # Just a bit bigger than the largest size in the test set below
14031         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14032                 error "buffered i/o to create file failed"
14033
14034         if zfs_or_rotational; then
14035                 # DIO on ZFS can take up to 2 seconds per IO
14036                 # rotational is better, but still slow.
14037                 # Limit testing on those media to larger sizes
14038                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14039                         $((stripe_size + 1024))"
14040         else
14041                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14042                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14043                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14044                         $((stripe_size - 1)) $stripe_size \
14045                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14046                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14047         fi
14048
14049         # Do page aligned and NOT page aligned AIO
14050         for align in 8 512 $((PAGE_SIZE)); do
14051         # Deliberately includes a few aligned sizes
14052         for bs in $bsizes; do
14053                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14054
14055                 echo "bs: $bs, align: $align, file_size $file_size"
14056                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14057                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14058                         error "unaligned aio failed, bs: $bs, align: $align"
14059
14060                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14061                         error "size incorrect"
14062                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14063                         error "files differ"
14064                 rm -f $DIR/$tfile.2
14065         done
14066         done
14067 }
14068 run_test 119i "test unaligned aio at varying sizes"
14069
14070 test_120a() {
14071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14072         remote_mds_nodsh && skip "remote MDS with nodsh"
14073         test_mkdir -i0 -c1 $DIR/$tdir
14074         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14075                 skip_env "no early lock cancel on server"
14076
14077         lru_resize_disable mdc
14078         lru_resize_disable osc
14079         cancel_lru_locks mdc
14080         # asynchronous object destroy at MDT could cause bl ast to client
14081         cancel_lru_locks osc
14082
14083         stat $DIR/$tdir > /dev/null
14084         can1=$(do_facet mds1 \
14085                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14086                awk '/ldlm_cancel/ {print $2}')
14087         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14088                awk '/ldlm_bl_callback/ {print $2}')
14089         test_mkdir -i0 -c1 $DIR/$tdir/d1
14090         can2=$(do_facet mds1 \
14091                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14092                awk '/ldlm_cancel/ {print $2}')
14093         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14094                awk '/ldlm_bl_callback/ {print $2}')
14095         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14096         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14097         lru_resize_enable mdc
14098         lru_resize_enable osc
14099 }
14100 run_test 120a "Early Lock Cancel: mkdir test"
14101
14102 test_120b() {
14103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14104         remote_mds_nodsh && skip "remote MDS with nodsh"
14105         test_mkdir $DIR/$tdir
14106         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14107                 skip_env "no early lock cancel on server"
14108
14109         lru_resize_disable mdc
14110         lru_resize_disable osc
14111         cancel_lru_locks mdc
14112         stat $DIR/$tdir > /dev/null
14113         can1=$(do_facet $SINGLEMDS \
14114                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14115                awk '/ldlm_cancel/ {print $2}')
14116         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14117                awk '/ldlm_bl_callback/ {print $2}')
14118         touch $DIR/$tdir/f1
14119         can2=$(do_facet $SINGLEMDS \
14120                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14121                awk '/ldlm_cancel/ {print $2}')
14122         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14123                awk '/ldlm_bl_callback/ {print $2}')
14124         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14125         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14126         lru_resize_enable mdc
14127         lru_resize_enable osc
14128 }
14129 run_test 120b "Early Lock Cancel: create test"
14130
14131 test_120c() {
14132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14133         remote_mds_nodsh && skip "remote MDS with nodsh"
14134         test_mkdir -i0 -c1 $DIR/$tdir
14135         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14136                 skip "no early lock cancel on server"
14137
14138         lru_resize_disable mdc
14139         lru_resize_disable osc
14140         test_mkdir -i0 -c1 $DIR/$tdir/d1
14141         test_mkdir -i0 -c1 $DIR/$tdir/d2
14142         touch $DIR/$tdir/d1/f1
14143         cancel_lru_locks mdc
14144         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14145         can1=$(do_facet mds1 \
14146                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14147                awk '/ldlm_cancel/ {print $2}')
14148         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14149                awk '/ldlm_bl_callback/ {print $2}')
14150         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14151         can2=$(do_facet mds1 \
14152                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14153                awk '/ldlm_cancel/ {print $2}')
14154         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14155                awk '/ldlm_bl_callback/ {print $2}')
14156         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14157         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14158         lru_resize_enable mdc
14159         lru_resize_enable osc
14160 }
14161 run_test 120c "Early Lock Cancel: link test"
14162
14163 test_120d() {
14164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14165         remote_mds_nodsh && skip "remote MDS with nodsh"
14166         test_mkdir -i0 -c1 $DIR/$tdir
14167         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14168                 skip_env "no early lock cancel on server"
14169
14170         lru_resize_disable mdc
14171         lru_resize_disable osc
14172         touch $DIR/$tdir
14173         cancel_lru_locks mdc
14174         stat $DIR/$tdir > /dev/null
14175         can1=$(do_facet mds1 \
14176                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14177                awk '/ldlm_cancel/ {print $2}')
14178         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14179                awk '/ldlm_bl_callback/ {print $2}')
14180         chmod a+x $DIR/$tdir
14181         can2=$(do_facet mds1 \
14182                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14183                awk '/ldlm_cancel/ {print $2}')
14184         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14185                awk '/ldlm_bl_callback/ {print $2}')
14186         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14187         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14188         lru_resize_enable mdc
14189         lru_resize_enable osc
14190 }
14191 run_test 120d "Early Lock Cancel: setattr test"
14192
14193 test_120e() {
14194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14195         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14196                 skip_env "no early lock cancel on server"
14197         remote_mds_nodsh && skip "remote MDS with nodsh"
14198
14199         local dlmtrace_set=false
14200
14201         test_mkdir -i0 -c1 $DIR/$tdir
14202         lru_resize_disable mdc
14203         lru_resize_disable osc
14204         ! $LCTL get_param debug | grep -q dlmtrace &&
14205                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14206         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14207         cancel_lru_locks mdc
14208         cancel_lru_locks osc
14209         dd if=$DIR/$tdir/f1 of=/dev/null
14210         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14211         # XXX client can not do early lock cancel of OST lock
14212         # during unlink (LU-4206), so cancel osc lock now.
14213         sleep 2
14214         cancel_lru_locks osc
14215         can1=$(do_facet mds1 \
14216                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14217                awk '/ldlm_cancel/ {print $2}')
14218         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14219                awk '/ldlm_bl_callback/ {print $2}')
14220         unlink $DIR/$tdir/f1
14221         sleep 5
14222         can2=$(do_facet mds1 \
14223                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14224                awk '/ldlm_cancel/ {print $2}')
14225         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14226                awk '/ldlm_bl_callback/ {print $2}')
14227         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14228                 $LCTL dk $TMP/cancel.debug.txt
14229         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14230                 $LCTL dk $TMP/blocking.debug.txt
14231         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14232         lru_resize_enable mdc
14233         lru_resize_enable osc
14234 }
14235 run_test 120e "Early Lock Cancel: unlink test"
14236
14237 test_120f() {
14238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14239         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14240                 skip_env "no early lock cancel on server"
14241         remote_mds_nodsh && skip "remote MDS with nodsh"
14242
14243         test_mkdir -i0 -c1 $DIR/$tdir
14244         lru_resize_disable mdc
14245         lru_resize_disable osc
14246         test_mkdir -i0 -c1 $DIR/$tdir/d1
14247         test_mkdir -i0 -c1 $DIR/$tdir/d2
14248         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14249         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14250         cancel_lru_locks mdc
14251         cancel_lru_locks osc
14252         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14253         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14254         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14255         # XXX client can not do early lock cancel of OST lock
14256         # during rename (LU-4206), so cancel osc lock now.
14257         sleep 2
14258         cancel_lru_locks osc
14259         can1=$(do_facet mds1 \
14260                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14261                awk '/ldlm_cancel/ {print $2}')
14262         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14263                awk '/ldlm_bl_callback/ {print $2}')
14264         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14265         sleep 5
14266         can2=$(do_facet mds1 \
14267                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14268                awk '/ldlm_cancel/ {print $2}')
14269         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14270                awk '/ldlm_bl_callback/ {print $2}')
14271         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14272         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14273         lru_resize_enable mdc
14274         lru_resize_enable osc
14275 }
14276 run_test 120f "Early Lock Cancel: rename test"
14277
14278 test_120g() {
14279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14280         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14281                 skip_env "no early lock cancel on server"
14282         remote_mds_nodsh && skip "remote MDS with nodsh"
14283
14284         lru_resize_disable mdc
14285         lru_resize_disable osc
14286         count=10000
14287         echo create $count files
14288         test_mkdir $DIR/$tdir
14289         cancel_lru_locks mdc
14290         cancel_lru_locks osc
14291         t0=$(date +%s)
14292
14293         can0=$(do_facet $SINGLEMDS \
14294                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14295                awk '/ldlm_cancel/ {print $2}')
14296         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14297                awk '/ldlm_bl_callback/ {print $2}')
14298         createmany -o $DIR/$tdir/f $count
14299         sync
14300         can1=$(do_facet $SINGLEMDS \
14301                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14302                awk '/ldlm_cancel/ {print $2}')
14303         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14304                awk '/ldlm_bl_callback/ {print $2}')
14305         t1=$(date +%s)
14306         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14307         echo rm $count files
14308         rm -r $DIR/$tdir
14309         sync
14310         can2=$(do_facet $SINGLEMDS \
14311                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14312                awk '/ldlm_cancel/ {print $2}')
14313         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14314                awk '/ldlm_bl_callback/ {print $2}')
14315         t2=$(date +%s)
14316         echo total: $count removes in $((t2-t1))
14317         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14318         sleep 2
14319         # wait for commitment of removal
14320         lru_resize_enable mdc
14321         lru_resize_enable osc
14322 }
14323 run_test 120g "Early Lock Cancel: performance test"
14324
14325 test_121() { #bug #10589
14326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14327
14328         rm -rf $DIR/$tfile
14329         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14330 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14331         lctl set_param fail_loc=0x310
14332         cancel_lru_locks osc > /dev/null
14333         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14334         lctl set_param fail_loc=0
14335         [[ $reads -eq $writes ]] ||
14336                 error "read $reads blocks, must be $writes blocks"
14337 }
14338 run_test 121 "read cancel race ========="
14339
14340 test_123a_base() { # was test 123, statahead(bug 11401)
14341         local lsx="$1"
14342
14343         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14344
14345         SLOWOK=0
14346         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14347                 log "testing UP system. Performance may be lower than expected."
14348                 SLOWOK=1
14349         fi
14350         running_in_vm && SLOWOK=1
14351
14352         $LCTL set_param mdc.*.batch_stats=0
14353
14354         rm -rf $DIR/$tdir
14355         test_mkdir $DIR/$tdir
14356         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14357         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14358         MULT=10
14359         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14360                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14361
14362                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14363                 lctl set_param -n llite.*.statahead_max 0
14364                 lctl get_param llite.*.statahead_max
14365                 cancel_lru_locks mdc
14366                 cancel_lru_locks osc
14367                 stime=$(date +%s)
14368                 time $lsx $DIR/$tdir | wc -l
14369                 etime=$(date +%s)
14370                 delta=$((etime - stime))
14371                 log "$lsx $i files without statahead: $delta sec"
14372                 lctl set_param llite.*.statahead_max=$max
14373
14374                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14375                          awk '/statahead.wrong:/ { print $NF }')
14376                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14377                 cancel_lru_locks mdc
14378                 cancel_lru_locks osc
14379                 stime=$(date +%s)
14380                 time $lsx $DIR/$tdir | wc -l
14381                 etime=$(date +%s)
14382                 delta_sa=$((etime - stime))
14383                 log "$lsx $i files with statahead: $delta_sa sec"
14384                 lctl get_param -n llite.*.statahead_stats
14385                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14386                          awk '/statahead.wrong:/ { print $NF }')
14387
14388                 [[ $swrong -lt $ewrong ]] &&
14389                         log "statahead was stopped, maybe too many locks held!"
14390                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14391
14392                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14393                         max=$(lctl get_param -n llite.*.statahead_max |
14394                                 head -n 1)
14395                         lctl set_param -n llite.*.statahead_max 0
14396                         lctl get_param llite.*.statahead_max
14397                         cancel_lru_locks mdc
14398                         cancel_lru_locks osc
14399                         stime=$(date +%s)
14400                         time $lsx $DIR/$tdir | wc -l
14401                         etime=$(date +%s)
14402                         delta=$((etime - stime))
14403                         log "$lsx $i files again without statahead: $delta sec"
14404                         lctl set_param llite.*.statahead_max=$max
14405                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14406                                 if [ $SLOWOK -eq 0 ]; then
14407                                         error "$lsx $i files is slower with statahead!"
14408                                 else
14409                                         log "$lsx $i files is slower with statahead!"
14410                                 fi
14411                                 break
14412                         fi
14413                 fi
14414
14415                 [ $delta -gt 20 ] && break
14416                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14417                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14418         done
14419         log "$lsx done"
14420
14421         stime=$(date +%s)
14422         rm -r $DIR/$tdir
14423         sync
14424         etime=$(date +%s)
14425         delta=$((etime - stime))
14426         log "rm -r $DIR/$tdir/: $delta seconds"
14427         log "rm done"
14428         lctl get_param -n llite.*.statahead_stats
14429         $LCTL get_param mdc.*.batch_stats
14430 }
14431
14432 test_123aa() {
14433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14434
14435         test_123a_base "ls -l"
14436 }
14437 run_test 123aa "verify statahead work"
14438
14439 test_123ab() {
14440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14441
14442         statx_supported || skip_env "Test must be statx() syscall supported"
14443
14444         test_123a_base "$STATX -l"
14445 }
14446 run_test 123ab "verify statahead work by using statx"
14447
14448 test_123ac() {
14449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14450
14451         statx_supported || skip_env "Test must be statx() syscall supported"
14452
14453         local rpcs_before
14454         local rpcs_after
14455         local agl_before
14456         local agl_after
14457
14458         cancel_lru_locks $OSC
14459         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14460         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14461                      awk '/agl.total:/ { print $NF }')
14462         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14463         test_123a_base "$STATX --cached=always -D"
14464         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14465                     awk '/agl.total:/ { print $NF }')
14466         [ $agl_before -eq $agl_after ] ||
14467                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14468         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14469         [ $rpcs_after -eq $rpcs_before ] ||
14470                 error "$STATX should not send glimpse RPCs to $OSC"
14471 }
14472 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14473
14474 test_batch_statahead() {
14475         local max=$1
14476         local batch_max=$2
14477         local num=10000
14478         local batch_rpcs
14479         local unbatch_rpcs
14480         local hit_total
14481
14482         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14483         $LCTL set_param mdc.*.batch_stats=0
14484         $LCTL set_param llite.*.statahead_max=$max
14485         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14486         # Verify that batched statahead is faster than one without statahead
14487         test_123a_base "ls -l"
14488
14489         stack_trap "rm -rf $DIR/$tdir" EXIT
14490         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14491         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14492
14493         # unbatched statahead
14494         $LCTL set_param llite.*.statahead_batch_max=0
14495         $LCTL set_param llite.*.statahead_stats=clear
14496         $LCTL set_param mdc.*.stats=clear
14497         cancel_lru_locks mdc
14498         cancel_lru_locks osc
14499         time ls -l $DIR/$tdir | wc -l
14500         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14501         wait_update_facet client "pgrep ll_sa" "" 35 ||
14502                 error "ll_sa thread is still running"
14503         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14504                     awk '/hit.total:/ { print $NF }')
14505         # hit ratio should be larger than 75% (7500).
14506         (( $hit_total > 7500 )) ||
14507                 error "unbatched statahead hit count ($hit_total) is too low"
14508
14509         # batched statahead
14510         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14511         $LCTL set_param llite.*.statahead_stats=clear
14512         $LCTL set_param mdc.*.batch_stats=clear
14513         $LCTL set_param mdc.*.stats=clear
14514         cancel_lru_locks mdc
14515         cancel_lru_locks osc
14516         time ls -l $DIR/$tdir | wc -l
14517         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14518         # wait for statahead thread to quit and update statahead stats
14519         wait_update_facet client "pgrep ll_sa" "" 35 ||
14520                 error "ll_sa thread is still running"
14521         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14522                     awk '/hit.total:/ { print $NF }')
14523         # hit ratio should be larger than 75% (7500).
14524         (( $hit_total > 7500 )) ||
14525                 error "batched statahead hit count ($hit_total) is too low"
14526
14527         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14528         (( $unbatch_rpcs > $batch_rpcs )) ||
14529                 error "batched statahead does not reduce RPC count"
14530         $LCTL get_param mdc.*.batch_stats
14531 }
14532
14533 test_123ad() {
14534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14535
14536         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14537                 skip "Need server version at least 2.15.53"
14538
14539         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14540                 skip "Server does not support batch RPC"
14541
14542         local max
14543         local batch_max
14544
14545         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14546         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14547
14548         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14549         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14550
14551         test_batch_statahead 32 32
14552         test_batch_statahead 2048 256
14553 }
14554 run_test 123ad "Verify batching statahead works correctly"
14555
14556 test_123b () { # statahead(bug 15027)
14557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14558
14559         test_mkdir $DIR/$tdir
14560         createmany -o $DIR/$tdir/$tfile-%d 1000
14561
14562         cancel_lru_locks mdc
14563         cancel_lru_locks osc
14564
14565 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14566         lctl set_param fail_loc=0x80000803
14567         ls -lR $DIR/$tdir > /dev/null
14568         log "ls done"
14569         lctl set_param fail_loc=0x0
14570         lctl get_param -n llite.*.statahead_stats
14571         rm -r $DIR/$tdir
14572         sync
14573
14574 }
14575 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14576
14577 test_123c() {
14578         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14579
14580         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14581         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14582         touch $DIR/$tdir.1/{1..3}
14583         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14584
14585         remount_client $MOUNT
14586
14587         $MULTIOP $DIR/$tdir.0 Q
14588
14589         # let statahead to complete
14590         ls -l $DIR/$tdir.0 > /dev/null
14591
14592         testid=$(echo $TESTNAME | tr '_' ' ')
14593         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14594                 error "statahead warning" || true
14595 }
14596 run_test 123c "Can not initialize inode warning on DNE statahead"
14597
14598 test_123d() {
14599         local num=100
14600         local swrong
14601         local ewrong
14602
14603         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14604         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14605                 error "setdirstripe $DIR/$tdir failed"
14606         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14607         remount_client $MOUNT
14608         $LCTL get_param llite.*.statahead_max
14609         $LCTL set_param llite.*.statahead_stats=0 ||
14610                 error "clear statahead_stats failed"
14611         swrong=$(lctl get_param -n llite.*.statahead_stats |
14612                  awk '/statahead.wrong:/ { print $NF }')
14613         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14614         # wait for statahead thread finished to update hit/miss stats.
14615         sleep 1
14616         $LCTL get_param -n llite.*.statahead_stats
14617         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14618                  awk '/statahead.wrong:/ { print $NF }')
14619         (( $swrong == $ewrong )) ||
14620                 log "statahead was stopped, maybe too many locks held!"
14621 }
14622 run_test 123d "Statahead on striped directories works correctly"
14623
14624 test_123e() {
14625         local max
14626         local batch_max
14627         local dir=$DIR/$tdir
14628
14629         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14630                 skip "Server does not support batch RPC"
14631
14632         mkdir $dir || error "mkdir $dir failed"
14633         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14634         stack_trap "rm -rf $dir"
14635
14636         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14637
14638         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14639         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14640         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14641         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14642
14643         $LCTL set_param llite.*.statahead_max=2048
14644         $LCTL set_param llite.*.statahead_batch_max=1024
14645
14646         ls -l $dir
14647         $LCTL get_param mdc.*.batch_stats
14648         $LCTL get_param llite.*.statahead_*
14649 }
14650 run_test 123e "statahead with large wide striping"
14651
14652 test_123f() {
14653         local max
14654         local batch_max
14655         local dir=$DIR/$tdir
14656
14657         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14658                 skip "Server does not support batch RPC"
14659
14660         mkdir $dir || error "mkdir $dir failed"
14661         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14662         stack_trap "rm -rf $dir"
14663
14664         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14665
14666         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14667         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14668
14669         $LCTL set_param llite.*.statahead_max=64
14670         $LCTL set_param llite.*.statahead_batch_max=64
14671
14672         ls -l $dir
14673         lctl get_param mdc.*.batch_stats
14674         lctl get_param llite.*.statahead_*
14675
14676         $LCTL set_param llite.*.statahead_max=$max
14677         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14678 }
14679 run_test 123f "Retry mechanism with large wide striping files"
14680
14681 test_123g() {
14682         local dir=$DIR/$tdir
14683         local num=1000
14684
14685         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14686                 skip "Server does not support batch RPC"
14687
14688         mkdir $dir || error "failed to mkdir $dir"
14689         createmany -o $dir/$tfile $num || error "failed creatmany files"
14690         cancel_lru_locks mdc
14691         cancel_lru_locks osc
14692
14693         $LCTL set_param llite.*.statahead_stats=clear
14694         $LCTL set_param mdc.*.batch_stats=clear
14695         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14696                 error "aheadmany $dir with $tfile failed"
14697         wait_update_facet client "pgrep ll_sa" "" 35 ||
14698                 error "ll_sa thread is still running"
14699         $LCTL get_param -n llite.*.statahead_stats
14700         $LCTL get_param -n mdc.*.batch_stats
14701
14702         local count
14703
14704         count=$($LCTL get_param -n llite.*.statahead_stats |
14705                 awk '/hit.total:/ {print $2}')
14706         echo "Hit total: $count"
14707         # Hit ratio should be >= 75%
14708         (( $count > num * 75 / 100 )) ||
14709                 error "hit total $count is be > 75% of $num"
14710 }
14711 run_test 123g "Test for stat-ahead advise"
14712
14713 test_123h_base() {
14714         local dir=$DIR/$tdir
14715         local cmd="touch $dir/$tfile.{$1}"
14716         local fcnt=$2
14717
14718         stack_trap "rm -rf $dir"
14719         mkdir -p $dir || error "failed to mkdir $dir"
14720         eval $cmd
14721
14722         cancel_lru_locks mdc
14723         $LCTL set_param llite.*.statahead_stats=clear
14724         $LCTL set_param mdc.*.batch_stats=0
14725         $LCTL set_param llite.*.statahead_max=1024
14726         $LCTL set_param llite.*.statahead_batch_max=1024
14727         lctl get_param -n llite.*.statahead_stats
14728         du -a $dir > /dev/null
14729         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14730         wait_update_facet client "pgrep ll_sa" "" 35 ||
14731                 error "ll_sa statahead thread does not quit in 35s"
14732         $LCTL get_param -n llite.*.statahead_stats
14733         $LCTL get_param -n mdc.*.batch_stats
14734
14735         local count=$($LCTL get_param -n llite.*.statahead_stats |
14736                         awk '/fname.total:/ {print $2}')
14737
14738         [ $count == 1 ] || error "File name pattern statahead not trigger"
14739         count=$($LCTL get_param -n llite.*.statahead_stats |
14740                 awk '/hit.total:/ {print $2}')
14741         # Hit ratio should be >= 75%
14742         (( $count > fcnt * 75 / 100 )) ||
14743                 error "hit total is too low: $count"
14744         rm -rf $dir || error "rm -rf $dir failed"
14745 }
14746
14747 test_123h() {
14748         local max
14749         local batch_max
14750         local enabled
14751
14752         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14753                 skip "Server does not support batch RPC"
14754
14755         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14756         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14757         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14758         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14759         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14760         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14761
14762         $LCTL set_param llite.*.enable_statahead_fname=1
14763
14764         echo "Scan a directory with number regularized fname"
14765         test_123h_base "0..10000" 10000
14766
14767         echo "Scan a directory with zeroed padding number regularized fname"
14768         test_123h_base "000000..010000" 10000
14769 }
14770 run_test 123h "Verify statahead work with the fname pattern via du"
14771
14772 test_123i_base() {
14773         local fmt=$1
14774         local iocmd=$2
14775         local dir=$DIR/$tdir
14776         local cmd="createmany -m $fmt"
14777
14778         echo "Command:"
14779         echo "- $cmd"
14780         echo "- $iocmd"
14781         stack_trap "unlinkmany $fmt"
14782         mkdir -p $dir || error "failed to mkdir $dir"
14783         eval $cmd
14784
14785         cancel_lru_locks mdc
14786         $LCTL set_param llite.*.statahead_stats=clear
14787         $LCTL set_param mdc.*.batch_stats=0
14788
14789         echo "statahead_stats (Pre):"
14790         lctl get_param -n llite.*.statahead_stats
14791         eval $iocmd || error "$iocmd failed"
14792         echo "statahead_stats (Post):"
14793         $LCTL get_param -n llite.*.statahead_stats
14794         $LCTL get_param -n mdc.*.batch_stats
14795
14796         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14797         wait_update_facet client "pgrep ll_sa" "" 35 ||
14798                 error "ll_sa statahead thread does not quit in 35s"
14799         $LCTL get_param -n llite.*.statahead_stats
14800         $LCTL get_param -n mdc.*.batch_stats
14801
14802         local count=$($LCTL get_param -n llite.*.statahead_stats |
14803                         awk '/fname.total:/ {print $2}')
14804
14805         [ $count == 1 ] || error "File name pattern statahead not trigger"
14806         count=$($LCTL get_param -n llite.*.statahead_stats |
14807                 awk '/hit.total:/ {print $2}')
14808         # Hit ratio should be >= 75%
14809         (( $count > 750 )) || error "hit total is too low: $count"
14810 }
14811
14812 test_123i() {
14813         local dir=$DIR/$tdir
14814         local cnt=1000
14815         local max
14816         local batch_max
14817         local enabled
14818         local min
14819
14820         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14821                 skip "Server does not support batch RPC"
14822
14823         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14824         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14825         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14826         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14827         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14828         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14829         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14830         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14831         $LCTL set_param llite.*.statahead_max=1024
14832         $LCTL set_param llite.*.statahead_batch_max=32
14833         $LCTL set_param llite.*.statahead_min=64
14834         $LCTL set_param llite.*.enable_statahead_fname=1
14835
14836         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14837         test_123i_base "$dir/$tfile $cnt" \
14838                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14839 }
14840 run_test 123i "Verify statahead work with the fname indexing pattern"
14841
14842 test_124a() {
14843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14844         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14845                 skip_env "no lru resize on server"
14846
14847         local NR=2000
14848
14849         test_mkdir $DIR/$tdir
14850
14851         log "create $NR files at $DIR/$tdir"
14852         createmany -o $DIR/$tdir/f $NR ||
14853                 error "failed to create $NR files in $DIR/$tdir"
14854
14855         cancel_lru_locks mdc
14856         ls -l $DIR/$tdir > /dev/null
14857
14858         local NSDIR=""
14859         local LRU_SIZE=0
14860         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14861                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14862                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14863                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14864                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14865                         log "NSDIR=$NSDIR"
14866                         log "NS=$(basename $NSDIR)"
14867                         break
14868                 fi
14869         done
14870
14871         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14872                 skip "Not enough cached locks created!"
14873         fi
14874         log "LRU=$LRU_SIZE"
14875
14876         local SLEEP=30
14877
14878         # We know that lru resize allows one client to hold $LIMIT locks
14879         # for 10h. After that locks begin to be killed by client.
14880         local MAX_HRS=10
14881         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14882         log "LIMIT=$LIMIT"
14883         if [ $LIMIT -lt $LRU_SIZE ]; then
14884                 skip "Limit is too small $LIMIT"
14885         fi
14886
14887         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14888         # killing locks. Some time was spent for creating locks. This means
14889         # that up to the moment of sleep finish we must have killed some of
14890         # them (10-100 locks). This depends on how fast ther were created.
14891         # Many of them were touched in almost the same moment and thus will
14892         # be killed in groups.
14893         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14894
14895         # Use $LRU_SIZE_B here to take into account real number of locks
14896         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14897         local LRU_SIZE_B=$LRU_SIZE
14898         log "LVF=$LVF"
14899         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14900         log "OLD_LVF=$OLD_LVF"
14901         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14902
14903         # Let's make sure that we really have some margin. Client checks
14904         # cached locks every 10 sec.
14905         SLEEP=$((SLEEP+20))
14906         log "Sleep ${SLEEP} sec"
14907         local SEC=0
14908         while ((SEC<$SLEEP)); do
14909                 echo -n "..."
14910                 sleep 5
14911                 SEC=$((SEC+5))
14912                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14913                 echo -n "$LRU_SIZE"
14914         done
14915         echo ""
14916         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14917         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14918
14919         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14920                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14921                 unlinkmany $DIR/$tdir/f $NR
14922                 return
14923         }
14924
14925         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14926         log "unlink $NR files at $DIR/$tdir"
14927         unlinkmany $DIR/$tdir/f $NR
14928 }
14929 run_test 124a "lru resize ======================================="
14930
14931 get_max_pool_limit()
14932 {
14933         local limit=$($LCTL get_param \
14934                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14935         local max=0
14936         for l in $limit; do
14937                 if [[ $l -gt $max ]]; then
14938                         max=$l
14939                 fi
14940         done
14941         echo $max
14942 }
14943
14944 test_124b() {
14945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14946         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14947                 skip_env "no lru resize on server"
14948
14949         LIMIT=$(get_max_pool_limit)
14950
14951         NR=$(($(default_lru_size)*20))
14952         if [[ $NR -gt $LIMIT ]]; then
14953                 log "Limit lock number by $LIMIT locks"
14954                 NR=$LIMIT
14955         fi
14956
14957         IFree=$(mdsrate_inodes_available)
14958         if [ $IFree -lt $NR ]; then
14959                 log "Limit lock number by $IFree inodes"
14960                 NR=$IFree
14961         fi
14962
14963         lru_resize_disable mdc
14964         test_mkdir -p $DIR/$tdir/disable_lru_resize
14965
14966         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14967         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14968         cancel_lru_locks mdc
14969         stime=`date +%s`
14970         PID=""
14971         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14972         PID="$PID $!"
14973         sleep 2
14974         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14975         PID="$PID $!"
14976         sleep 2
14977         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14978         PID="$PID $!"
14979         wait $PID
14980         etime=`date +%s`
14981         nolruresize_delta=$((etime-stime))
14982         log "ls -la time: $nolruresize_delta seconds"
14983         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14984         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14985
14986         lru_resize_enable mdc
14987         test_mkdir -p $DIR/$tdir/enable_lru_resize
14988
14989         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14990         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14991         cancel_lru_locks mdc
14992         stime=`date +%s`
14993         PID=""
14994         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14995         PID="$PID $!"
14996         sleep 2
14997         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14998         PID="$PID $!"
14999         sleep 2
15000         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15001         PID="$PID $!"
15002         wait $PID
15003         etime=`date +%s`
15004         lruresize_delta=$((etime-stime))
15005         log "ls -la time: $lruresize_delta seconds"
15006         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15007
15008         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15009                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15010         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15011                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15012         else
15013                 log "lru resize performs the same with no lru resize"
15014         fi
15015         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15016 }
15017 run_test 124b "lru resize (performance test) ======================="
15018
15019 test_124c() {
15020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15021         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15022                 skip_env "no lru resize on server"
15023
15024         # cache ununsed locks on client
15025         local nr=100
15026         cancel_lru_locks mdc
15027         test_mkdir $DIR/$tdir
15028         createmany -o $DIR/$tdir/f $nr ||
15029                 error "failed to create $nr files in $DIR/$tdir"
15030         ls -l $DIR/$tdir > /dev/null
15031
15032         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15033         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15034         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15035         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15036         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15037
15038         # set lru_max_age to 1 sec
15039         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15040         echo "sleep $((recalc_p * 2)) seconds..."
15041         sleep $((recalc_p * 2))
15042
15043         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15044         # restore lru_max_age
15045         $LCTL set_param -n $nsdir.lru_max_age $max_age
15046         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15047         unlinkmany $DIR/$tdir/f $nr
15048 }
15049 run_test 124c "LRUR cancel very aged locks"
15050
15051 test_124d() {
15052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15053         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15054                 skip_env "no lru resize on server"
15055
15056         # cache ununsed locks on client
15057         local nr=100
15058
15059         lru_resize_disable mdc
15060         stack_trap "lru_resize_enable mdc" EXIT
15061
15062         cancel_lru_locks mdc
15063
15064         # asynchronous object destroy at MDT could cause bl ast to client
15065         test_mkdir $DIR/$tdir
15066         createmany -o $DIR/$tdir/f $nr ||
15067                 error "failed to create $nr files in $DIR/$tdir"
15068         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15069
15070         ls -l $DIR/$tdir > /dev/null
15071
15072         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15073         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15074         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15075         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15076
15077         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15078
15079         # set lru_max_age to 1 sec
15080         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15081         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15082
15083         echo "sleep $((recalc_p * 2)) seconds..."
15084         sleep $((recalc_p * 2))
15085
15086         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15087
15088         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15089 }
15090 run_test 124d "cancel very aged locks if lru-resize disabled"
15091
15092 test_125() { # 13358
15093         $LCTL get_param -n llite.*.client_type | grep -q local ||
15094                 skip "must run as local client"
15095         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15096                 skip_env "must have acl enabled"
15097         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15098         id $USER0 || skip_env "missing user $USER0"
15099
15100         test_mkdir $DIR/$tdir
15101         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15102         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15103                 error "setfacl $DIR/$tdir failed"
15104         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15105 }
15106 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15107
15108 test_126() { # bug 12829/13455
15109         $GSS && skip_env "must run as gss disabled"
15110         $LCTL get_param -n llite.*.client_type | grep -q local ||
15111                 skip "must run as local client"
15112         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15113
15114         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15115         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15116         rm -f $DIR/$tfile
15117         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15118 }
15119 run_test 126 "check that the fsgid provided by the client is taken into account"
15120
15121 test_127a() { # bug 15521
15122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15123         local name count samp unit min max sum sumsq
15124         local tmpfile=$TMP/$tfile.tmp
15125
15126         # enable stats header if it is disabled
15127         $LCTL set_param enable_stats_header=1
15128
15129         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15130         echo "stats before reset"
15131         stack_trap "rm -f $tmpfile"
15132         local now=$(date +%s)
15133
15134         $LCTL get_param osc.*.stats | tee $tmpfile
15135
15136         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15137         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15138         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15139         local uptime=$(awk '{ print $1 }' /proc/uptime)
15140
15141         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15142         (( ${snapshot_time%\.*} >= $now - 5 &&
15143            ${snapshot_time%\.*} <= $now + 5 )) ||
15144                 error "snapshot_time=$snapshot_time != now=$now"
15145         # elapsed _should_ be from mount, but at least less than uptime
15146         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15147                 error "elapsed=$elapsed > uptime=$uptime"
15148         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15149            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15150                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15151
15152         $LCTL set_param osc.*.stats=0
15153         local reset=$(date +%s)
15154         local fsize=$((2048 * 1024))
15155
15156         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15157         cancel_lru_locks osc
15158         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15159
15160         now=$(date +%s)
15161         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15162         while read name count samp unit min max sum sumsq; do
15163                 [[ "$samp" == "samples" ]] || continue
15164
15165                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15166                 [ ! $min ] && error "Missing min value for $name proc entry"
15167                 eval $name=$count || error "Wrong proc format"
15168
15169                 case $name in
15170                 read_bytes|write_bytes)
15171                         [[ "$unit" =~ "bytes" ]] ||
15172                                 error "unit is not 'bytes': $unit"
15173                         (( $min >= 4096 )) || error "min is too small: $min"
15174                         (( $min <= $fsize )) || error "min is too big: $min"
15175                         (( $max >= 4096 )) || error "max is too small: $max"
15176                         (( $max <= $fsize )) || error "max is too big: $max"
15177                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15178                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15179                                 error "sumsquare is too small: $sumsq"
15180                         (( $sumsq <= $fsize * $fsize )) ||
15181                                 error "sumsquare is too big: $sumsq"
15182                         ;;
15183                 ost_read|ost_write)
15184                         [[ "$unit" =~ "usec" ]] ||
15185                                 error "unit is not 'usec': $unit"
15186                         ;;
15187                 *)      ;;
15188                 esac
15189         done < $tmpfile
15190
15191         #check that we actually got some stats
15192         [ "$read_bytes" ] || error "Missing read_bytes stats"
15193         [ "$write_bytes" ] || error "Missing write_bytes stats"
15194         [ "$read_bytes" != 0 ] || error "no read done"
15195         [ "$write_bytes" != 0 ] || error "no write done"
15196
15197         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15198         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15199         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15200
15201         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15202         (( ${snapshot_time%\.*} >= $now - 5 &&
15203            ${snapshot_time%\.*} <= $now + 5 )) ||
15204                 error "reset snapshot_time=$snapshot_time != now=$now"
15205         # elapsed should be from time of stats reset
15206         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15207            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15208                 error "reset elapsed=$elapsed > $now - $reset"
15209         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15210            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15211                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15212 }
15213 run_test 127a "verify the client stats are sane"
15214
15215 test_127b() { # bug LU-333
15216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15217         local name count samp unit min max sum sumsq
15218
15219         echo "stats before reset"
15220         $LCTL get_param llite.*.stats
15221         $LCTL set_param llite.*.stats=0
15222
15223         # perform 2 reads and writes so MAX is different from SUM.
15224         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15225         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15226         cancel_lru_locks osc
15227         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15228         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15229
15230         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15231         stack_trap "rm -f $TMP/$tfile.tmp"
15232         while read name count samp unit min max sum sumsq; do
15233                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15234                 eval $name=$count || error "Wrong proc format"
15235
15236                 case $name in
15237                 read_bytes|write_bytes)
15238                         [[ "$unit" =~ "bytes" ]] ||
15239                                 error "unit is not 'bytes': $unit"
15240                         (( $count == 2 )) || error "count is not 2: $count"
15241                         (( $min == $PAGE_SIZE )) ||
15242                                 error "min is not $PAGE_SIZE: $min"
15243                         (( $max == $PAGE_SIZE )) ||
15244                                 error "max is not $PAGE_SIZE: $max"
15245                         (( $sum == $PAGE_SIZE * 2 )) ||
15246                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15247                         ;;
15248                 read|write)
15249                         [[ "$unit" =~ "usec" ]] ||
15250                                 error "unit is not 'usec': $unit"
15251                         ;;
15252                 *)      ;;
15253                 esac
15254         done < $TMP/$tfile.tmp
15255
15256         #check that we actually got some stats
15257         [ "$read_bytes" ] || error "Missing read_bytes stats"
15258         [ "$write_bytes" ] || error "Missing write_bytes stats"
15259         [ "$read_bytes" != 0 ] || error "no read done"
15260         [ "$write_bytes" != 0 ] || error "no write done"
15261 }
15262 run_test 127b "verify the llite client stats are sane"
15263
15264 test_127c() { # LU-12394
15265         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15266         local size
15267         local bsize
15268         local reads
15269         local writes
15270         local count
15271
15272         $LCTL set_param llite.*.extents_stats=1
15273         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15274
15275         # Use two stripes so there is enough space in default config
15276         $LFS setstripe -c 2 $DIR/$tfile
15277
15278         # Extent stats start at 0-4K and go in power of two buckets
15279         # LL_HIST_START = 12 --> 2^12 = 4K
15280         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15281         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15282         # small configs
15283         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15284                 do
15285                 # Write and read, 2x each, second time at a non-zero offset
15286                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15287                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15288                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15289                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15290                 rm -f $DIR/$tfile
15291         done
15292
15293         $LCTL get_param llite.*.extents_stats
15294
15295         count=2
15296         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15297                 do
15298                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15299                                 grep -m 1 $bsize)
15300                 reads=$(echo $bucket | awk '{print $5}')
15301                 writes=$(echo $bucket | awk '{print $9}')
15302                 [ "$reads" -eq $count ] ||
15303                         error "$reads reads in < $bsize bucket, expect $count"
15304                 [ "$writes" -eq $count ] ||
15305                         error "$writes writes in < $bsize bucket, expect $count"
15306         done
15307
15308         # Test mmap write and read
15309         $LCTL set_param llite.*.extents_stats=c
15310         size=512
15311         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15312         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15313         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15314
15315         $LCTL get_param llite.*.extents_stats
15316
15317         count=$(((size*1024) / PAGE_SIZE))
15318
15319         bsize=$((2 * PAGE_SIZE / 1024))K
15320
15321         bucket=$($LCTL get_param -n llite.*.extents_stats |
15322                         grep -m 1 $bsize)
15323         reads=$(echo $bucket | awk '{print $5}')
15324         writes=$(echo $bucket | awk '{print $9}')
15325         # mmap writes fault in the page first, creating an additonal read
15326         [ "$reads" -eq $((2 * count)) ] ||
15327                 error "$reads reads in < $bsize bucket, expect $count"
15328         [ "$writes" -eq $count ] ||
15329                 error "$writes writes in < $bsize bucket, expect $count"
15330 }
15331 run_test 127c "test llite extent stats with regular & mmap i/o"
15332
15333 test_128() { # bug 15212
15334         touch $DIR/$tfile
15335         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15336                 find $DIR/$tfile
15337                 find $DIR/$tfile
15338         EOF
15339
15340         result=$(grep error $TMP/$tfile.log)
15341         rm -f $DIR/$tfile $TMP/$tfile.log
15342         [ -z "$result" ] ||
15343                 error "consecutive find's under interactive lfs failed"
15344 }
15345 run_test 128 "interactive lfs for 2 consecutive find's"
15346
15347 set_dir_limits () {
15348         local mntdev
15349         local canondev
15350         local node
15351
15352         local ldproc=/proc/fs/ldiskfs
15353         local facets=$(get_facets MDS)
15354
15355         for facet in ${facets//,/ }; do
15356                 canondev=$(ldiskfs_canon \
15357                            *.$(convert_facet2label $facet).mntdev $facet)
15358                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15359                         ldproc=/sys/fs/ldiskfs
15360                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15361                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15362         done
15363 }
15364
15365 check_mds_dmesg() {
15366         local facets=$(get_facets MDS)
15367         for facet in ${facets//,/ }; do
15368                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15369         done
15370         return 1
15371 }
15372
15373 test_129() {
15374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15375         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15376                 skip "Need MDS version with at least 2.5.56"
15377         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15378                 skip_env "ldiskfs only test"
15379         fi
15380         remote_mds_nodsh && skip "remote MDS with nodsh"
15381
15382         local ENOSPC=28
15383         local has_warning=false
15384
15385         rm -rf $DIR/$tdir
15386         mkdir -p $DIR/$tdir
15387
15388         # block size of mds1
15389         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15390         set_dir_limits $maxsize $((maxsize * 6 / 8))
15391         stack_trap "set_dir_limits 0 0"
15392         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15393         local dirsize=$(stat -c%s "$DIR/$tdir")
15394         local nfiles=0
15395         while (( $dirsize <= $maxsize )); do
15396                 $MCREATE $DIR/$tdir/file_base_$nfiles
15397                 rc=$?
15398                 # check two errors:
15399                 # ENOSPC for ext4 max_dir_size, which has been used since
15400                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15401                 if (( rc == ENOSPC )); then
15402                         set_dir_limits 0 0
15403                         echo "rc=$rc returned as expected after $nfiles files"
15404
15405                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15406                                 error "create failed w/o dir size limit"
15407
15408                         # messages may be rate limited if test is run repeatedly
15409                         check_mds_dmesg '"is approaching max"' ||
15410                                 echo "warning message should be output"
15411                         check_mds_dmesg '"has reached max"' ||
15412                                 echo "reached message should be output"
15413
15414                         dirsize=$(stat -c%s "$DIR/$tdir")
15415
15416                         [[ $dirsize -ge $maxsize ]] && return 0
15417                         error "dirsize $dirsize < $maxsize after $nfiles files"
15418                 elif (( rc != 0 )); then
15419                         break
15420                 fi
15421                 nfiles=$((nfiles + 1))
15422                 dirsize=$(stat -c%s "$DIR/$tdir")
15423         done
15424
15425         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15426 }
15427 run_test 129 "test directory size limit ========================"
15428
15429 OLDIFS="$IFS"
15430 cleanup_130() {
15431         trap 0
15432         IFS="$OLDIFS"
15433         rm -f $DIR/$tfile
15434 }
15435
15436 test_130a() {
15437         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15438         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15439
15440         trap cleanup_130 EXIT RETURN
15441
15442         local fm_file=$DIR/$tfile
15443         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15444         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15445                 error "dd failed for $fm_file"
15446
15447         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15448         filefrag -ves $fm_file
15449         local rc=$?
15450         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15451                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15452         (( $rc == 0 )) || error "filefrag $fm_file failed"
15453
15454         filefrag_op=$(filefrag -ve -k $fm_file |
15455                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15456         local lun=$($LFS getstripe -i $fm_file)
15457
15458         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15459         IFS=$'\n'
15460         local tot_len=0
15461         for line in $filefrag_op; do
15462                 local frag_lun=$(echo $line | cut -d: -f5)
15463                 local ext_len=$(echo $line | cut -d: -f4)
15464
15465                 if (( $frag_lun != $lun )); then
15466                         error "FIEMAP on 1-stripe file($fm_file) failed"
15467                         return
15468                 fi
15469                 (( tot_len += ext_len ))
15470         done
15471
15472         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15473                 error "FIEMAP on 1-stripe file($fm_file) failed"
15474                 return
15475         fi
15476
15477         echo "FIEMAP on single striped file succeeded"
15478 }
15479 run_test 130a "FIEMAP (1-stripe file)"
15480
15481 test_130b() {
15482         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15483
15484         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15485         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15486         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15487                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15488
15489         trap cleanup_130 EXIT RETURN
15490
15491         local fm_file=$DIR/$tfile
15492         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15493                 error "setstripe on $fm_file"
15494
15495         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15496                 error "dd failed on $fm_file"
15497
15498         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15499         filefrag_op=$(filefrag -ve -k $fm_file |
15500                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15501
15502         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15503                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15504
15505         IFS=$'\n'
15506         local tot_len=0
15507         local num_luns=1
15508
15509         for line in $filefrag_op; do
15510                 local frag_lun=$(echo $line | cut -d: -f5 |
15511                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15512                 local ext_len=$(echo $line | cut -d: -f4)
15513                 if (( $frag_lun != $last_lun )); then
15514                         if (( tot_len != 1024 )); then
15515                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15516                                 return
15517                         else
15518                                 (( num_luns += 1 ))
15519                                 tot_len=0
15520                         fi
15521                 fi
15522                 (( tot_len += ext_len ))
15523                 last_lun=$frag_lun
15524         done
15525         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15526                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15527                 return
15528         fi
15529
15530         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15531 }
15532 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15533
15534 test_130c() {
15535         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15536
15537         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15538         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15539         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15540                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15541
15542         trap cleanup_130 EXIT RETURN
15543
15544         local fm_file=$DIR/$tfile
15545         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15546
15547         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15548                 error "dd failed on $fm_file"
15549
15550         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15551         filefrag_op=$(filefrag -ve -k $fm_file |
15552                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15553
15554         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15555                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15556
15557         IFS=$'\n'
15558         local tot_len=0
15559         local num_luns=1
15560         for line in $filefrag_op; do
15561                 local frag_lun=$(echo $line | cut -d: -f5 |
15562                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15563                 local ext_len=$(echo $line | cut -d: -f4)
15564                 if (( $frag_lun != $last_lun )); then
15565                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15566                         if (( logical != 512 )); then
15567                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15568                                 return
15569                         fi
15570                         if (( tot_len != 512 )); then
15571                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15572                                 return
15573                         else
15574                                 (( num_luns += 1 ))
15575                                 tot_len=0
15576                         fi
15577                 fi
15578                 (( tot_len += ext_len ))
15579                 last_lun=$frag_lun
15580         done
15581         if (( num_luns != 2 || tot_len != 512 )); then
15582                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15583                 return
15584         fi
15585
15586         echo "FIEMAP on 2-stripe file with hole succeeded"
15587 }
15588 run_test 130c "FIEMAP (2-stripe file with hole)"
15589
15590 test_130d() {
15591         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15592
15593         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15594         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15595         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15596                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15597
15598         trap cleanup_130 EXIT RETURN
15599
15600         local fm_file=$DIR/$tfile
15601         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15602                         error "setstripe on $fm_file"
15603
15604         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15605         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15606                 error "dd failed on $fm_file"
15607
15608         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15609         filefrag_op=$(filefrag -ve -k $fm_file |
15610                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15611
15612         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15613                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15614
15615         IFS=$'\n'
15616         local tot_len=0
15617         local num_luns=1
15618         for line in $filefrag_op; do
15619                 local frag_lun=$(echo $line | cut -d: -f5 |
15620                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15621                 local ext_len=$(echo $line | cut -d: -f4)
15622                 if (( $frag_lun != $last_lun )); then
15623                         if (( tot_len != 1024 )); then
15624                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15625                                 return
15626                         else
15627                                 (( num_luns += 1 ))
15628                                 local tot_len=0
15629                         fi
15630                 fi
15631                 (( tot_len += ext_len ))
15632                 last_lun=$frag_lun
15633         done
15634         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15635                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15636                 return
15637         fi
15638
15639         echo "FIEMAP on N-stripe file succeeded"
15640 }
15641 run_test 130d "FIEMAP (N-stripe file)"
15642
15643 test_130e() {
15644         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15645
15646         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15647         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15648         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15649                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15650
15651         trap cleanup_130 EXIT RETURN
15652
15653         local fm_file=$DIR/$tfile
15654         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15655         stack_trap "rm -f $fm_file"
15656
15657         local num_blks=512
15658         local expected_len=$(( (num_blks / 2) * 64 ))
15659         for ((i = 0; i < $num_blks; i++)); do
15660                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15661                         conv=notrunc > /dev/null 2>&1
15662         done
15663
15664         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15665         filefrag_op=$(filefrag -ve -k $fm_file |
15666                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15667
15668         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15669
15670         IFS=$'\n'
15671         local tot_len=0
15672         local num_luns=1
15673         for line in $filefrag_op; do
15674                 local frag_lun=$(echo $line | cut -d: -f5)
15675                 local ext_len=$(echo $line | cut -d: -f4)
15676                 if (( $frag_lun != $last_lun )); then
15677                         if (( tot_len != $expected_len )); then
15678                                 error "OST$last_lun $tot_len != $expected_len"
15679                         else
15680                                 (( num_luns += 1 ))
15681                                 tot_len=0
15682                         fi
15683                 fi
15684                 (( tot_len += ext_len ))
15685                 last_lun=$frag_lun
15686         done
15687         if (( num_luns != 2 || tot_len != $expected_len )); then
15688                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15689         fi
15690
15691         echo "FIEMAP with continuation calls succeeded"
15692 }
15693 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15694
15695 test_130f() {
15696         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15697         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15698         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15699                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15700
15701         local fm_file=$DIR/$tfile
15702         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15703                 error "multiop create with lov_delay_create on $fm_file"
15704
15705         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15706         filefrag_extents=$(filefrag -vek $fm_file |
15707                            awk '/extents? found/ { print $2 }')
15708         if (( $filefrag_extents != 0 )); then
15709                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15710         fi
15711
15712         rm -f $fm_file
15713 }
15714 run_test 130f "FIEMAP (unstriped file)"
15715
15716 test_130g() {
15717         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15718                 skip "Need MDS version with at least 2.12.53 for overstriping"
15719         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15720         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15721         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15722                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15723
15724         local file=$DIR/$tfile
15725         local nr=$((OSTCOUNT * 100))
15726
15727         $LFS setstripe -C $nr -S1M $file ||
15728                 error "failed to setstripe -C $nr $file"
15729
15730         stack_trap "rm -f $file"
15731         dd if=/dev/zero of=$file count=$nr bs=1M
15732         sync
15733         nr=$($LFS getstripe -c $file)
15734
15735         local extents=$(filefrag -v $file |
15736                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15737
15738         echo "filefrag list $extents extents in file with stripecount $nr"
15739         if (( extents < nr )); then
15740                 $LFS getstripe $file
15741                 filefrag -v $file
15742                 error "filefrag printed $extents < $nr extents"
15743         fi
15744 }
15745 run_test 130g "FIEMAP (overstripe file)"
15746
15747 # Test for writev/readv
15748 test_131a() {
15749         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15750                 error "writev test failed"
15751         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15752                 error "readv failed"
15753         rm -f $DIR/$tfile
15754 }
15755 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15756
15757 test_131b() {
15758         local fsize=$((524288 + 1048576 + 1572864))
15759         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15760                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15761                         error "append writev test failed"
15762
15763         ((fsize += 1572864 + 1048576))
15764         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15765                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15766                         error "append writev test failed"
15767         rm -f $DIR/$tfile
15768 }
15769 run_test 131b "test append writev"
15770
15771 test_131c() {
15772         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15773         error "NOT PASS"
15774 }
15775 run_test 131c "test read/write on file w/o objects"
15776
15777 test_131d() {
15778         rwv -f $DIR/$tfile -w -n 1 1572864
15779         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15780         if [ "$NOB" != 1572864 ]; then
15781                 error "Short read filed: read $NOB bytes instead of 1572864"
15782         fi
15783         rm -f $DIR/$tfile
15784 }
15785 run_test 131d "test short read"
15786
15787 test_131e() {
15788         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15789         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15790         error "read hitting hole failed"
15791         rm -f $DIR/$tfile
15792 }
15793 run_test 131e "test read hitting hole"
15794
15795 check_stats() {
15796         local facet=$1
15797         local op=$2
15798         local want=${3:-0}
15799         local res
15800
15801         # open             11 samples [usecs] 468 4793 13658 35791898
15802         case $facet in
15803         mds*) res=($(do_facet $facet \
15804                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15805                  ;;
15806         ost*) res=($(do_facet $facet \
15807                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15808                  ;;
15809         *) error "Wrong facet '$facet'" ;;
15810         esac
15811         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15812         # if $want is zero, it means any stat increment is ok.
15813         if (( $want > 0 )); then
15814                 local count=${res[1]}
15815
15816                 if (( $count != $want )); then
15817                         if [[ $facet =~ "mds" ]]; then
15818                                 do_nodes $(comma_list $(mdts_nodes)) \
15819                                         $LCTL get_param mdt.*.md_stats
15820                         else
15821                                 do_nodes $(comma_list $(osts-nodes)) \
15822                                         $LCTL get_param obdfilter.*.stats
15823                         fi
15824                         error "The $op counter on $facet is $count, not $want"
15825                 fi
15826         fi
15827 }
15828
15829 test_133a() {
15830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15831         remote_ost_nodsh && skip "remote OST with nodsh"
15832         remote_mds_nodsh && skip "remote MDS with nodsh"
15833         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15834                 skip_env "MDS doesn't support rename stats"
15835
15836         local testdir=$DIR/${tdir}/stats_testdir
15837
15838         mkdir_on_mdt0 $DIR/${tdir}
15839
15840         # clear stats.
15841         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15842         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15843
15844         # verify mdt stats first.
15845         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15846         check_stats $SINGLEMDS "mkdir" 1
15847
15848         # clear "open" from "lfs mkdir" above
15849         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15850         touch ${testdir}/${tfile} || error "touch failed"
15851         check_stats $SINGLEMDS "open" 1
15852         check_stats $SINGLEMDS "close" 1
15853         (( $MDS1_VERSION >= $(version_code 2.15.62) )) && {
15854                 # open should match close
15855                 ls -lR ${testdir}
15856                 check_stats $SINGLEMDS "open" 2
15857                 check_stats $SINGLEMDS "close" 2
15858         }
15859         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15860                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15861                 check_stats $SINGLEMDS "mknod" 2
15862         }
15863         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15864         check_stats $SINGLEMDS "unlink" 1
15865         rm -f ${testdir}/${tfile} || error "file remove failed"
15866         check_stats $SINGLEMDS "unlink" 2
15867
15868         # remove working dir and check mdt stats again.
15869         rmdir ${testdir} || error "rmdir failed"
15870         check_stats $SINGLEMDS "rmdir" 1
15871
15872         local testdir1=$DIR/${tdir}/stats_testdir1
15873         mkdir_on_mdt0 ${testdir}
15874         mkdir_on_mdt0 ${testdir1}
15875         touch ${testdir1}/test1
15876         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15877         check_stats $SINGLEMDS "crossdir_rename" 1
15878
15879         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15880         check_stats $SINGLEMDS "samedir_rename" 1
15881
15882         rm -rf $DIR/${tdir}
15883 }
15884 run_test 133a "Verifying MDT stats ========================================"
15885
15886 test_133b() {
15887         local res
15888
15889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15890         remote_ost_nodsh && skip "remote OST with nodsh"
15891         remote_mds_nodsh && skip "remote MDS with nodsh"
15892
15893         local testdir=$DIR/${tdir}/stats_testdir
15894
15895         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15896         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15897         touch ${testdir}/${tfile} || error "touch failed"
15898         cancel_lru_locks mdc
15899
15900         # clear stats.
15901         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15902         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15903
15904         # extra mdt stats verification.
15905         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15906         check_stats $SINGLEMDS "setattr" 1
15907         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15908         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15909         then            # LU-1740
15910                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15911                 check_stats $SINGLEMDS "getattr" 1
15912         fi
15913         rm -rf $DIR/${tdir}
15914
15915         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15916         # so the check below is not reliable
15917         [ $MDSCOUNT -eq 1 ] || return 0
15918
15919         # Sleep to avoid a cached response.
15920         #define OBD_STATFS_CACHE_SECONDS 1
15921         sleep 2
15922         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15923         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15924         $LFS df || error "lfs failed"
15925         check_stats $SINGLEMDS "statfs" 1
15926
15927         # check aggregated statfs (LU-10018)
15928         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15929                 return 0
15930         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15931                 return 0
15932         sleep 2
15933         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15934         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15935         df $DIR
15936         check_stats $SINGLEMDS "statfs" 1
15937
15938         # We want to check that the client didn't send OST_STATFS to
15939         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15940         # extra care is needed here.
15941         if remote_mds; then
15942                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15943                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15944
15945                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15946                 [ "$res" ] && error "OST got STATFS"
15947         fi
15948
15949         return 0
15950 }
15951 run_test 133b "Verifying extra MDT stats =================================="
15952
15953 test_133c() {
15954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15955         remote_ost_nodsh && skip "remote OST with nodsh"
15956         remote_mds_nodsh && skip "remote MDS with nodsh"
15957
15958         local testdir=$DIR/$tdir/stats_testdir
15959
15960         test_mkdir -p $testdir
15961
15962         # verify obdfilter stats.
15963         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15964         sync
15965         cancel_lru_locks osc
15966         wait_delete_completed
15967
15968         # clear stats.
15969         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15970         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15971
15972         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15973                 error "dd failed"
15974         sync
15975         cancel_lru_locks osc
15976         check_stats ost1 "write" 1
15977
15978         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15979         check_stats ost1 "read" 1
15980
15981         > $testdir/$tfile || error "truncate failed"
15982         check_stats ost1 "punch" 1
15983
15984         rm -f $testdir/$tfile || error "file remove failed"
15985         wait_delete_completed
15986         check_stats ost1 "destroy" 1
15987
15988         rm -rf $DIR/$tdir
15989 }
15990 run_test 133c "Verifying OST stats ========================================"
15991
15992 order_2() {
15993         local value=$1
15994         local orig=$value
15995         local order=1
15996
15997         while [ $value -ge 2 ]; do
15998                 order=$((order*2))
15999                 value=$((value/2))
16000         done
16001
16002         if [ $orig -gt $order ]; then
16003                 order=$((order*2))
16004         fi
16005         echo $order
16006 }
16007
16008 size_in_KMGT() {
16009     local value=$1
16010     local size=('K' 'M' 'G' 'T');
16011     local i=0
16012     local size_string=$value
16013
16014     while [ $value -ge 1024 ]; do
16015         if [ $i -gt 3 ]; then
16016             #T is the biggest unit we get here, if that is bigger,
16017             #just return XXXT
16018             size_string=${value}T
16019             break
16020         fi
16021         value=$((value >> 10))
16022         if [ $value -lt 1024 ]; then
16023             size_string=${value}${size[$i]}
16024             break
16025         fi
16026         i=$((i + 1))
16027     done
16028
16029     echo $size_string
16030 }
16031
16032 get_rename_size() {
16033         local size=$1
16034         local context=${2:-.}
16035         local sample=$(do_facet $SINGLEMDS $LCTL \
16036                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16037                 grep -A1 $context |
16038                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16039         echo $sample
16040 }
16041
16042 test_133d() {
16043         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16044         remote_ost_nodsh && skip "remote OST with nodsh"
16045         remote_mds_nodsh && skip "remote MDS with nodsh"
16046         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16047                 skip_env "MDS doesn't support rename stats"
16048
16049         local testdir1=$DIR/${tdir}/stats_testdir1
16050         local testdir2=$DIR/${tdir}/stats_testdir2
16051         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16052
16053         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16054
16055         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16056         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16057
16058         createmany -o $testdir1/test 512 || error "createmany failed"
16059
16060         # check samedir rename size
16061         mv ${testdir1}/test0 ${testdir1}/test_0
16062
16063         local testdir1_size=$(ls -l $DIR/${tdir} |
16064                 awk '/stats_testdir1/ {print $5}')
16065         local testdir2_size=$(ls -l $DIR/${tdir} |
16066                 awk '/stats_testdir2/ {print $5}')
16067
16068         testdir1_size=$(order_2 $testdir1_size)
16069         testdir2_size=$(order_2 $testdir2_size)
16070
16071         testdir1_size=$(size_in_KMGT $testdir1_size)
16072         testdir2_size=$(size_in_KMGT $testdir2_size)
16073
16074         echo "source rename dir size: ${testdir1_size}"
16075         echo "target rename dir size: ${testdir2_size}"
16076
16077         local cmd="do_facet $SINGLEMDS $LCTL "
16078         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16079
16080         eval $cmd || error "$cmd failed"
16081         local samedir=$($cmd | grep 'same_dir')
16082         local same_sample=$(get_rename_size $testdir1_size)
16083         [ -z "$samedir" ] && error "samedir_rename_size count error"
16084         [[ $same_sample -eq 1 ]] ||
16085                 error "samedir_rename_size error $same_sample"
16086         echo "Check same dir rename stats success"
16087
16088         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16089
16090         # check crossdir rename size
16091         mv ${testdir1}/test_0 ${testdir2}/test_0
16092
16093         testdir1_size=$(ls -l $DIR/${tdir} |
16094                 awk '/stats_testdir1/ {print $5}')
16095         testdir2_size=$(ls -l $DIR/${tdir} |
16096                 awk '/stats_testdir2/ {print $5}')
16097
16098         testdir1_size=$(order_2 $testdir1_size)
16099         testdir2_size=$(order_2 $testdir2_size)
16100
16101         testdir1_size=$(size_in_KMGT $testdir1_size)
16102         testdir2_size=$(size_in_KMGT $testdir2_size)
16103
16104         echo "source rename dir size: ${testdir1_size}"
16105         echo "target rename dir size: ${testdir2_size}"
16106
16107         eval $cmd || error "$cmd failed"
16108         local crossdir=$($cmd | grep 'crossdir')
16109         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16110         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16111         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16112         [[ $src_sample -eq 1 ]] ||
16113                 error "crossdir_rename_size error $src_sample"
16114         [[ $tgt_sample -eq 1 ]] ||
16115                 error "crossdir_rename_size error $tgt_sample"
16116         echo "Check cross dir rename stats success"
16117         rm -rf $DIR/${tdir}
16118 }
16119 run_test 133d "Verifying rename_stats ========================================"
16120
16121 test_133e() {
16122         remote_mds_nodsh && skip "remote MDS with nodsh"
16123         remote_ost_nodsh && skip "remote OST with nodsh"
16124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16125
16126         local testdir=$DIR/${tdir}/stats_testdir
16127         local ctr f0 f1 bs=32768 count=42 sum
16128
16129         mkdir -p ${testdir} || error "mkdir failed"
16130
16131         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16132
16133         for ctr in {write,read}_bytes; do
16134                 sync
16135                 cancel_lru_locks osc
16136
16137                 do_facet ost1 $LCTL set_param -n \
16138                         "obdfilter.*.exports.clear=clear"
16139
16140                 if [ $ctr = write_bytes ]; then
16141                         f0=/dev/zero
16142                         f1=${testdir}/${tfile}
16143                 else
16144                         f0=${testdir}/${tfile}
16145                         f1=/dev/null
16146                 fi
16147
16148                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16149                         error "dd failed"
16150                 sync
16151                 cancel_lru_locks osc
16152
16153                 sum=$(do_facet ost1 $LCTL get_param \
16154                         "obdfilter.*.exports.*.stats" |
16155                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16156                                 $1 == ctr { sum += $7 }
16157                                 END { printf("%0.0f", sum) }')
16158
16159                 if ((sum != bs * count)); then
16160                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16161                 fi
16162         done
16163
16164         rm -rf $DIR/${tdir}
16165 }
16166 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16167
16168 test_133f() {
16169         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16170                 skip "too old lustre for get_param -R ($facet_ver)"
16171
16172         # verifying readability.
16173         $LCTL get_param -R '*' &> /dev/null
16174
16175         # Verifing writability with badarea_io.
16176         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16177         local skipped_params='force_lbug|changelog_mask|daemon_file'
16178         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16179                 egrep -v "$skipped_params" |
16180                 xargs -n 1 find $proc_dirs -name |
16181                 xargs -n 1 badarea_io ||
16182                 error "client badarea_io failed"
16183
16184         # remount the FS in case writes/reads /proc break the FS
16185         cleanup || error "failed to unmount"
16186         setup || error "failed to setup"
16187 }
16188 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16189
16190 test_133g() {
16191         remote_mds_nodsh && skip "remote MDS with nodsh"
16192         remote_ost_nodsh && skip "remote OST with nodsh"
16193
16194         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16195         local proc_dirs_str=$(eval echo $proc_dirs)
16196         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16197         local facet
16198         for facet in mds1 ost1; do
16199                 local facet_ver=$(lustre_version_code $facet)
16200                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16201                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16202                 else
16203                         log "$facet: too old lustre for get_param -R"
16204                 fi
16205                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16206                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16207                                 tr -d = | egrep -v $skipped_params |
16208                                 xargs -n 1 find $proc_dirs_str -name |
16209                                 xargs -n 1 badarea_io" ||
16210                                         error "$facet badarea_io failed"
16211                 else
16212                         skip_noexit "$facet: too old lustre for get_param -R"
16213                 fi
16214         done
16215
16216         # remount the FS in case writes/reads /proc break the FS
16217         cleanup || error "failed to unmount"
16218         setup || error "failed to setup"
16219 }
16220 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16221
16222 test_133h() {
16223         remote_mds_nodsh && skip "remote MDS with nodsh"
16224         remote_ost_nodsh && skip "remote OST with nodsh"
16225         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16226                 skip "Need MDS version at least 2.9.54"
16227
16228         local facet
16229         for facet in client mds1 ost1; do
16230                 # Get the list of files that are missing the terminating newline
16231                 local plist=$(do_facet $facet
16232                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16233                 local ent
16234                 for ent in $plist; do
16235                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16236                                 awk -v FS='\v' -v RS='\v\v' \
16237                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16238                                         print FILENAME}'" 2>/dev/null)
16239                         [ -z $missing ] || {
16240                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16241                                 error "file does not end with newline: $facet-$ent"
16242                         }
16243                 done
16244         done
16245 }
16246 run_test 133h "Proc files should end with newlines"
16247
16248 test_134a() {
16249         remote_mds_nodsh && skip "remote MDS with nodsh"
16250         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16251                 skip "Need MDS version at least 2.7.54"
16252
16253         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16254         cancel_lru_locks mdc
16255
16256         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16257         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16258         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16259
16260         local nr=1000
16261         createmany -o $DIR/$tdir/f $nr ||
16262                 error "failed to create $nr files in $DIR/$tdir"
16263         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16264
16265         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16266         do_facet mds1 $LCTL set_param fail_loc=0x327
16267         do_facet mds1 $LCTL set_param fail_val=500
16268         touch $DIR/$tdir/m
16269
16270         echo "sleep 10 seconds ..."
16271         sleep 10
16272         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16273
16274         do_facet mds1 $LCTL set_param fail_loc=0
16275         do_facet mds1 $LCTL set_param fail_val=0
16276         [ $lck_cnt -lt $unused ] ||
16277                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16278
16279         rm $DIR/$tdir/m
16280         unlinkmany $DIR/$tdir/f $nr
16281 }
16282 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16283
16284 test_134b() {
16285         remote_mds_nodsh && skip "remote MDS with nodsh"
16286         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16287                 skip "Need MDS version at least 2.7.54"
16288
16289         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16290         cancel_lru_locks mdc
16291
16292         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16293                         ldlm.lock_reclaim_threshold_mb)
16294         # disable reclaim temporarily
16295         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16296
16297         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16298         do_facet mds1 $LCTL set_param fail_loc=0x328
16299         do_facet mds1 $LCTL set_param fail_val=500
16300
16301         $LCTL set_param debug=+trace
16302
16303         local nr=600
16304         createmany -o $DIR/$tdir/f $nr &
16305         local create_pid=$!
16306
16307         echo "Sleep $TIMEOUT seconds ..."
16308         sleep $TIMEOUT
16309         if ! ps -p $create_pid  > /dev/null 2>&1; then
16310                 do_facet mds1 $LCTL set_param fail_loc=0
16311                 do_facet mds1 $LCTL set_param fail_val=0
16312                 do_facet mds1 $LCTL set_param \
16313                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16314                 error "createmany finished incorrectly!"
16315         fi
16316         do_facet mds1 $LCTL set_param fail_loc=0
16317         do_facet mds1 $LCTL set_param fail_val=0
16318         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16319         wait $create_pid || return 1
16320
16321         unlinkmany $DIR/$tdir/f $nr
16322 }
16323 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16324
16325 test_135() {
16326         remote_mds_nodsh && skip "remote MDS with nodsh"
16327         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16328                 skip "Need MDS version at least 2.13.50"
16329         local fname
16330
16331         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16332
16333 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16334         #set only one record at plain llog
16335         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16336
16337         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16338
16339         #fill already existed plain llog each 64767
16340         #wrapping whole catalog
16341         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16342
16343         createmany -o $DIR/$tdir/$tfile_ 64700
16344         for (( i = 0; i < 64700; i = i + 2 ))
16345         do
16346                 rm $DIR/$tdir/$tfile_$i &
16347                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16348                 local pid=$!
16349                 wait $pid
16350         done
16351
16352         #waiting osp synchronization
16353         wait_delete_completed
16354 }
16355 run_test 135 "Race catalog processing"
16356
16357 test_136() {
16358         remote_mds_nodsh && skip "remote MDS with nodsh"
16359         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16360                 skip "Need MDS version at least 2.13.50"
16361         local fname
16362
16363         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16364         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16365         #set only one record at plain llog
16366 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16367         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16368
16369         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16370
16371         #fill already existed 2 plain llogs each 64767
16372         #wrapping whole catalog
16373         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16374         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16375         wait_delete_completed
16376
16377         createmany -o $DIR/$tdir/$tfile_ 10
16378         sleep 25
16379
16380         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16381         for (( i = 0; i < 10; i = i + 3 ))
16382         do
16383                 rm $DIR/$tdir/$tfile_$i &
16384                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16385                 local pid=$!
16386                 wait $pid
16387                 sleep 7
16388                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16389         done
16390
16391         #waiting osp synchronization
16392         wait_delete_completed
16393 }
16394 run_test 136 "Race catalog processing 2"
16395
16396 test_140() { #bug-17379
16397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16398
16399         test_mkdir $DIR/$tdir
16400         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16401         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16402
16403         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16404         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16405         local i=0
16406         while i=$((i + 1)); do
16407                 test_mkdir $i
16408                 cd $i || error "Changing to $i"
16409                 ln -s ../stat stat || error "Creating stat symlink"
16410                 # Read the symlink until ELOOP present,
16411                 # not LBUGing the system is considered success,
16412                 # we didn't overrun the stack.
16413                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16414                 if [ $ret -ne 0 ]; then
16415                         if [ $ret -eq 40 ]; then
16416                                 break  # -ELOOP
16417                         else
16418                                 error "Open stat symlink"
16419                                         return
16420                         fi
16421                 fi
16422         done
16423         i=$((i - 1))
16424         echo "The symlink depth = $i"
16425         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16426                 error "Invalid symlink depth"
16427
16428         # Test recursive symlink
16429         ln -s symlink_self symlink_self
16430         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16431         echo "open symlink_self returns $ret"
16432         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16433 }
16434 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16435
16436 test_150a() {
16437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16438
16439         local TF="$TMP/$tfile"
16440
16441         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16442         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16443         cp $TF $DIR/$tfile
16444         cancel_lru_locks $OSC
16445         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16446         remount_client $MOUNT
16447         df -P $MOUNT
16448         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16449
16450         $TRUNCATE $TF 6000
16451         $TRUNCATE $DIR/$tfile 6000
16452         cancel_lru_locks $OSC
16453         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16454
16455         echo "12345" >>$TF
16456         echo "12345" >>$DIR/$tfile
16457         cancel_lru_locks $OSC
16458         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16459
16460         echo "12345" >>$TF
16461         echo "12345" >>$DIR/$tfile
16462         cancel_lru_locks $OSC
16463         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16464 }
16465 run_test 150a "truncate/append tests"
16466
16467 test_150b() {
16468         check_set_fallocate_or_skip
16469         local out
16470
16471         touch $DIR/$tfile
16472         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16473         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16474                 skip_eopnotsupp "$out|check_fallocate failed"
16475 }
16476 run_test 150b "Verify fallocate (prealloc) functionality"
16477
16478 test_150bb() {
16479         check_set_fallocate_or_skip
16480
16481         touch $DIR/$tfile
16482         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16483         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16484         > $DIR/$tfile
16485         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16486         # precomputed md5sum for 20MB of zeroes
16487         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16488         local sum=($(md5sum $DIR/$tfile))
16489
16490         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16491
16492         check_set_fallocate 1
16493
16494         > $DIR/$tfile
16495         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16496         sum=($(md5sum $DIR/$tfile))
16497
16498         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16499 }
16500 run_test 150bb "Verify fallocate modes both zero space"
16501
16502 test_150c() {
16503         check_set_fallocate_or_skip
16504         local striping="-c2"
16505
16506         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16507         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16508         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16509         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16510         local want=$((OSTCOUNT * 1048576))
16511
16512         # Must allocate all requested space, not more than 5% extra
16513         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16514                 error "bytes $bytes is not $want"
16515
16516         rm -f $DIR/$tfile
16517
16518         echo "verify fallocate on PFL file"
16519
16520         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16521
16522         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16523                 error "Create $DIR/$tfile failed"
16524         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16525         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16526         want=$((512 * 1048576))
16527
16528         # Must allocate all requested space, not more than 5% extra
16529         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16530                 error "bytes $bytes is not $want"
16531 }
16532 run_test 150c "Verify fallocate Size and Blocks"
16533
16534 test_150d() {
16535         check_set_fallocate_or_skip
16536         local striping="-c2"
16537
16538         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16539
16540         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16541         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16542                 error "setstripe failed"
16543         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16544         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16545         local want=$((OSTCOUNT * 1048576))
16546
16547         # Must allocate all requested space, not more than 5% extra
16548         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16549                 error "bytes $bytes is not $want"
16550 }
16551 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16552
16553 test_150e() {
16554         check_set_fallocate_or_skip
16555
16556         echo "df before:"
16557         $LFS df
16558         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16559         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16560                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16561
16562         # Find OST with Minimum Size
16563         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16564                        sort -un | head -1)
16565
16566         # Get 100MB per OST of the available space to reduce run time
16567         # else 60% of the available space if we are running SLOW tests
16568         if [ $SLOW == "no" ]; then
16569                 local space=$((1024 * 100 * OSTCOUNT))
16570         else
16571                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16572         fi
16573
16574         fallocate -l${space}k $DIR/$tfile ||
16575                 error "fallocate ${space}k $DIR/$tfile failed"
16576         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16577
16578         # get size immediately after fallocate. This should be correctly
16579         # updated
16580         local size=$(stat -c '%s' $DIR/$tfile)
16581         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16582
16583         # Sleep for a while for statfs to get updated. And not pull from cache.
16584         sleep 2
16585
16586         echo "df after fallocate:"
16587         $LFS df
16588
16589         (( size / 1024 == space )) || error "size $size != requested $space"
16590         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16591                 error "used $used < space $space"
16592
16593         rm $DIR/$tfile || error "rm failed"
16594         sync
16595         wait_delete_completed
16596
16597         echo "df after unlink:"
16598         $LFS df
16599 }
16600 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16601
16602 test_150f() {
16603         local size
16604         local blocks
16605         local want_size_before=20480 # in bytes
16606         local want_blocks_before=40 # 512 sized blocks
16607         local want_blocks_after=24  # 512 sized blocks
16608         local length=$(((want_blocks_before - want_blocks_after) * 512))
16609
16610         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16611                 skip "need at least 2.14.0 for fallocate punch"
16612
16613         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16614                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16615         fi
16616
16617         check_set_fallocate_or_skip
16618         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16619
16620         [[ "x$DOM" == "xyes" ]] &&
16621                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16622
16623         echo "Verify fallocate punch: Range within the file range"
16624         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16625                 error "dd failed for bs 4096 and count 5"
16626
16627         # Call fallocate with punch range which is within the file range
16628         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16629                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16630         # client must see changes immediately after fallocate
16631         size=$(stat -c '%s' $DIR/$tfile)
16632         blocks=$(stat -c '%b' $DIR/$tfile)
16633
16634         # Verify punch worked.
16635         (( blocks == want_blocks_after )) ||
16636                 error "punch failed: blocks $blocks != $want_blocks_after"
16637
16638         (( size == want_size_before )) ||
16639                 error "punch failed: size $size != $want_size_before"
16640
16641         # Verify there is hole in file
16642         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16643         # precomputed md5sum
16644         local expect="4a9a834a2db02452929c0a348273b4aa"
16645
16646         cksum=($(md5sum $DIR/$tfile))
16647         [[ "${cksum[0]}" == "$expect" ]] ||
16648                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16649
16650         # Start second sub-case for fallocate punch.
16651         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16652         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16653                 error "dd failed for bs 4096 and count 5"
16654
16655         # Punch range less than block size will have no change in block count
16656         want_blocks_after=40  # 512 sized blocks
16657
16658         # Punch overlaps two blocks and less than blocksize
16659         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16660                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16661         size=$(stat -c '%s' $DIR/$tfile)
16662         blocks=$(stat -c '%b' $DIR/$tfile)
16663
16664         # Verify punch worked.
16665         (( blocks == want_blocks_after )) ||
16666                 error "punch failed: blocks $blocks != $want_blocks_after"
16667
16668         (( size == want_size_before )) ||
16669                 error "punch failed: size $size != $want_size_before"
16670
16671         # Verify if range is really zero'ed out. We expect Zeros.
16672         # precomputed md5sum
16673         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16674         cksum=($(md5sum $DIR/$tfile))
16675         [[ "${cksum[0]}" == "$expect" ]] ||
16676                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16677 }
16678 run_test 150f "Verify fallocate punch functionality"
16679
16680 test_150g() {
16681         local space
16682         local size
16683         local blocks
16684         local blocks_after
16685         local size_after
16686         local BS=4096 # Block size in bytes
16687
16688         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16689                 skip "need at least 2.14.0 for fallocate punch"
16690
16691         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16692                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16693         fi
16694
16695         check_set_fallocate_or_skip
16696         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16697
16698         if [[ "x$DOM" == "xyes" ]]; then
16699                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16700                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16701         else
16702                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16703                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16704         fi
16705
16706         # Get 100MB per OST of the available space to reduce run time
16707         # else 60% of the available space if we are running SLOW tests
16708         if [ $SLOW == "no" ]; then
16709                 space=$((1024 * 100 * OSTCOUNT))
16710         else
16711                 # Find OST with Minimum Size
16712                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16713                         sort -un | head -1)
16714                 echo "min size OST: $space"
16715                 space=$(((space * 60)/100 * OSTCOUNT))
16716         fi
16717         # space in 1k units, round to 4k blocks
16718         local blkcount=$((space * 1024 / $BS))
16719
16720         echo "Verify fallocate punch: Very large Range"
16721         fallocate -l${space}k $DIR/$tfile ||
16722                 error "fallocate ${space}k $DIR/$tfile failed"
16723         # write 1M at the end, start and in the middle
16724         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16725                 error "dd failed: bs $BS count 256"
16726         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16727                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16728         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16729                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16730
16731         # Gather stats.
16732         size=$(stat -c '%s' $DIR/$tfile)
16733
16734         # gather punch length.
16735         local punch_size=$((size - (BS * 2)))
16736
16737         echo "punch_size = $punch_size"
16738         echo "size - punch_size: $((size - punch_size))"
16739         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16740
16741         # Call fallocate to punch all except 2 blocks. We leave the
16742         # first and the last block
16743         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16744         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16745                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16746
16747         size_after=$(stat -c '%s' $DIR/$tfile)
16748         blocks_after=$(stat -c '%b' $DIR/$tfile)
16749
16750         # Verify punch worked.
16751         # Size should be kept
16752         (( size == size_after )) ||
16753                 error "punch failed: size $size != $size_after"
16754
16755         # two 4k data blocks to remain plus possible 1 extra extent block
16756         (( blocks_after <= ((BS / 512) * 3) )) ||
16757                 error "too many blocks remains: $blocks_after"
16758
16759         # Verify that file has hole between the first and the last blocks
16760         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16761         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16762
16763         echo "Hole at [$hole_start, $hole_end)"
16764         (( hole_start == BS )) ||
16765                 error "no hole at offset $BS after punch"
16766
16767         (( hole_end == BS + punch_size )) ||
16768                 error "data at offset $hole_end < $((BS + punch_size))"
16769 }
16770 run_test 150g "Verify fallocate punch on large range"
16771
16772 test_150h() {
16773         local file=$DIR/$tfile
16774         local size
16775
16776         check_set_fallocate_or_skip
16777         statx_supported || skip_env "Test must be statx() syscall supported"
16778
16779         # fallocate() does not update the size information on the MDT
16780         fallocate -l 16K $file || error "failed to fallocate $file"
16781         cancel_lru_locks $OSC
16782         # STATX with cached-always mode will not send glimpse RPCs to OST,
16783         # it uses the caching attrs on the client side as much as possible.
16784         size=$($STATX --cached=always -c %s $file)
16785         [ $size == 16384 ] ||
16786                 error "size after fallocate() is $size, expected 16384"
16787 }
16788 run_test 150h "Verify extend fallocate updates the file size"
16789
16790 #LU-2902 roc_hit was not able to read all values from lproc
16791 function roc_hit_init() {
16792         local list=$(comma_list $(osts_nodes))
16793         local dir=$DIR/$tdir-check
16794         local file=$dir/$tfile
16795         local BEFORE
16796         local AFTER
16797         local idx
16798
16799         test_mkdir $dir
16800         #use setstripe to do a write to every ost
16801         for i in $(seq 0 $((OSTCOUNT-1))); do
16802                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16803                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16804                 idx=$(printf %04x $i)
16805                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16806                         awk '$1 == "cache_access" {sum += $7}
16807                                 END { printf("%0.0f", sum) }')
16808
16809                 cancel_lru_locks osc
16810                 cat $file >/dev/null
16811
16812                 AFTER=$(get_osd_param $list *OST*$idx stats |
16813                         awk '$1 == "cache_access" {sum += $7}
16814                                 END { printf("%0.0f", sum) }')
16815
16816                 echo BEFORE:$BEFORE AFTER:$AFTER
16817                 if ! let "AFTER - BEFORE == 4"; then
16818                         rm -rf $dir
16819                         error "roc_hit is not safe to use"
16820                 fi
16821                 rm $file
16822         done
16823
16824         rm -rf $dir
16825 }
16826
16827 function roc_hit() {
16828         local list=$(comma_list $(osts_nodes))
16829         echo $(get_osd_param $list '' stats |
16830                 awk '$1 == "cache_hit" {sum += $7}
16831                         END { printf("%0.0f", sum) }')
16832 }
16833
16834 function set_cache() {
16835         local on=1
16836
16837         if [ "$2" == "off" ]; then
16838                 on=0;
16839         fi
16840         local list=$(comma_list $(osts_nodes))
16841         set_osd_param $list '' $1_cache_enable $on
16842
16843         cancel_lru_locks osc
16844 }
16845
16846 test_151() {
16847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16848         remote_ost_nodsh && skip "remote OST with nodsh"
16849         (( CLIENT_VERSION == OST1_VERSION )) ||
16850                 skip "LU-13081: no interop testing for OSS cache"
16851
16852         local CPAGES=3
16853         local list=$(comma_list $(osts_nodes))
16854
16855         # check whether obdfilter is cache capable at all
16856         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16857                 skip "not cache-capable obdfilter"
16858         fi
16859
16860         # check cache is enabled on all obdfilters
16861         if get_osd_param $list '' read_cache_enable | grep 0; then
16862                 skip "oss cache is disabled"
16863         fi
16864
16865         set_osd_param $list '' writethrough_cache_enable 1
16866
16867         # check write cache is enabled on all obdfilters
16868         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16869                 skip "oss write cache is NOT enabled"
16870         fi
16871
16872         roc_hit_init
16873
16874         #define OBD_FAIL_OBD_NO_LRU  0x609
16875         do_nodes $list $LCTL set_param fail_loc=0x609
16876
16877         # pages should be in the case right after write
16878         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16879                 error "dd failed"
16880
16881         local BEFORE=$(roc_hit)
16882         cancel_lru_locks osc
16883         cat $DIR/$tfile >/dev/null
16884         local AFTER=$(roc_hit)
16885
16886         do_nodes $list $LCTL set_param fail_loc=0
16887
16888         if ! let "AFTER - BEFORE == CPAGES"; then
16889                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16890         fi
16891
16892         cancel_lru_locks osc
16893         # invalidates OST cache
16894         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16895         set_osd_param $list '' read_cache_enable 0
16896         cat $DIR/$tfile >/dev/null
16897
16898         # now data shouldn't be found in the cache
16899         BEFORE=$(roc_hit)
16900         cancel_lru_locks osc
16901         cat $DIR/$tfile >/dev/null
16902         AFTER=$(roc_hit)
16903         if let "AFTER - BEFORE != 0"; then
16904                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16905         fi
16906
16907         set_osd_param $list '' read_cache_enable 1
16908         rm -f $DIR/$tfile
16909 }
16910 run_test 151 "test cache on oss and controls ==============================="
16911
16912 test_152() {
16913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16914
16915         local TF="$TMP/$tfile"
16916
16917         # simulate ENOMEM during write
16918 #define OBD_FAIL_OST_NOMEM      0x226
16919         lctl set_param fail_loc=0x80000226
16920         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16921         cp $TF $DIR/$tfile
16922         sync || error "sync failed"
16923         lctl set_param fail_loc=0
16924
16925         # discard client's cache
16926         cancel_lru_locks osc
16927
16928         # simulate ENOMEM during read
16929         lctl set_param fail_loc=0x80000226
16930         cmp $TF $DIR/$tfile || error "cmp failed"
16931         lctl set_param fail_loc=0
16932
16933         rm -f $TF
16934 }
16935 run_test 152 "test read/write with enomem ============================"
16936
16937 test_153() {
16938         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16939 }
16940 run_test 153 "test if fdatasync does not crash ======================="
16941
16942 dot_lustre_fid_permission_check() {
16943         local fid=$1
16944         local ffid=$MOUNT/.lustre/fid/$fid
16945         local test_dir=$2
16946
16947         echo "stat fid $fid"
16948         stat $ffid || error "stat $ffid failed."
16949         echo "touch fid $fid"
16950         touch $ffid || error "touch $ffid failed."
16951         echo "write to fid $fid"
16952         cat /etc/hosts > $ffid || error "write $ffid failed."
16953         echo "read fid $fid"
16954         diff /etc/hosts $ffid || error "read $ffid failed."
16955         echo "append write to fid $fid"
16956         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16957         echo "rename fid $fid"
16958         mv $ffid $test_dir/$tfile.1 &&
16959                 error "rename $ffid to $tfile.1 should fail."
16960         touch $test_dir/$tfile.1
16961         mv $test_dir/$tfile.1 $ffid &&
16962                 error "rename $tfile.1 to $ffid should fail."
16963         rm -f $test_dir/$tfile.1
16964         echo "truncate fid $fid"
16965         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16966         echo "link fid $fid"
16967         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16968         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16969                 id $USER0 || skip_env "missing user $USER0"
16970                 echo "setfacl fid $fid"
16971                 setfacl -R -m u:$USER0:rwx $ffid ||
16972                         error "setfacl $ffid failed"
16973                 echo "getfacl fid $fid"
16974                 getfacl $ffid || error "getfacl $ffid failed."
16975         fi
16976         echo "unlink fid $fid"
16977         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16978         echo "mknod fid $fid"
16979         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16980
16981         fid=[0xf00000400:0x1:0x0]
16982         ffid=$MOUNT/.lustre/fid/$fid
16983
16984         echo "stat non-exist fid $fid"
16985         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16986         echo "write to non-exist fid $fid"
16987         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16988         echo "link new fid $fid"
16989         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16990
16991         mkdir -p $test_dir/$tdir
16992         touch $test_dir/$tdir/$tfile
16993         fid=$($LFS path2fid $test_dir/$tdir)
16994         rc=$?
16995         [ $rc -ne 0 ] &&
16996                 error "error: could not get fid for $test_dir/$dir/$tfile."
16997
16998         ffid=$MOUNT/.lustre/fid/$fid
16999
17000         echo "ls $fid"
17001         ls $ffid || error "ls $ffid failed."
17002         echo "touch $fid/$tfile.1"
17003         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
17004
17005         echo "touch $MOUNT/.lustre/fid/$tfile"
17006         touch $MOUNT/.lustre/fid/$tfile && \
17007                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
17008
17009         echo "setxattr to $MOUNT/.lustre/fid"
17010         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17011
17012         echo "listxattr for $MOUNT/.lustre/fid"
17013         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17014
17015         echo "delxattr from $MOUNT/.lustre/fid"
17016         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17017
17018         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17019         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17020                 error "touch invalid fid should fail."
17021
17022         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17023         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17024                 error "touch non-normal fid should fail."
17025
17026         echo "rename $tdir to $MOUNT/.lustre/fid"
17027         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17028                 error "rename to $MOUNT/.lustre/fid should fail."
17029
17030         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17031         then            # LU-3547
17032                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17033                 local new_obf_mode=777
17034
17035                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17036                 chmod $new_obf_mode $DIR/.lustre/fid ||
17037                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17038
17039                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17040                 [ $obf_mode -eq $new_obf_mode ] ||
17041                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17042
17043                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17044                 chmod $old_obf_mode $DIR/.lustre/fid ||
17045                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17046         fi
17047
17048         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17049         fid=$($LFS path2fid $test_dir/$tfile-2)
17050
17051         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17052         then # LU-5424
17053                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17054                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17055                         error "create lov data thru .lustre failed"
17056         fi
17057         echo "cp /etc/passwd $test_dir/$tfile-2"
17058         cp /etc/passwd $test_dir/$tfile-2 ||
17059                 error "copy to $test_dir/$tfile-2 failed."
17060         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17061         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17062                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17063
17064         rm -rf $test_dir/tfile.lnk
17065         rm -rf $test_dir/$tfile-2
17066 }
17067
17068 test_154A() {
17069         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17070                 skip "Need MDS version at least 2.4.1"
17071
17072         local tf=$DIR/$tfile
17073         touch $tf
17074
17075         local fid=$($LFS path2fid $tf)
17076         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17077
17078         # check that we get the same pathname back
17079         local rootpath
17080         local found
17081         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17082                 echo "$rootpath $fid"
17083                 found=$($LFS fid2path $rootpath "$fid")
17084                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17085                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17086         done
17087
17088         # check wrong root path format
17089         rootpath=$MOUNT"_wrong"
17090         found=$($LFS fid2path $rootpath "$fid")
17091         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17092 }
17093 run_test 154A "lfs path2fid and fid2path basic checks"
17094
17095 test_154B() {
17096         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17097                 skip "Need MDS version at least 2.4.1"
17098
17099         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17100         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17101         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17102         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17103
17104         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17105         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17106
17107         # check that we get the same pathname
17108         echo "PFID: $PFID, name: $name"
17109         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17110         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17111         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17112                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17113
17114         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17115 }
17116 run_test 154B "verify the ll_decode_linkea tool"
17117
17118 test_154a() {
17119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17120         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17121         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17122                 skip "Need MDS version at least 2.2.51"
17123         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17124
17125         cp /etc/hosts $DIR/$tfile
17126
17127         fid=$($LFS path2fid $DIR/$tfile)
17128         rc=$?
17129         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17130
17131         dot_lustre_fid_permission_check "$fid" $DIR ||
17132                 error "dot lustre permission check $fid failed"
17133
17134         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17135
17136         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17137
17138         touch $MOUNT/.lustre/file &&
17139                 error "creation is not allowed under .lustre"
17140
17141         mkdir $MOUNT/.lustre/dir &&
17142                 error "mkdir is not allowed under .lustre"
17143
17144         rm -rf $DIR/$tfile
17145 }
17146 run_test 154a "Open-by-FID"
17147
17148 test_154b() {
17149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17150         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17151         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17152         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17153                 skip "Need MDS version at least 2.2.51"
17154
17155         local remote_dir=$DIR/$tdir/remote_dir
17156         local MDTIDX=1
17157         local rc=0
17158
17159         mkdir -p $DIR/$tdir
17160         $LFS mkdir -i $MDTIDX $remote_dir ||
17161                 error "create remote directory failed"
17162
17163         cp /etc/hosts $remote_dir/$tfile
17164
17165         fid=$($LFS path2fid $remote_dir/$tfile)
17166         rc=$?
17167         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17168
17169         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17170                 error "dot lustre permission check $fid failed"
17171         rm -rf $DIR/$tdir
17172 }
17173 run_test 154b "Open-by-FID for remote directory"
17174
17175 test_154c() {
17176         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17177                 skip "Need MDS version at least 2.4.1"
17178
17179         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17180         local FID1=$($LFS path2fid $DIR/$tfile.1)
17181         local FID2=$($LFS path2fid $DIR/$tfile.2)
17182         local FID3=$($LFS path2fid $DIR/$tfile.3)
17183
17184         local N=1
17185         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17186                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17187                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17188                 local want=FID$N
17189                 [ "$FID" = "${!want}" ] ||
17190                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17191                 N=$((N + 1))
17192         done
17193
17194         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17195         do
17196                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17197                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17198                 N=$((N + 1))
17199         done
17200 }
17201 run_test 154c "lfs path2fid and fid2path multiple arguments"
17202
17203 test_154d() {
17204         remote_mds_nodsh && skip "remote MDS with nodsh"
17205         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17206                 skip "Need MDS version at least 2.5.53"
17207
17208         if remote_mds; then
17209                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17210         else
17211                 nid="0@lo"
17212         fi
17213         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17214         local fd
17215         local cmd
17216
17217         rm -f $DIR/$tfile
17218         touch $DIR/$tfile
17219
17220         local fid=$($LFS path2fid $DIR/$tfile)
17221         # Open the file
17222         fd=$(free_fd)
17223         cmd="exec $fd<$DIR/$tfile"
17224         eval $cmd
17225         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17226         echo "$fid_list" | grep "$fid"
17227         rc=$?
17228
17229         cmd="exec $fd>/dev/null"
17230         eval $cmd
17231         if [ $rc -ne 0 ]; then
17232                 error "FID $fid not found in open files list $fid_list"
17233         fi
17234 }
17235 run_test 154d "Verify open file fid"
17236
17237 test_154e()
17238 {
17239         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17240                 skip "Need MDS version at least 2.6.50"
17241
17242         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17243                 error ".lustre returned by readdir"
17244         fi
17245 }
17246 run_test 154e ".lustre is not returned by readdir"
17247
17248 test_154f() {
17249         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17250
17251         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17252         mkdir_on_mdt0 $DIR/$tdir
17253         # test dirs inherit from its stripe
17254         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17255         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17256         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17257         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17258         touch $DIR/f
17259
17260         # get fid of parents
17261         local FID0=$($LFS path2fid $DIR/$tdir)
17262         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17263         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17264         local FID3=$($LFS path2fid $DIR)
17265
17266         # check that path2fid --parents returns expected <parent_fid>/name
17267         # 1) test for a directory (single parent)
17268         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17269         [ "$parent" == "$FID0/foo1" ] ||
17270                 error "expected parent: $FID0/foo1, got: $parent"
17271
17272         # 2) test for a file with nlink > 1 (multiple parents)
17273         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17274         echo "$parent" | grep -F "$FID1/$tfile" ||
17275                 error "$FID1/$tfile not returned in parent list"
17276         echo "$parent" | grep -F "$FID2/link" ||
17277                 error "$FID2/link not returned in parent list"
17278
17279         # 3) get parent by fid
17280         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17281         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17282         echo "$parent" | grep -F "$FID1/$tfile" ||
17283                 error "$FID1/$tfile not returned in parent list (by fid)"
17284         echo "$parent" | grep -F "$FID2/link" ||
17285                 error "$FID2/link not returned in parent list (by fid)"
17286
17287         # 4) test for entry in root directory
17288         parent=$($LFS path2fid --parents $DIR/f)
17289         echo "$parent" | grep -F "$FID3/f" ||
17290                 error "$FID3/f not returned in parent list"
17291
17292         # 5) test it on root directory
17293         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17294                 error "$MOUNT should not have parents"
17295
17296         # enable xattr caching and check that linkea is correctly updated
17297         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17298         save_lustre_params client "llite.*.xattr_cache" > $save
17299         lctl set_param llite.*.xattr_cache 1
17300
17301         # 6.1) linkea update on rename
17302         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17303
17304         # get parents by fid
17305         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17306         # foo1 should no longer be returned in parent list
17307         echo "$parent" | grep -F "$FID1" &&
17308                 error "$FID1 should no longer be in parent list"
17309         # the new path should appear
17310         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17311                 error "$FID2/$tfile.moved is not in parent list"
17312
17313         # 6.2) linkea update on unlink
17314         rm -f $DIR/$tdir/foo2/link
17315         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17316         # foo2/link should no longer be returned in parent list
17317         echo "$parent" | grep -F "$FID2/link" &&
17318                 error "$FID2/link should no longer be in parent list"
17319         true
17320
17321         rm -f $DIR/f
17322         restore_lustre_params < $save
17323         rm -f $save
17324 }
17325 run_test 154f "get parent fids by reading link ea"
17326
17327 test_154g()
17328 {
17329         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17330            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17331                 skip "Need MDS version at least 2.6.92"
17332
17333         mkdir_on_mdt0 $DIR/$tdir
17334         llapi_fid_test -d $DIR/$tdir
17335 }
17336 run_test 154g "various llapi FID tests"
17337
17338 test_154h()
17339 {
17340         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17341                 skip "Need client at least version 2.15.55.1"
17342
17343         # Create an empty file
17344         touch $DIR/$tfile
17345
17346         # Get FID (interactive mode) and save under $TMP/$tfile.log
17347         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17348                 path2fid $DIR/$tfile
17349         EOF
17350
17351         fid=$(cat $TMP/$tfile.log)
17352         # $fid should not be empty
17353         [[ ! -z $fid ]] || error "FID is empty"
17354         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17355 }
17356 run_test 154h "Verify interactive path2fid"
17357
17358 test_155_small_load() {
17359     local temp=$TMP/$tfile
17360     local file=$DIR/$tfile
17361
17362     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17363         error "dd of=$temp bs=6096 count=1 failed"
17364     cp $temp $file
17365     cancel_lru_locks $OSC
17366     cmp $temp $file || error "$temp $file differ"
17367
17368     $TRUNCATE $temp 6000
17369     $TRUNCATE $file 6000
17370     cmp $temp $file || error "$temp $file differ (truncate1)"
17371
17372     echo "12345" >>$temp
17373     echo "12345" >>$file
17374     cmp $temp $file || error "$temp $file differ (append1)"
17375
17376     echo "12345" >>$temp
17377     echo "12345" >>$file
17378     cmp $temp $file || error "$temp $file differ (append2)"
17379
17380     rm -f $temp $file
17381     true
17382 }
17383
17384 test_155_big_load() {
17385         remote_ost_nodsh && skip "remote OST with nodsh"
17386
17387         local temp=$TMP/$tfile
17388         local file=$DIR/$tfile
17389
17390         free_min_max
17391         local cache_size=$(do_facet ost$((MAXI+1)) \
17392                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17393
17394         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17395         # pre-set value
17396         if [ -z "$cache_size" ]; then
17397                 cache_size=256
17398         fi
17399         local large_file_size=$((cache_size * 2))
17400
17401         echo "OSS cache size: $cache_size KB"
17402         echo "Large file size: $large_file_size KB"
17403
17404         [ $MAXV -le $large_file_size ] &&
17405                 skip_env "max available OST size needs > $large_file_size KB"
17406
17407         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17408
17409         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17410                 error "dd of=$temp bs=$large_file_size count=1k failed"
17411         cp $temp $file
17412         ls -lh $temp $file
17413         cancel_lru_locks osc
17414         cmp $temp $file || error "$temp $file differ"
17415
17416         rm -f $temp $file
17417         true
17418 }
17419
17420 save_writethrough() {
17421         local facets=$(get_facets OST)
17422
17423         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17424 }
17425
17426 test_155a() {
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 on
17435         test_155_small_load
17436         restore_lustre_params < $p
17437         rm -f $p
17438 }
17439 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17440
17441 test_155b() {
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 on
17449         set_cache writethrough off
17450         test_155_small_load
17451         restore_lustre_params < $p
17452         rm -f $p
17453 }
17454 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17455
17456 test_155c() {
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 on
17465         test_155_small_load
17466         restore_lustre_params < $p
17467         rm -f $p
17468 }
17469 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17470
17471 test_155d() {
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 off
17479         set_cache writethrough off
17480         test_155_small_load
17481         restore_lustre_params < $p
17482         rm -f $p
17483 }
17484 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17485
17486 test_155e() {
17487         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17488
17489         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17490
17491         save_writethrough $p
17492
17493         set_cache read on
17494         set_cache writethrough on
17495         test_155_big_load
17496         restore_lustre_params < $p
17497         rm -f $p
17498 }
17499 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17500
17501 test_155f() {
17502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17503
17504         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17505
17506         save_writethrough $p
17507
17508         set_cache read on
17509         set_cache writethrough off
17510         test_155_big_load
17511         restore_lustre_params < $p
17512         rm -f $p
17513 }
17514 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17515
17516 test_155g() {
17517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17518
17519         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17520
17521         save_writethrough $p
17522
17523         set_cache read off
17524         set_cache writethrough on
17525         test_155_big_load
17526         restore_lustre_params < $p
17527         rm -f $p
17528 }
17529 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17530
17531 test_155h() {
17532         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17533
17534         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17535
17536         save_writethrough $p
17537
17538         set_cache read off
17539         set_cache writethrough off
17540         test_155_big_load
17541         restore_lustre_params < $p
17542         rm -f $p
17543 }
17544 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17545
17546 test_156() {
17547         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17548         remote_ost_nodsh && skip "remote OST with nodsh"
17549         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17550                 skip "stats not implemented on old servers"
17551         [ "$ost1_FSTYPE" = "zfs" ] &&
17552                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17553         (( CLIENT_VERSION == OST1_VERSION )) ||
17554                 skip "LU-13081: no interop testing for OSS cache"
17555
17556         local CPAGES=3
17557         local BEFORE
17558         local AFTER
17559         local file="$DIR/$tfile"
17560         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17561
17562         save_writethrough $p
17563         roc_hit_init
17564
17565         log "Turn on read and write cache"
17566         set_cache read on
17567         set_cache writethrough on
17568
17569         log "Write data and read it back."
17570         log "Read should be satisfied from the cache."
17571         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17572         BEFORE=$(roc_hit)
17573         cancel_lru_locks osc
17574         cat $file >/dev/null
17575         AFTER=$(roc_hit)
17576         if ! let "AFTER - BEFORE == CPAGES"; then
17577                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17578         else
17579                 log "cache hits: before: $BEFORE, after: $AFTER"
17580         fi
17581
17582         log "Read again; it should be satisfied from the cache."
17583         BEFORE=$AFTER
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 (3): before: $BEFORE, after: $AFTER"
17589         else
17590                 log "cache hits:: before: $BEFORE, after: $AFTER"
17591         fi
17592
17593         log "Turn off the read cache and turn on the write cache"
17594         set_cache read off
17595         set_cache writethrough on
17596
17597         log "Read again; it should be satisfied from the cache."
17598         BEFORE=$(roc_hit)
17599         cancel_lru_locks osc
17600         cat $file >/dev/null
17601         AFTER=$(roc_hit)
17602         if ! let "AFTER - BEFORE == CPAGES"; then
17603                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17604         else
17605                 log "cache hits:: before: $BEFORE, after: $AFTER"
17606         fi
17607
17608         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17609                 # > 2.12.56 uses pagecache if cached
17610                 log "Read again; it should not be satisfied from the cache."
17611                 BEFORE=$AFTER
17612                 cancel_lru_locks osc
17613                 cat $file >/dev/null
17614                 AFTER=$(roc_hit)
17615                 if ! let "AFTER - BEFORE == 0"; then
17616                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17617                 else
17618                         log "cache hits:: before: $BEFORE, after: $AFTER"
17619                 fi
17620         fi
17621
17622         log "Write data and read it back."
17623         log "Read should be satisfied from the cache."
17624         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17625         BEFORE=$(roc_hit)
17626         cancel_lru_locks osc
17627         cat $file >/dev/null
17628         AFTER=$(roc_hit)
17629         if ! let "AFTER - BEFORE == CPAGES"; then
17630                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17631         else
17632                 log "cache hits:: before: $BEFORE, after: $AFTER"
17633         fi
17634
17635         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17636                 # > 2.12.56 uses pagecache if cached
17637                 log "Read again; it should not be satisfied from the cache."
17638                 BEFORE=$AFTER
17639                 cancel_lru_locks osc
17640                 cat $file >/dev/null
17641                 AFTER=$(roc_hit)
17642                 if ! let "AFTER - BEFORE == 0"; then
17643                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17644                 else
17645                         log "cache hits:: before: $BEFORE, after: $AFTER"
17646                 fi
17647         fi
17648
17649         log "Turn off read and write cache"
17650         set_cache read off
17651         set_cache writethrough off
17652
17653         log "Write data and read it back"
17654         log "It should not be satisfied from the cache."
17655         rm -f $file
17656         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17657         cancel_lru_locks osc
17658         BEFORE=$(roc_hit)
17659         cat $file >/dev/null
17660         AFTER=$(roc_hit)
17661         if ! let "AFTER - BEFORE == 0"; then
17662                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17663         else
17664                 log "cache hits:: before: $BEFORE, after: $AFTER"
17665         fi
17666
17667         log "Turn on the read cache and turn off the write cache"
17668         set_cache read on
17669         set_cache writethrough off
17670
17671         log "Write data and read it back"
17672         log "It should not be satisfied from the cache."
17673         rm -f $file
17674         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17675         BEFORE=$(roc_hit)
17676         cancel_lru_locks osc
17677         cat $file >/dev/null
17678         AFTER=$(roc_hit)
17679         if ! let "AFTER - BEFORE == 0"; then
17680                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17681         else
17682                 log "cache hits:: before: $BEFORE, after: $AFTER"
17683         fi
17684
17685         log "Read again; it should be satisfied from the cache."
17686         BEFORE=$(roc_hit)
17687         cancel_lru_locks osc
17688         cat $file >/dev/null
17689         AFTER=$(roc_hit)
17690         if ! let "AFTER - BEFORE == CPAGES"; then
17691                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17692         else
17693                 log "cache hits:: before: $BEFORE, after: $AFTER"
17694         fi
17695
17696         restore_lustre_params < $p
17697         rm -f $p $file
17698 }
17699 run_test 156 "Verification of tunables"
17700
17701 test_160a() {
17702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17703         remote_mds_nodsh && skip "remote MDS with nodsh"
17704         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17705                 skip "Need MDS version at least 2.2.0"
17706
17707         changelog_register || error "changelog_register failed"
17708         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17709         changelog_users $SINGLEMDS | grep -q $cl_user ||
17710                 error "User $cl_user not found in changelog_users"
17711
17712         mkdir_on_mdt0 $DIR/$tdir
17713
17714         # change something
17715         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17716         changelog_clear 0 || error "changelog_clear failed"
17717         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17718         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17719         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17720         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17721         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17722         rm $DIR/$tdir/pics/desktop.jpg
17723
17724         echo "verifying changelog mask"
17725         changelog_chmask "-MKDIR"
17726         changelog_chmask "-CLOSE"
17727
17728         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17729         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17730
17731         changelog_chmask "+MKDIR"
17732         changelog_chmask "+CLOSE"
17733
17734         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17735         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17736
17737         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17738         CLOSES=$(changelog_dump | grep -c "CLOSE")
17739         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17740         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17741
17742         # verify contents
17743         echo "verifying target fid"
17744         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17745         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17746         [ "$fidc" == "$fidf" ] ||
17747                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17748         echo "verifying parent fid"
17749         # The FID returned from the Changelog may be the directory shard on
17750         # a different MDT, and not the FID returned by path2fid on the parent.
17751         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17752         # since this is what will matter when recreating this file in the tree.
17753         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17754         local pathp=$($LFS fid2path $MOUNT "$fidp")
17755         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17756                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17757
17758         echo "getting records for $cl_user"
17759         changelog_users $SINGLEMDS
17760         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17761         local nclr=3
17762         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17763                 error "changelog_clear failed"
17764         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17765         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17766         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17767                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17768
17769         local min0_rec=$(changelog_users $SINGLEMDS |
17770                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17771         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17772                           awk '{ print $1; exit; }')
17773
17774         changelog_dump | tail -n 5
17775         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17776         [ $first_rec == $((min0_rec + 1)) ] ||
17777                 error "first index should be $min0_rec + 1 not $first_rec"
17778
17779         # LU-3446 changelog index reset on MDT restart
17780         local cur_rec1=$(changelog_users $SINGLEMDS |
17781                          awk '/^current.index:/ { print $NF }')
17782         changelog_clear 0 ||
17783                 error "clear all changelog records for $cl_user failed"
17784         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17785         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17786                 error "Fail to start $SINGLEMDS"
17787         local cur_rec2=$(changelog_users $SINGLEMDS |
17788                          awk '/^current.index:/ { print $NF }')
17789         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17790         [ $cur_rec1 == $cur_rec2 ] ||
17791                 error "current index should be $cur_rec1 not $cur_rec2"
17792
17793         echo "verifying users from this test are deregistered"
17794         changelog_deregister || error "changelog_deregister failed"
17795         changelog_users $SINGLEMDS | grep -q $cl_user &&
17796                 error "User '$cl_user' still in changelog_users"
17797
17798         # lctl get_param -n mdd.*.changelog_users
17799         # current_index: 144
17800         # ID    index (idle seconds)
17801         # cl3   144   (2) mask=<list>
17802         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17803                 # this is the normal case where all users were deregistered
17804                 # make sure no new records are added when no users are present
17805                 local last_rec1=$(changelog_users $SINGLEMDS |
17806                                   awk '/^current.index:/ { print $NF }')
17807                 touch $DIR/$tdir/chloe
17808                 local last_rec2=$(changelog_users $SINGLEMDS |
17809                                   awk '/^current.index:/ { print $NF }')
17810                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17811                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17812         else
17813                 # any changelog users must be leftovers from a previous test
17814                 changelog_users $SINGLEMDS
17815                 echo "other changelog users; can't verify off"
17816         fi
17817 }
17818 run_test 160a "changelog sanity"
17819
17820 test_160b() { # LU-3587
17821         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17822         remote_mds_nodsh && skip "remote MDS with nodsh"
17823         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17824                 skip "Need MDS version at least 2.2.0"
17825
17826         changelog_register || error "changelog_register failed"
17827         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17828         changelog_users $SINGLEMDS | grep -q $cl_user ||
17829                 error "User '$cl_user' not found in changelog_users"
17830
17831         local longname1=$(str_repeat a 255)
17832         local longname2=$(str_repeat b 255)
17833
17834         cd $DIR
17835         echo "creating very long named file"
17836         touch $longname1 || error "create of '$longname1' failed"
17837         echo "renaming very long named file"
17838         mv $longname1 $longname2
17839
17840         changelog_dump | grep RENME | tail -n 5
17841         rm -f $longname2
17842 }
17843 run_test 160b "Verify that very long rename doesn't crash in changelog"
17844
17845 test_160c() {
17846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17847         remote_mds_nodsh && skip "remote MDS with nodsh"
17848
17849         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17850                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17851                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17852                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17853
17854         local rc=0
17855
17856         # Registration step
17857         changelog_register || error "changelog_register failed"
17858
17859         rm -rf $DIR/$tdir
17860         mkdir -p $DIR/$tdir
17861         $MCREATE $DIR/$tdir/foo_160c
17862         changelog_chmask "-TRUNC"
17863         $TRUNCATE $DIR/$tdir/foo_160c 200
17864         changelog_chmask "+TRUNC"
17865         $TRUNCATE $DIR/$tdir/foo_160c 199
17866         changelog_dump | tail -n 5
17867         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17868         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17869 }
17870 run_test 160c "verify that changelog log catch the truncate event"
17871
17872 test_160d() {
17873         remote_mds_nodsh && skip "remote MDS with nodsh"
17874         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17876         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17877                 skip "Need MDS version at least 2.7.60"
17878
17879         # Registration step
17880         changelog_register || error "changelog_register failed"
17881
17882         mkdir -p $DIR/$tdir/migrate_dir
17883         changelog_clear 0 || error "changelog_clear failed"
17884
17885         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17886         changelog_dump | tail -n 5
17887         local migrates=$(changelog_dump | grep -c "MIGRT")
17888         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17889 }
17890 run_test 160d "verify that changelog log catch the migrate event"
17891
17892 test_160e() {
17893         remote_mds_nodsh && skip "remote MDS with nodsh"
17894
17895         # Create a user
17896         changelog_register || error "changelog_register failed"
17897
17898         local MDT0=$(facet_svc $SINGLEMDS)
17899         local rc
17900
17901         # No user (expect fail)
17902         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17903         rc=$?
17904         if [ $rc -eq 0 ]; then
17905                 error "Should fail without user"
17906         elif [ $rc -ne 4 ]; then
17907                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17908         fi
17909
17910         # Delete a future user (expect fail)
17911         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17912         rc=$?
17913         if [ $rc -eq 0 ]; then
17914                 error "Deleted non-existant user cl77"
17915         elif [ $rc -ne 2 ]; then
17916                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17917         fi
17918
17919         # Clear to a bad index (1 billion should be safe)
17920         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17921         rc=$?
17922
17923         if [ $rc -eq 0 ]; then
17924                 error "Successfully cleared to invalid CL index"
17925         elif [ $rc -ne 22 ]; then
17926                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17927         fi
17928 }
17929 run_test 160e "changelog negative testing (should return errors)"
17930
17931 test_160f() {
17932         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17933         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17934                 skip "Need MDS version at least 2.10.56"
17935
17936         local mdts=$(comma_list $(mdts_nodes))
17937
17938         # Create a user
17939         changelog_register || error "first changelog_register failed"
17940         changelog_register || error "second changelog_register failed"
17941         local cl_users
17942         declare -A cl_user1
17943         declare -A cl_user2
17944         local user_rec1
17945         local user_rec2
17946         local i
17947
17948         # generate some changelog records to accumulate on each MDT
17949         # use all_char because created files should be evenly distributed
17950         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17951                 error "test_mkdir $tdir failed"
17952         log "$(date +%s): creating first files"
17953         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17954                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17955                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17956         done
17957
17958         # check changelogs have been generated
17959         local start=$SECONDS
17960         local idle_time=$((MDSCOUNT * 5 + 5))
17961         local nbcl=$(changelog_dump | wc -l)
17962         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17963
17964         for param in "changelog_max_idle_time=$idle_time" \
17965                      "changelog_gc=1" \
17966                      "changelog_min_gc_interval=2" \
17967                      "changelog_min_free_cat_entries=3"; do
17968                 local MDT0=$(facet_svc $SINGLEMDS)
17969                 local var="${param%=*}"
17970                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17971
17972                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17973                 do_nodes $mdts $LCTL set_param mdd.*.$param
17974         done
17975
17976         # force cl_user2 to be idle (1st part), but also cancel the
17977         # cl_user1 records so that it is not evicted later in the test.
17978         local sleep1=$((idle_time / 2))
17979         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17980         sleep $sleep1
17981
17982         # simulate changelog catalog almost full
17983         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17984         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17985
17986         for i in $(seq $MDSCOUNT); do
17987                 cl_users=(${CL_USERS[mds$i]})
17988                 cl_user1[mds$i]="${cl_users[0]}"
17989                 cl_user2[mds$i]="${cl_users[1]}"
17990
17991                 [ -n "${cl_user1[mds$i]}" ] ||
17992                         error "mds$i: no user registered"
17993                 [ -n "${cl_user2[mds$i]}" ] ||
17994                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17995
17996                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17997                 [ -n "$user_rec1" ] ||
17998                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17999                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18000                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18001                 [ -n "$user_rec2" ] ||
18002                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18003                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18004                      "$user_rec1 + 2 == $user_rec2"
18005                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18006                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18007                               "$user_rec1 + 2, but is $user_rec2"
18008                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18009                 [ -n "$user_rec2" ] ||
18010                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18011                 [ $user_rec1 == $user_rec2 ] ||
18012                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18013                               "$user_rec1, but is $user_rec2"
18014         done
18015
18016         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18017         local sleep2=$((idle_time - (SECONDS - start) + 1))
18018         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18019         sleep $sleep2
18020
18021         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18022         # cl_user1 should be OK because it recently processed records.
18023         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18024         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18025                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18026                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18027         done
18028
18029         # ensure gc thread is done
18030         for i in $(mdts_nodes); do
18031                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18032                         error "$i: GC-thread not done"
18033         done
18034
18035         local first_rec
18036         for (( i = 1; i <= MDSCOUNT; i++ )); do
18037                 # check cl_user1 still registered
18038                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18039                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18040                 # check cl_user2 unregistered
18041                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18042                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18043
18044                 # check changelogs are present and starting at $user_rec1 + 1
18045                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18046                 [ -n "$user_rec1" ] ||
18047                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18048                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18049                             awk '{ print $1; exit; }')
18050
18051                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18052                 [ $((user_rec1 + 1)) == $first_rec ] ||
18053                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18054         done
18055 }
18056 run_test 160f "changelog garbage collect (timestamped users)"
18057
18058 test_160g() {
18059         remote_mds_nodsh && skip "remote MDS with nodsh"
18060         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18061                 skip "Need MDS version at least 2.14.55"
18062
18063         local mdts=$(comma_list $(mdts_nodes))
18064
18065         # Create a user
18066         changelog_register || error "first changelog_register failed"
18067         changelog_register || error "second changelog_register failed"
18068         local cl_users
18069         declare -A cl_user1
18070         declare -A cl_user2
18071         local user_rec1
18072         local user_rec2
18073         local i
18074
18075         # generate some changelog records to accumulate on each MDT
18076         # use all_char because created files should be evenly distributed
18077         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18078                 error "test_mkdir $tdir failed"
18079         for ((i = 0; i < MDSCOUNT; i++)); do
18080                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18081                         error "create $DIR/$tdir/d$i.1 failed"
18082         done
18083
18084         # check changelogs have been generated
18085         local nbcl=$(changelog_dump | wc -l)
18086         (( $nbcl > 0 )) || error "no changelogs found"
18087
18088         # reduce the max_idle_indexes value to make sure we exceed it
18089         for param in "changelog_max_idle_indexes=2" \
18090                      "changelog_gc=1" \
18091                      "changelog_min_gc_interval=2"; do
18092                 local MDT0=$(facet_svc $SINGLEMDS)
18093                 local var="${param%=*}"
18094                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18095
18096                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18097                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18098                         error "unable to set mdd.*.$param"
18099         done
18100
18101         local start=$SECONDS
18102         for i in $(seq $MDSCOUNT); do
18103                 cl_users=(${CL_USERS[mds$i]})
18104                 cl_user1[mds$i]="${cl_users[0]}"
18105                 cl_user2[mds$i]="${cl_users[1]}"
18106
18107                 [ -n "${cl_user1[mds$i]}" ] ||
18108                         error "mds$i: user1 is not registered"
18109                 [ -n "${cl_user2[mds$i]}" ] ||
18110                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18111
18112                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18113                 [ -n "$user_rec1" ] ||
18114                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18115                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18116                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18117                 [ -n "$user_rec2" ] ||
18118                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18119                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18120                      "$user_rec1 + 2 == $user_rec2"
18121                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18122                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18123                               "expected $user_rec1 + 2, but is $user_rec2"
18124                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18125                 [ -n "$user_rec2" ] ||
18126                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18127                 [ $user_rec1 == $user_rec2 ] ||
18128                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18129                               "expected $user_rec1, but is $user_rec2"
18130         done
18131
18132         # ensure we are past the previous changelog_min_gc_interval set above
18133         local sleep2=$((start + 2 - SECONDS))
18134         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18135         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18136         # cl_user1 should be OK because it recently processed records.
18137         for ((i = 0; i < MDSCOUNT; i++)); do
18138                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18139                         error "create $DIR/$tdir/d$i.3 failed"
18140         done
18141
18142         # ensure gc thread is done
18143         for i in $(mdts_nodes); do
18144                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18145                         error "$i: GC-thread not done"
18146         done
18147
18148         local first_rec
18149         for (( i = 1; i <= MDSCOUNT; i++ )); do
18150                 # check cl_user1 still registered
18151                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18152                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18153                 # check cl_user2 unregistered
18154                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18155                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18156
18157                 # check changelogs are present and starting at $user_rec1 + 1
18158                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18159                 [ -n "$user_rec1" ] ||
18160                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18161                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18162                             awk '{ print $1; exit; }')
18163
18164                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18165                 [ $((user_rec1 + 1)) == $first_rec ] ||
18166                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18167         done
18168 }
18169 run_test 160g "changelog garbage collect on idle records"
18170
18171 test_160h() {
18172         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18173         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18174                 skip "Need MDS version at least 2.10.56"
18175
18176         local mdts=$(comma_list $(mdts_nodes))
18177
18178         # Create a user
18179         changelog_register || error "first changelog_register failed"
18180         changelog_register || error "second changelog_register failed"
18181         local cl_users
18182         declare -A cl_user1
18183         declare -A cl_user2
18184         local user_rec1
18185         local user_rec2
18186         local i
18187
18188         # generate some changelog records to accumulate on each MDT
18189         # use all_char because created files should be evenly distributed
18190         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18191                 error "test_mkdir $tdir failed"
18192         for ((i = 0; i < MDSCOUNT; i++)); do
18193                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18194                         error "create $DIR/$tdir/d$i.1 failed"
18195         done
18196
18197         # check changelogs have been generated
18198         local nbcl=$(changelog_dump | wc -l)
18199         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18200
18201         for param in "changelog_max_idle_time=10" \
18202                      "changelog_gc=1" \
18203                      "changelog_min_gc_interval=2"; do
18204                 local MDT0=$(facet_svc $SINGLEMDS)
18205                 local var="${param%=*}"
18206                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18207
18208                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18209                 do_nodes $mdts $LCTL set_param mdd.*.$param
18210         done
18211
18212         # force cl_user2 to be idle (1st part)
18213         sleep 9
18214
18215         for i in $(seq $MDSCOUNT); do
18216                 cl_users=(${CL_USERS[mds$i]})
18217                 cl_user1[mds$i]="${cl_users[0]}"
18218                 cl_user2[mds$i]="${cl_users[1]}"
18219
18220                 [ -n "${cl_user1[mds$i]}" ] ||
18221                         error "mds$i: no user registered"
18222                 [ -n "${cl_user2[mds$i]}" ] ||
18223                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18224
18225                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18226                 [ -n "$user_rec1" ] ||
18227                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18228                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18229                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18230                 [ -n "$user_rec2" ] ||
18231                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18232                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18233                      "$user_rec1 + 2 == $user_rec2"
18234                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18235                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18236                               "$user_rec1 + 2, but is $user_rec2"
18237                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18238                 [ -n "$user_rec2" ] ||
18239                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18240                 [ $user_rec1 == $user_rec2 ] ||
18241                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18242                               "$user_rec1, but is $user_rec2"
18243         done
18244
18245         # force cl_user2 to be idle (2nd part) and to reach
18246         # changelog_max_idle_time
18247         sleep 2
18248
18249         # force each GC-thread start and block then
18250         # one per MDT/MDD, set fail_val accordingly
18251         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18252         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18253
18254         # generate more changelogs to trigger fail_loc
18255         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18256                 error "create $DIR/$tdir/${tfile}bis failed"
18257
18258         # stop MDT to stop GC-thread, should be done in back-ground as it will
18259         # block waiting for the thread to be released and exit
18260         declare -A stop_pids
18261         for i in $(seq $MDSCOUNT); do
18262                 stop mds$i &
18263                 stop_pids[mds$i]=$!
18264         done
18265
18266         for i in $(mdts_nodes); do
18267                 local facet
18268                 local nb=0
18269                 local facets=$(facets_up_on_host $i)
18270
18271                 for facet in ${facets//,/ }; do
18272                         if [[ $facet == mds* ]]; then
18273                                 nb=$((nb + 1))
18274                         fi
18275                 done
18276                 # ensure each MDS's gc threads are still present and all in "R"
18277                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18278                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18279                         error "$i: expected $nb GC-thread"
18280                 wait_update $i \
18281                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18282                         "R" 20 ||
18283                         error "$i: GC-thread not found in R-state"
18284                 # check umounts of each MDT on MDS have reached kthread_stop()
18285                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18286                         error "$i: expected $nb umount"
18287                 wait_update $i \
18288                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18289                         error "$i: umount not found in D-state"
18290         done
18291
18292         # release all GC-threads
18293         do_nodes $mdts $LCTL set_param fail_loc=0
18294
18295         # wait for MDT stop to complete
18296         for i in $(seq $MDSCOUNT); do
18297                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18298         done
18299
18300         # XXX
18301         # may try to check if any orphan changelog records are present
18302         # via ldiskfs/zfs and llog_reader...
18303
18304         # re-start/mount MDTs
18305         for i in $(seq $MDSCOUNT); do
18306                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18307                         error "Fail to start mds$i"
18308         done
18309
18310         local first_rec
18311         for i in $(seq $MDSCOUNT); do
18312                 # check cl_user1 still registered
18313                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18314                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18315                 # check cl_user2 unregistered
18316                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18317                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18318
18319                 # check changelogs are present and starting at $user_rec1 + 1
18320                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18321                 [ -n "$user_rec1" ] ||
18322                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18323                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18324                             awk '{ print $1; exit; }')
18325
18326                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18327                 [ $((user_rec1 + 1)) == $first_rec ] ||
18328                         error "mds$i: first index should be $user_rec1 + 1, " \
18329                               "but is $first_rec"
18330         done
18331 }
18332 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18333               "during mount"
18334
18335 test_160i() {
18336
18337         local mdts=$(comma_list $(mdts_nodes))
18338
18339         changelog_register || error "first changelog_register failed"
18340
18341         # generate some changelog records to accumulate on each MDT
18342         # use all_char because created files should be evenly distributed
18343         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18344                 error "test_mkdir $tdir failed"
18345         for ((i = 0; i < MDSCOUNT; i++)); do
18346                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18347                         error "create $DIR/$tdir/d$i.1 failed"
18348         done
18349
18350         # check changelogs have been generated
18351         local nbcl=$(changelog_dump | wc -l)
18352         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18353
18354         # simulate race between register and unregister
18355         # XXX as fail_loc is set per-MDS, with DNE configs the race
18356         # simulation will only occur for one MDT per MDS and for the
18357         # others the normal race scenario will take place
18358         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18359         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18360         do_nodes $mdts $LCTL set_param fail_val=1
18361
18362         # unregister 1st user
18363         changelog_deregister &
18364         local pid1=$!
18365         # wait some time for deregister work to reach race rdv
18366         sleep 2
18367         # register 2nd user
18368         changelog_register || error "2nd user register failed"
18369
18370         wait $pid1 || error "1st user deregister failed"
18371
18372         local i
18373         local last_rec
18374         declare -A LAST_REC
18375         for i in $(seq $MDSCOUNT); do
18376                 if changelog_users mds$i | grep "^cl"; then
18377                         # make sure new records are added with one user present
18378                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18379                                           awk '/^current.index:/ { print $NF }')
18380                 else
18381                         error "mds$i has no user registered"
18382                 fi
18383         done
18384
18385         # generate more changelog records to accumulate on each MDT
18386         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18387                 error "create $DIR/$tdir/${tfile}bis failed"
18388
18389         for i in $(seq $MDSCOUNT); do
18390                 last_rec=$(changelog_users $SINGLEMDS |
18391                            awk '/^current.index:/ { print $NF }')
18392                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18393                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18394                         error "changelogs are off on mds$i"
18395         done
18396 }
18397 run_test 160i "changelog user register/unregister race"
18398
18399 test_160j() {
18400         remote_mds_nodsh && skip "remote MDS with nodsh"
18401         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18402                 skip "Need MDS version at least 2.12.56"
18403
18404         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18405         stack_trap "umount $MOUNT2" EXIT
18406
18407         changelog_register || error "first changelog_register failed"
18408         stack_trap "changelog_deregister" EXIT
18409
18410         # generate some changelog
18411         # use all_char because created files should be evenly distributed
18412         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18413                 error "mkdir $tdir failed"
18414         for ((i = 0; i < MDSCOUNT; i++)); do
18415                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18416                         error "create $DIR/$tdir/d$i.1 failed"
18417         done
18418
18419         # open the changelog device
18420         exec 3>/dev/changelog-$FSNAME-MDT0000
18421         stack_trap "exec 3>&-" EXIT
18422         exec 4</dev/changelog-$FSNAME-MDT0000
18423         stack_trap "exec 4<&-" EXIT
18424
18425         # umount the first lustre mount
18426         umount $MOUNT
18427         stack_trap "mount_client $MOUNT" EXIT
18428
18429         # read changelog, which may or may not fail, but should not crash
18430         cat <&4 >/dev/null
18431
18432         # clear changelog
18433         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18434         changelog_users $SINGLEMDS | grep -q $cl_user ||
18435                 error "User $cl_user not found in changelog_users"
18436
18437         printf 'clear:'$cl_user':0' >&3
18438 }
18439 run_test 160j "client can be umounted while its chanangelog is being used"
18440
18441 test_160k() {
18442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18443         remote_mds_nodsh && skip "remote MDS with nodsh"
18444
18445         mkdir -p $DIR/$tdir/1/1
18446
18447         changelog_register || error "changelog_register failed"
18448         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18449
18450         changelog_users $SINGLEMDS | grep -q $cl_user ||
18451                 error "User '$cl_user' not found in changelog_users"
18452 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18453         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18454         rmdir $DIR/$tdir/1/1 & sleep 1
18455         mkdir $DIR/$tdir/2
18456         touch $DIR/$tdir/2/2
18457         rm -rf $DIR/$tdir/2
18458
18459         wait
18460         sleep 4
18461
18462         changelog_dump | grep rmdir || error "rmdir not recorded"
18463 }
18464 run_test 160k "Verify that changelog records are not lost"
18465
18466 # Verifies that a file passed as a parameter has recently had an operation
18467 # performed on it that has generated an MTIME changelog which contains the
18468 # correct parent FID. As files might reside on a different MDT from the
18469 # parent directory in DNE configurations, the FIDs are translated to paths
18470 # before being compared, which should be identical
18471 compare_mtime_changelog() {
18472         local file="${1}"
18473         local mdtidx
18474         local mtime
18475         local cl_fid
18476         local pdir
18477         local dir
18478
18479         mdtidx=$($LFS getstripe --mdt-index $file)
18480         mdtidx=$(printf "%04x" $mdtidx)
18481
18482         # Obtain the parent FID from the MTIME changelog
18483         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18484         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18485
18486         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18487         [ -z "$cl_fid" ] && error "parent FID not present"
18488
18489         # Verify that the path for the parent FID is the same as the path for
18490         # the test directory
18491         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18492
18493         dir=$(dirname $1)
18494
18495         [[ "${pdir%/}" == "$dir" ]] ||
18496                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18497 }
18498
18499 test_160l() {
18500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18501
18502         remote_mds_nodsh && skip "remote MDS with nodsh"
18503         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18504                 skip "Need MDS version at least 2.13.55"
18505
18506         local cl_user
18507
18508         changelog_register || error "changelog_register failed"
18509         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18510
18511         changelog_users $SINGLEMDS | grep -q $cl_user ||
18512                 error "User '$cl_user' not found in changelog_users"
18513
18514         # Clear some types so that MTIME changelogs are generated
18515         changelog_chmask "-CREAT"
18516         changelog_chmask "-CLOSE"
18517
18518         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18519
18520         # Test CL_MTIME during setattr
18521         touch $DIR/$tdir/$tfile
18522         compare_mtime_changelog $DIR/$tdir/$tfile
18523
18524         # Test CL_MTIME during close
18525         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18526         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18527 }
18528 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18529
18530 test_160m() {
18531         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18532         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18533                 skip "Need MDS version at least 2.14.51"
18534         local cl_users
18535         local cl_user1
18536         local cl_user2
18537         local pid1
18538
18539         # Create a user
18540         changelog_register || error "first changelog_register failed"
18541         changelog_register || error "second changelog_register failed"
18542
18543         cl_users=(${CL_USERS[mds1]})
18544         cl_user1="${cl_users[0]}"
18545         cl_user2="${cl_users[1]}"
18546         # generate some changelog records to accumulate on MDT0
18547         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18548         createmany -m $DIR/$tdir/$tfile 50 ||
18549                 error "create $DIR/$tdir/$tfile failed"
18550         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18551         rm -f $DIR/$tdir
18552
18553         # check changelogs have been generated
18554         local nbcl=$(changelog_dump | wc -l)
18555         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18556
18557 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18558         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18559
18560         __changelog_clear mds1 $cl_user1 +10
18561         __changelog_clear mds1 $cl_user2 0 &
18562         pid1=$!
18563         sleep 2
18564         __changelog_clear mds1 $cl_user1 0 ||
18565                 error "fail to cancel record for $cl_user1"
18566         wait $pid1
18567         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18568 }
18569 run_test 160m "Changelog clear race"
18570
18571 test_160n() {
18572         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18573         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18574                 skip "Need MDS version at least 2.14.51"
18575         local cl_users
18576         local cl_user1
18577         local cl_user2
18578         local pid1
18579         local first_rec
18580         local last_rec=0
18581
18582         # Create a user
18583         changelog_register || error "first changelog_register failed"
18584
18585         cl_users=(${CL_USERS[mds1]})
18586         cl_user1="${cl_users[0]}"
18587
18588         # generate some changelog records to accumulate on MDT0
18589         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18590         first_rec=$(changelog_users $SINGLEMDS |
18591                         awk '/^current.index:/ { print $NF }')
18592         while (( last_rec < (( first_rec + 65000)) )); do
18593                 createmany -m $DIR/$tdir/$tfile 10000 ||
18594                         error "create $DIR/$tdir/$tfile failed"
18595
18596                 for i in $(seq 0 10000); do
18597                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18598                                 > /dev/null
18599                 done
18600
18601                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18602                         error "unlinkmany failed unlink"
18603                 last_rec=$(changelog_users $SINGLEMDS |
18604                         awk '/^current.index:/ { print $NF }')
18605                 echo last record $last_rec
18606                 (( last_rec == 0 )) && error "no changelog found"
18607         done
18608
18609 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18610         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18611
18612         __changelog_clear mds1 $cl_user1 0 &
18613         pid1=$!
18614         sleep 2
18615         __changelog_clear mds1 $cl_user1 0 ||
18616                 error "fail to cancel record for $cl_user1"
18617         wait $pid1
18618         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18619 }
18620 run_test 160n "Changelog destroy race"
18621
18622 test_160o() {
18623         local mdt="$(facet_svc $SINGLEMDS)"
18624
18625         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18626         remote_mds_nodsh && skip "remote MDS with nodsh"
18627         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18628                 skip "Need MDS version at least 2.14.52"
18629
18630         changelog_register --user test_160o -m unlnk+close+open ||
18631                 error "changelog_register failed"
18632
18633         do_facet $SINGLEMDS $LCTL --device $mdt \
18634                                 changelog_register -u "Tt3_-#" &&
18635                 error "bad symbols in name should fail"
18636
18637         do_facet $SINGLEMDS $LCTL --device $mdt \
18638                                 changelog_register -u test_160o &&
18639                 error "the same name registration should fail"
18640
18641         do_facet $SINGLEMDS $LCTL --device $mdt \
18642                         changelog_register -u test_160toolongname &&
18643                 error "too long name registration should fail"
18644
18645         changelog_chmask "MARK+HSM"
18646         lctl get_param mdd.*.changelog*mask
18647         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18648         changelog_users $SINGLEMDS | grep -q $cl_user ||
18649                 error "User $cl_user not found in changelog_users"
18650         #verify username
18651         echo $cl_user | grep -q test_160o ||
18652                 error "User $cl_user has no specific name 'test160o'"
18653
18654         # change something
18655         changelog_clear 0 || error "changelog_clear failed"
18656         # generate some changelog records to accumulate on MDT0
18657         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18658         touch $DIR/$tdir/$tfile                 # open 1
18659
18660         OPENS=$(changelog_dump | grep -c "OPEN")
18661         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18662
18663         # must be no MKDIR it wasn't set as user mask
18664         MKDIR=$(changelog_dump | grep -c "MKDIR")
18665         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18666
18667         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18668                                 mdd.$mdt.changelog_current_mask -n)
18669         # register maskless user
18670         changelog_register || error "changelog_register failed"
18671         # effective mask should be not changed because it is not minimal
18672         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18673                                 mdd.$mdt.changelog_current_mask -n)
18674         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18675         # set server mask to minimal value
18676         changelog_chmask "MARK"
18677         # check effective mask again, should be treated as DEFMASK now
18678         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18679                                 mdd.$mdt.changelog_current_mask -n)
18680         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18681
18682         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18683                 # set server mask back to some value
18684                 changelog_chmask "CLOSE,UNLNK"
18685                 # check effective mask again, should not remain as DEFMASK
18686                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18687                                 mdd.$mdt.changelog_current_mask -n)
18688                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18689         fi
18690
18691         do_facet $SINGLEMDS $LCTL --device $mdt \
18692                                 changelog_deregister -u test_160o ||
18693                 error "cannot deregister by name"
18694 }
18695 run_test 160o "changelog user name and mask"
18696
18697 test_160p() {
18698         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18699         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18700                 skip "Need MDS version at least 2.14.51"
18701         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18702         local cl_users
18703         local cl_user1
18704         local entry_count
18705
18706         # Create a user
18707         changelog_register || error "first changelog_register failed"
18708
18709         cl_users=(${CL_USERS[mds1]})
18710         cl_user1="${cl_users[0]}"
18711
18712         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18713         createmany -m $DIR/$tdir/$tfile 50 ||
18714                 error "create $DIR/$tdir/$tfile failed"
18715         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18716         rm -rf $DIR/$tdir
18717
18718         # check changelogs have been generated
18719         entry_count=$(changelog_dump | wc -l)
18720         ((entry_count != 0)) || error "no changelog entries found"
18721
18722         # remove changelog_users and check that orphan entries are removed
18723         stop mds1
18724         local dev=$(mdsdevname 1)
18725         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18726         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18727         entry_count=$(changelog_dump | wc -l)
18728         ((entry_count == 0)) ||
18729                 error "found $entry_count changelog entries, expected none"
18730 }
18731 run_test 160p "Changelog orphan cleanup with no users"
18732
18733 test_160q() {
18734         local mdt="$(facet_svc $SINGLEMDS)"
18735         local clu
18736
18737         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18738         remote_mds_nodsh && skip "remote MDS with nodsh"
18739         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18740                 skip "Need MDS version at least 2.14.54"
18741
18742         # set server mask to minimal value like server init does
18743         changelog_chmask "MARK"
18744         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18745                 error "changelog_register failed"
18746         # check effective mask again, should be treated as DEFMASK now
18747         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18748                                 mdd.$mdt.changelog_current_mask -n)
18749         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18750                 error "changelog_deregister failed"
18751         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18752 }
18753 run_test 160q "changelog effective mask is DEFMASK if not set"
18754
18755 test_160s() {
18756         remote_mds_nodsh && skip "remote MDS with nodsh"
18757         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18758                 skip "Need MDS version at least 2.14.55"
18759
18760         local mdts=$(comma_list $(mdts_nodes))
18761
18762         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18763         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18764                                        fail_val=$((24 * 3600 * 10))
18765
18766         # Create a user which is 10 days old
18767         changelog_register || error "first changelog_register failed"
18768         local cl_users
18769         declare -A cl_user1
18770         local i
18771
18772         # generate some changelog records to accumulate on each MDT
18773         # use all_char because created files should be evenly distributed
18774         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18775                 error "test_mkdir $tdir failed"
18776         for ((i = 0; i < MDSCOUNT; i++)); do
18777                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18778                         error "create $DIR/$tdir/d$i.1 failed"
18779         done
18780
18781         # check changelogs have been generated
18782         local nbcl=$(changelog_dump | wc -l)
18783         (( nbcl > 0 )) || error "no changelogs found"
18784
18785         # reduce the max_idle_indexes value to make sure we exceed it
18786         for param in "changelog_max_idle_indexes=2097446912" \
18787                      "changelog_max_idle_time=2592000" \
18788                      "changelog_gc=1" \
18789                      "changelog_min_gc_interval=2"; do
18790                 local MDT0=$(facet_svc $SINGLEMDS)
18791                 local var="${param%=*}"
18792                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18793
18794                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18795                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18796                         error "unable to set mdd.*.$param"
18797         done
18798
18799         local start=$SECONDS
18800         for i in $(seq $MDSCOUNT); do
18801                 cl_users=(${CL_USERS[mds$i]})
18802                 cl_user1[mds$i]="${cl_users[0]}"
18803
18804                 [[ -n "${cl_user1[mds$i]}" ]] ||
18805                         error "mds$i: no user registered"
18806         done
18807
18808         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18809         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18810
18811         # ensure we are past the previous changelog_min_gc_interval set above
18812         local sleep2=$((start + 2 - SECONDS))
18813         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18814
18815         # Generate one more changelog to trigger GC
18816         for ((i = 0; i < MDSCOUNT; i++)); do
18817                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18818                         error "create $DIR/$tdir/d$i.3 failed"
18819         done
18820
18821         # ensure gc thread is done
18822         for node in $(mdts_nodes); do
18823                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18824                         error "$node: GC-thread not done"
18825         done
18826
18827         do_nodes $mdts $LCTL set_param fail_loc=0
18828
18829         for (( i = 1; i <= MDSCOUNT; i++ )); do
18830                 # check cl_user1 is purged
18831                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18832                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18833         done
18834         return 0
18835 }
18836 run_test 160s "changelog garbage collect on idle records * time"
18837
18838 test_160t() {
18839         remote_mds_nodsh && skip "remote MDS with nodsh"
18840         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18841                 skip "Need MDS version at least 2.15.50"
18842
18843         local MDT0=$(facet_svc $SINGLEMDS)
18844         local cl_users
18845         local cl_user1
18846         local cl_user2
18847         local start
18848
18849         changelog_register --user user1 -m all ||
18850                 error "user1 failed to register"
18851
18852         mkdir_on_mdt0 $DIR/$tdir
18853         # create default overstripe to maximize changelog size
18854         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18855         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18856         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18857
18858         # user2 consumes less records so less space
18859         changelog_register --user user2 || error "user2 failed to register"
18860         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18861         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18862
18863         # check changelogs have been generated
18864         local nbcl=$(changelog_dump | wc -l)
18865         (( nbcl > 0 )) || error "no changelogs found"
18866
18867         # reduce the changelog_min_gc_interval to force check
18868         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18869                 local var="${param%=*}"
18870                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18871
18872                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18873                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18874                         error "unable to set mdd.*.$param"
18875         done
18876
18877         start=$SECONDS
18878         cl_users=(${CL_USERS[mds1]})
18879         cl_user1="${cl_users[0]}"
18880         cl_user2="${cl_users[1]}"
18881
18882         [[ -n $cl_user1 ]] ||
18883                 error "mds1: user #1 isn't registered"
18884         [[ -n $cl_user2 ]] ||
18885                 error "mds1: user #2 isn't registered"
18886
18887         # ensure we are past the previous changelog_min_gc_interval set above
18888         local sleep2=$((start + 2 - SECONDS))
18889         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18890
18891         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18892         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18893                         fail_val=$(((llog_size1 + llog_size2) / 2))
18894
18895         # Generate more changelog to trigger GC
18896         createmany -o $DIR/$tdir/u3_ 4 ||
18897                 error "create failed for more files"
18898
18899         # ensure gc thread is done
18900         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18901                 error "mds1: GC-thread not done"
18902
18903         do_facet mds1 $LCTL set_param fail_loc=0
18904
18905         # check cl_user1 is purged
18906         changelog_users mds1 | grep -q "$cl_user1" &&
18907                 error "User $cl_user1 is registered"
18908         # check cl_user2 is not purged
18909         changelog_users mds1 | grep -q "$cl_user2" ||
18910                 error "User $cl_user2 is not registered"
18911 }
18912 run_test 160t "changelog garbage collect on lack of space"
18913
18914 test_160u() { # LU-17400
18915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18916         remote_mds_nodsh && skip "remote MDS with nodsh"
18917         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18918                 skip "Need MDS version at least 2.2.0"
18919
18920         cd $DIR || error "cd $DIR failed"
18921
18922         # ensure changelog has a clean view if tests are run multiple times
18923         [ -d rename ] && rm -rf rename
18924
18925         changelog_register || error "changelog_register failed"
18926         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18927
18928         changelog_users $SINGLEMDS | grep -q $cl_user ||
18929                 error "User '$cl_user' not found in changelog_users"
18930
18931         local longname1=$(str_repeat a 255)
18932
18933         echo "creating simple directory tree"
18934         mkdir -p rename/a || error "create of simple directory tree failed"
18935         echo "creating rename/hw file"
18936         echo "hello world" > rename/hw || error "create of rename/hw failed"
18937         echo "creating very long named file"
18938         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18939         echo "move rename/hw to rename/a/a.hw"
18940         mv rename/hw rename/a/a.hw || error "mv failed"
18941
18942         RENME=($(changelog_dump | grep "RENME"))
18943         #declare -p RENME # for debugging captured value with indexes
18944
18945         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18946                 error "changelog rename record type name/sname error"
18947 }
18948 run_test 160u "changelog rename record type name and sname strings are correct"
18949
18950 test_161a() {
18951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18952
18953         test_mkdir -c1 $DIR/$tdir
18954         cp /etc/hosts $DIR/$tdir/$tfile
18955         test_mkdir -c1 $DIR/$tdir/foo1
18956         test_mkdir -c1 $DIR/$tdir/foo2
18957         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18958         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18959         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18960         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18961         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18962         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18963                 $LFS fid2path $DIR $FID
18964                 error "bad link ea"
18965         fi
18966         # middle
18967         rm $DIR/$tdir/foo2/zachary
18968         # last
18969         rm $DIR/$tdir/foo2/thor
18970         # first
18971         rm $DIR/$tdir/$tfile
18972         # rename
18973         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18974         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18975                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18976         rm $DIR/$tdir/foo2/maggie
18977
18978         # overflow the EA
18979         local longname=$tfile.avg_len_is_thirty_two_
18980         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18981                 error_noexit 'failed to unlink many hardlinks'" EXIT
18982         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18983                 error "failed to hardlink many files"
18984         links=$($LFS fid2path $DIR $FID | wc -l)
18985         echo -n "${links}/1000 links in link EA"
18986         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18987 }
18988 run_test 161a "link ea sanity"
18989
18990 test_161b() {
18991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18992         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18993
18994         local MDTIDX=1
18995         local remote_dir=$DIR/$tdir/remote_dir
18996
18997         mkdir -p $DIR/$tdir
18998         $LFS mkdir -i $MDTIDX $remote_dir ||
18999                 error "create remote directory failed"
19000
19001         cp /etc/hosts $remote_dir/$tfile
19002         mkdir -p $remote_dir/foo1
19003         mkdir -p $remote_dir/foo2
19004         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19005         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19006         ln $remote_dir/$tfile $remote_dir/foo1/luna
19007         ln $remote_dir/$tfile $remote_dir/foo2/thor
19008
19009         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19010                      tr -d ']')
19011         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19012                 $LFS fid2path $DIR $FID
19013                 error "bad link ea"
19014         fi
19015         # middle
19016         rm $remote_dir/foo2/zachary
19017         # last
19018         rm $remote_dir/foo2/thor
19019         # first
19020         rm $remote_dir/$tfile
19021         # rename
19022         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19023         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19024         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19025                 $LFS fid2path $DIR $FID
19026                 error "bad link rename"
19027         fi
19028         rm $remote_dir/foo2/maggie
19029
19030         # overflow the EA
19031         local longname=filename_avg_len_is_thirty_two_
19032         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19033                 error "failed to hardlink many files"
19034         links=$($LFS fid2path $DIR $FID | wc -l)
19035         echo -n "${links}/1000 links in link EA"
19036         [[ ${links} -gt 60 ]] ||
19037                 error "expected at least 60 links in link EA"
19038         unlinkmany $remote_dir/foo2/$longname 1000 ||
19039         error "failed to unlink many hardlinks"
19040 }
19041 run_test 161b "link ea sanity under remote directory"
19042
19043 test_161c() {
19044         remote_mds_nodsh && skip "remote MDS with nodsh"
19045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19046         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19047                 skip "Need MDS version at least 2.1.5"
19048
19049         # define CLF_RENAME_LAST 0x0001
19050         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19051         changelog_register || error "changelog_register failed"
19052
19053         rm -rf $DIR/$tdir
19054         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19055         touch $DIR/$tdir/foo_161c
19056         touch $DIR/$tdir/bar_161c
19057         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19058         changelog_dump | grep RENME | tail -n 5
19059         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19060         changelog_clear 0 || error "changelog_clear failed"
19061         if [ x$flags != "x0x1" ]; then
19062                 error "flag $flags is not 0x1"
19063         fi
19064
19065         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19066         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19067         touch $DIR/$tdir/foo_161c
19068         touch $DIR/$tdir/bar_161c
19069         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19070         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19071         changelog_dump | grep RENME | tail -n 5
19072         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19073         changelog_clear 0 || error "changelog_clear failed"
19074         if [ x$flags != "x0x0" ]; then
19075                 error "flag $flags is not 0x0"
19076         fi
19077         echo "rename overwrite a target having nlink > 1," \
19078                 "changelog record has flags of $flags"
19079
19080         # rename doesn't overwrite a target (changelog flag 0x0)
19081         touch $DIR/$tdir/foo_161c
19082         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19083         changelog_dump | grep RENME | tail -n 5
19084         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19085         changelog_clear 0 || error "changelog_clear failed"
19086         if [ x$flags != "x0x0" ]; then
19087                 error "flag $flags is not 0x0"
19088         fi
19089         echo "rename doesn't overwrite a target," \
19090                 "changelog record has flags of $flags"
19091
19092         # define CLF_UNLINK_LAST 0x0001
19093         # unlink a file having nlink = 1 (changelog flag 0x1)
19094         rm -f $DIR/$tdir/foo2_161c
19095         changelog_dump | grep UNLNK | tail -n 5
19096         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19097         changelog_clear 0 || error "changelog_clear failed"
19098         if [ x$flags != "x0x1" ]; then
19099                 error "flag $flags is not 0x1"
19100         fi
19101         echo "unlink a file having nlink = 1," \
19102                 "changelog record has flags of $flags"
19103
19104         # unlink a file having nlink > 1 (changelog flag 0x0)
19105         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19106         rm -f $DIR/$tdir/foobar_161c
19107         changelog_dump | grep UNLNK | tail -n 5
19108         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19109         changelog_clear 0 || error "changelog_clear failed"
19110         if [ x$flags != "x0x0" ]; then
19111                 error "flag $flags is not 0x0"
19112         fi
19113         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19114 }
19115 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19116
19117 test_161d() {
19118         remote_mds_nodsh && skip "remote MDS with nodsh"
19119         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19120
19121         local pid
19122         local fid
19123
19124         changelog_register || error "changelog_register failed"
19125
19126         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19127         # interfer with $MOUNT/.lustre/fid/ access
19128         mkdir $DIR/$tdir
19129         [[ $? -eq 0 ]] || error "mkdir failed"
19130
19131         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19132         $LCTL set_param fail_loc=0x8000140c
19133         # 5s pause
19134         $LCTL set_param fail_val=5
19135
19136         # create file
19137         echo foofoo > $DIR/$tdir/$tfile &
19138         pid=$!
19139
19140         # wait for create to be delayed
19141         sleep 2
19142
19143         ps -p $pid
19144         [[ $? -eq 0 ]] || error "create should be blocked"
19145
19146         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19147         stack_trap "rm -f $tempfile"
19148         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19149         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19150         # some delay may occur during ChangeLog publishing and file read just
19151         # above, that could allow file write to happen finally
19152         [[ -s $tempfile ]] && echo "file should be empty"
19153
19154         $LCTL set_param fail_loc=0
19155
19156         wait $pid
19157         [[ $? -eq 0 ]] || error "create failed"
19158 }
19159 run_test 161d "create with concurrent .lustre/fid access"
19160
19161 check_path() {
19162         local expected="$1"
19163         shift
19164         local fid="$2"
19165
19166         local path
19167         path=$($LFS fid2path "$@")
19168         local rc=$?
19169
19170         if [ $rc -ne 0 ]; then
19171                 error "path looked up of '$expected' failed: rc=$rc"
19172         elif [ "$path" != "$expected" ]; then
19173                 error "path looked up '$path' instead of '$expected'"
19174         else
19175                 echo "FID '$fid' resolves to path '$path' as expected"
19176         fi
19177 }
19178
19179 test_162a() { # was test_162
19180         test_mkdir -p -c1 $DIR/$tdir/d2
19181         touch $DIR/$tdir/d2/$tfile
19182         touch $DIR/$tdir/d2/x1
19183         touch $DIR/$tdir/d2/x2
19184         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19185         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19186         # regular file
19187         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19188         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19189
19190         # softlink
19191         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19192         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19193         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19194
19195         # softlink to wrong file
19196         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19197         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19198         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19199
19200         # hardlink
19201         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19202         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19203         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19204         # fid2path dir/fsname should both work
19205         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19206         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19207
19208         # hardlink count: check that there are 2 links
19209         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19210         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19211
19212         # hardlink indexing: remove the first link
19213         rm $DIR/$tdir/d2/p/q/r/hlink
19214         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19215 }
19216 run_test 162a "path lookup sanity"
19217
19218 test_162b() {
19219         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19220         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19221
19222         mkdir $DIR/$tdir
19223         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19224                                 error "create striped dir failed"
19225
19226         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19227                                         tail -n 1 | awk '{print $2}')
19228         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19229
19230         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19231         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19232
19233         # regular file
19234         for ((i=0;i<5;i++)); do
19235                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19236                         error "get fid for f$i failed"
19237                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19238
19239                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19240                         error "get fid for d$i failed"
19241                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19242         done
19243
19244         return 0
19245 }
19246 run_test 162b "striped directory path lookup sanity"
19247
19248 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19249 test_162c() {
19250         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19251                 skip "Need MDS version at least 2.7.51"
19252
19253         local lpath=$tdir.local
19254         local rpath=$tdir.remote
19255
19256         test_mkdir $DIR/$lpath
19257         test_mkdir $DIR/$rpath
19258
19259         for ((i = 0; i <= 101; i++)); do
19260                 lpath="$lpath/$i"
19261                 mkdir $DIR/$lpath
19262                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19263                         error "get fid for local directory $DIR/$lpath failed"
19264                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19265
19266                 rpath="$rpath/$i"
19267                 test_mkdir $DIR/$rpath
19268                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19269                         error "get fid for remote directory $DIR/$rpath failed"
19270                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19271         done
19272
19273         return 0
19274 }
19275 run_test 162c "fid2path works with paths 100 or more directories deep"
19276
19277 oalr_event_count() {
19278         local event="${1}"
19279         local trace="${2}"
19280
19281         awk -v name="${FSNAME}-OST0000" \
19282             -v event="${event}" \
19283             '$1 == "TRACE" && $2 == event && $3 == name' \
19284             "${trace}" |
19285         wc -l
19286 }
19287
19288 oalr_expect_event_count() {
19289         local event="${1}"
19290         local trace="${2}"
19291         local expect="${3}"
19292         local count
19293
19294         count=$(oalr_event_count "${event}" "${trace}")
19295         if ((count == expect)); then
19296                 return 0
19297         fi
19298
19299         error_noexit "${event} event count was '${count}', expected ${expect}"
19300         cat "${trace}" >&2
19301         exit 1
19302 }
19303
19304 cleanup_165() {
19305         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19306         stop ost1
19307         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19308 }
19309
19310 setup_165() {
19311         sync # Flush previous IOs so we can count log entries.
19312         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19313         stack_trap cleanup_165 EXIT
19314 }
19315
19316 test_165a() {
19317         local trace="/tmp/${tfile}.trace"
19318         local rc
19319         local count
19320
19321         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19322                 skip "OFD access log unsupported"
19323
19324         setup_165
19325         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19326         sleep 5
19327
19328         do_facet ost1 ofd_access_log_reader --list
19329         stop ost1
19330
19331         do_facet ost1 killall -TERM ofd_access_log_reader
19332         wait
19333         rc=$?
19334
19335         if ((rc != 0)); then
19336                 error "ofd_access_log_reader exited with rc = '${rc}'"
19337         fi
19338
19339         # Parse trace file for discovery events:
19340         oalr_expect_event_count alr_log_add "${trace}" 1
19341         oalr_expect_event_count alr_log_eof "${trace}" 1
19342         oalr_expect_event_count alr_log_free "${trace}" 1
19343 }
19344 run_test 165a "ofd access log discovery"
19345
19346 test_165b() {
19347         local trace="/tmp/${tfile}.trace"
19348         local file="${DIR}/${tfile}"
19349         local pfid1
19350         local pfid2
19351         local -a entry
19352         local rc
19353         local count
19354         local size
19355         local flags
19356
19357         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19358                 skip "OFD access log unsupported"
19359
19360         setup_165
19361         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19362         sleep 5
19363
19364         do_facet ost1 ofd_access_log_reader --list
19365
19366         lfs setstripe -c 1 -i 0 "${file}"
19367         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19368                 error "cannot create '${file}'"
19369
19370         sleep 5
19371         do_facet ost1 killall -TERM ofd_access_log_reader
19372         wait
19373         rc=$?
19374
19375         if ((rc != 0)); then
19376                 error "ofd_access_log_reader exited with rc = '${rc}'"
19377         fi
19378
19379         oalr_expect_event_count alr_log_entry "${trace}" 1
19380
19381         pfid1=$($LFS path2fid "${file}")
19382
19383         # 1     2             3   4    5     6   7    8    9     10
19384         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19385         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19386
19387         echo "entry = '${entry[*]}'" >&2
19388
19389         pfid2=${entry[4]}
19390         if [[ "${pfid1}" != "${pfid2}" ]]; then
19391                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19392         fi
19393
19394         size=${entry[8]}
19395         if ((size != 1048576)); then
19396                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19397         fi
19398
19399         flags=${entry[10]}
19400         if [[ "${flags}" != "w" ]]; then
19401                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19402         fi
19403
19404         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19405         sleep 5
19406
19407         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19408                 error "cannot read '${file}'"
19409         sleep 5
19410
19411         do_facet ost1 killall -TERM ofd_access_log_reader
19412         wait
19413         rc=$?
19414
19415         if ((rc != 0)); then
19416                 error "ofd_access_log_reader exited with rc = '${rc}'"
19417         fi
19418
19419         oalr_expect_event_count alr_log_entry "${trace}" 1
19420
19421         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19422         echo "entry = '${entry[*]}'" >&2
19423
19424         pfid2=${entry[4]}
19425         if [[ "${pfid1}" != "${pfid2}" ]]; then
19426                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19427         fi
19428
19429         size=${entry[8]}
19430         if ((size != 524288)); then
19431                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19432         fi
19433
19434         flags=${entry[10]}
19435         if [[ "${flags}" != "r" ]]; then
19436                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19437         fi
19438 }
19439 run_test 165b "ofd access log entries are produced and consumed"
19440
19441 test_165c() {
19442         local trace="/tmp/${tfile}.trace"
19443         local file="${DIR}/${tdir}/${tfile}"
19444
19445         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19446                 skip "OFD access log unsupported"
19447
19448         test_mkdir "${DIR}/${tdir}"
19449
19450         setup_165
19451         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19452         sleep 5
19453
19454         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19455
19456         # 4096 / 64 = 64. Create twice as many entries.
19457         for ((i = 0; i < 128; i++)); do
19458                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19459                         error "cannot create file"
19460         done
19461
19462         sync
19463
19464         do_facet ost1 killall -TERM ofd_access_log_reader
19465         wait
19466         rc=$?
19467         if ((rc != 0)); then
19468                 error "ofd_access_log_reader exited with rc = '${rc}'"
19469         fi
19470
19471         unlinkmany  "${file}-%d" 128
19472 }
19473 run_test 165c "full ofd access logs do not block IOs"
19474
19475 oal_get_read_count() {
19476         local stats="$1"
19477
19478         # STATS lustre-OST0001 alr_read_count 1
19479
19480         do_facet ost1 cat "${stats}" |
19481         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19482              END { print count; }'
19483 }
19484
19485 oal_expect_read_count() {
19486         local stats="$1"
19487         local count
19488         local expect="$2"
19489
19490         # Ask ofd_access_log_reader to write stats.
19491         do_facet ost1 killall -USR1 ofd_access_log_reader
19492
19493         # Allow some time for things to happen.
19494         sleep 1
19495
19496         count=$(oal_get_read_count "${stats}")
19497         if ((count == expect)); then
19498                 return 0
19499         fi
19500
19501         error_noexit "bad read count, got ${count}, expected ${expect}"
19502         do_facet ost1 cat "${stats}" >&2
19503         exit 1
19504 }
19505
19506 test_165d() {
19507         local stats="/tmp/${tfile}.stats"
19508         local file="${DIR}/${tdir}/${tfile}"
19509         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19510
19511         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19512                 skip "OFD access log unsupported"
19513
19514         test_mkdir "${DIR}/${tdir}"
19515
19516         setup_165
19517         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19518         sleep 5
19519
19520         lfs setstripe -c 1 -i 0 "${file}"
19521
19522         do_facet ost1 lctl set_param "${param}=rw"
19523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19524                 error "cannot create '${file}'"
19525         oal_expect_read_count "${stats}" 1
19526
19527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19528                 error "cannot read '${file}'"
19529         oal_expect_read_count "${stats}" 2
19530
19531         do_facet ost1 lctl set_param "${param}=r"
19532         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19533                 error "cannot create '${file}'"
19534         oal_expect_read_count "${stats}" 2
19535
19536         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19537                 error "cannot read '${file}'"
19538         oal_expect_read_count "${stats}" 3
19539
19540         do_facet ost1 lctl set_param "${param}=w"
19541         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19542                 error "cannot create '${file}'"
19543         oal_expect_read_count "${stats}" 4
19544
19545         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19546                 error "cannot read '${file}'"
19547         oal_expect_read_count "${stats}" 4
19548
19549         do_facet ost1 lctl set_param "${param}=0"
19550         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19551                 error "cannot create '${file}'"
19552         oal_expect_read_count "${stats}" 4
19553
19554         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19555                 error "cannot read '${file}'"
19556         oal_expect_read_count "${stats}" 4
19557
19558         do_facet ost1 killall -TERM ofd_access_log_reader
19559         wait
19560         rc=$?
19561         if ((rc != 0)); then
19562                 error "ofd_access_log_reader exited with rc = '${rc}'"
19563         fi
19564 }
19565 run_test 165d "ofd_access_log mask works"
19566
19567 test_165e() {
19568         local stats="/tmp/${tfile}.stats"
19569         local file0="${DIR}/${tdir}-0/${tfile}"
19570         local file1="${DIR}/${tdir}-1/${tfile}"
19571
19572         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19573                 skip "OFD access log unsupported"
19574
19575         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19576
19577         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19578         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19579
19580         lfs setstripe -c 1 -i 0 "${file0}"
19581         lfs setstripe -c 1 -i 0 "${file1}"
19582
19583         setup_165
19584         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19585         sleep 5
19586
19587         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19588                 error "cannot create '${file0}'"
19589         sync
19590         oal_expect_read_count "${stats}" 0
19591
19592         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19593                 error "cannot create '${file1}'"
19594         sync
19595         oal_expect_read_count "${stats}" 1
19596
19597         do_facet ost1 killall -TERM ofd_access_log_reader
19598         wait
19599         rc=$?
19600         if ((rc != 0)); then
19601                 error "ofd_access_log_reader exited with rc = '${rc}'"
19602         fi
19603 }
19604 run_test 165e "ofd_access_log MDT index filter works"
19605
19606 test_165f() {
19607         local trace="/tmp/${tfile}.trace"
19608         local rc
19609         local count
19610
19611         setup_165
19612         do_facet ost1 timeout 60 ofd_access_log_reader \
19613                 --exit-on-close --debug=- --trace=- > "${trace}" &
19614         sleep 5
19615         stop ost1
19616
19617         wait
19618         rc=$?
19619
19620         if ((rc != 0)); then
19621                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19622                 cat "${trace}"
19623                 exit 1
19624         fi
19625 }
19626 run_test 165f "ofd_access_log_reader --exit-on-close works"
19627
19628 test_169() {
19629         # do directio so as not to populate the page cache
19630         log "creating a 10 Mb file"
19631         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19632                 error "multiop failed while creating a file"
19633         log "starting reads"
19634         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19635         log "truncating the file"
19636         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19637                 error "multiop failed while truncating the file"
19638         log "killing dd"
19639         kill %+ || true # reads might have finished
19640         echo "wait until dd is finished"
19641         wait
19642         log "removing the temporary file"
19643         rm -rf $DIR/$tfile || error "tmp file removal failed"
19644 }
19645 run_test 169 "parallel read and truncate should not deadlock"
19646
19647 test_170() {
19648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19649
19650         $LCTL clear     # bug 18514
19651         $LCTL debug_daemon start $TMP/${tfile}_log_good
19652         touch $DIR/$tfile
19653         $LCTL debug_daemon stop
19654         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19655                 error "sed failed to read log_good"
19656
19657         $LCTL debug_daemon start $TMP/${tfile}_log_good
19658         rm -rf $DIR/$tfile
19659         $LCTL debug_daemon stop
19660
19661         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19662                error "lctl df log_bad failed"
19663
19664         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19665         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19666
19667         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19668         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19669
19670         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19671                 error "bad_line good_line1 good_line2 are empty"
19672
19673         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19674         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19675         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19676
19677         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19678         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19679         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19680
19681         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19682                 error "bad_line_new good_line_new are empty"
19683
19684         local expected_good=$((good_line1 + good_line2*2))
19685
19686         rm -f $TMP/${tfile}*
19687         # LU-231, short malformed line may not be counted into bad lines
19688         if [ $bad_line -ne $bad_line_new ] &&
19689                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19690                 error "expected $bad_line bad lines, but got $bad_line_new"
19691                 return 1
19692         fi
19693
19694         if [ $expected_good -ne $good_line_new ]; then
19695                 error "expected $expected_good good lines, but got $good_line_new"
19696                 return 2
19697         fi
19698         true
19699 }
19700 run_test 170 "test lctl df to handle corrupted log ====================="
19701
19702 test_171() { # bug20592
19703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19704
19705         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19706         $LCTL set_param fail_loc=0x50e
19707         $LCTL set_param fail_val=3000
19708         multiop_bg_pause $DIR/$tfile O_s || true
19709         local MULTIPID=$!
19710         kill -USR1 $MULTIPID
19711         # cause log dump
19712         sleep 3
19713         wait $MULTIPID
19714         if dmesg | grep "recursive fault"; then
19715                 error "caught a recursive fault"
19716         fi
19717         $LCTL set_param fail_loc=0
19718         true
19719 }
19720 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19721
19722 test_172() {
19723
19724         #define OBD_FAIL_OBD_CLEANUP  0x60e
19725         $LCTL set_param fail_loc=0x60e
19726         umount $MOUNT || error "umount $MOUNT failed"
19727         stack_trap "mount_client $MOUNT"
19728
19729         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19730                 error "no client OBDs are remained"
19731
19732         $LCTL dl | while read devno state type name foo; do
19733                 case $type in
19734                 lov|osc|lmv|mdc)
19735                         $LCTL --device $name cleanup
19736                         $LCTL --device $name detach
19737                         ;;
19738                 *)
19739                         # skip server devices
19740                         ;;
19741                 esac
19742         done
19743
19744         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19745                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19746                 error "some client OBDs are still remained"
19747         fi
19748
19749 }
19750 run_test 172 "manual device removal with lctl cleanup/detach ======"
19751
19752 # it would be good to share it with obdfilter-survey/iokit-libecho code
19753 setup_obdecho_osc () {
19754         local rc=0
19755         local ost_nid=$1
19756         local obdfilter_name=$2
19757         echo "Creating new osc for $obdfilter_name on $ost_nid"
19758         # make sure we can find loopback nid
19759         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19760
19761         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19762                            ${obdfilter_name}_osc_UUID || rc=2; }
19763         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19764                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19765         return $rc
19766 }
19767
19768 cleanup_obdecho_osc () {
19769         local obdfilter_name=$1
19770         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19771         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19772         return 0
19773 }
19774
19775 obdecho_test() {
19776         local OBD=$1
19777         local node=$2
19778         local pages=${3:-64}
19779         local rc=0
19780         local id
19781
19782         local count=10
19783         local obd_size=$(get_obd_size $node $OBD)
19784         local page_size=$(get_page_size $node)
19785         if [[ -n "$obd_size" ]]; then
19786                 local new_count=$((obd_size / (pages * page_size / 1024)))
19787                 [[ $new_count -ge $count ]] || count=$new_count
19788         fi
19789
19790         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19791         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19792                            rc=2; }
19793         if [ $rc -eq 0 ]; then
19794             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19795             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19796         fi
19797         echo "New object id is $id"
19798         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19799                            rc=4; }
19800         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19801                            "test_brw $count w v $pages $id" || rc=4; }
19802         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19803                            rc=4; }
19804         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19805                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19806         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19807                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19808         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19809         return $rc
19810 }
19811
19812 test_180a() {
19813         skip "obdecho on osc is no longer supported"
19814 }
19815 run_test 180a "test obdecho on osc"
19816
19817 test_180b() {
19818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19819         remote_ost_nodsh && skip "remote OST with nodsh"
19820
19821         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19822                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19823                 error "failed to load module obdecho"
19824
19825         local target=$(do_facet ost1 $LCTL dl |
19826                        awk '/obdfilter/ { print $4; exit; }')
19827
19828         if [ -n "$target" ]; then
19829                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19830         else
19831                 do_facet ost1 $LCTL dl
19832                 error "there is no obdfilter target on ost1"
19833         fi
19834 }
19835 run_test 180b "test obdecho directly on obdfilter"
19836
19837 test_180c() { # LU-2598
19838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19839         remote_ost_nodsh && skip "remote OST with nodsh"
19840         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19841                 skip "Need MDS version at least 2.4.0"
19842
19843         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19844                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19845                 error "failed to load module obdecho"
19846
19847         local target=$(do_facet ost1 $LCTL dl |
19848                        awk '/obdfilter/ { print $4; exit; }')
19849
19850         if [ -n "$target" ]; then
19851                 local pages=16384 # 64MB bulk I/O RPC size
19852
19853                 obdecho_test "$target" ost1 "$pages" ||
19854                         error "obdecho_test with pages=$pages failed with $?"
19855         else
19856                 do_facet ost1 $LCTL dl
19857                 error "there is no obdfilter target on ost1"
19858         fi
19859 }
19860 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19861
19862 test_181() { # bug 22177
19863         test_mkdir $DIR/$tdir
19864         # create enough files to index the directory
19865         createmany -o $DIR/$tdir/foobar 4000
19866         # print attributes for debug purpose
19867         lsattr -d .
19868         # open dir
19869         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19870         MULTIPID=$!
19871         # remove the files & current working dir
19872         unlinkmany $DIR/$tdir/foobar 4000
19873         rmdir $DIR/$tdir
19874         kill -USR1 $MULTIPID
19875         wait $MULTIPID
19876         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19877         return 0
19878 }
19879 run_test 181 "Test open-unlinked dir ========================"
19880
19881 test_182a() {
19882         local fcount=1000
19883         local tcount=10
19884
19885         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19886
19887         $LCTL set_param mdc.*.rpc_stats=clear
19888
19889         for (( i = 0; i < $tcount; i++ )) ; do
19890                 mkdir $DIR/$tdir/$i
19891         done
19892
19893         for (( i = 0; i < $tcount; i++ )) ; do
19894                 createmany -o $DIR/$tdir/$i/f- $fcount &
19895         done
19896         wait
19897
19898         for (( i = 0; i < $tcount; i++ )) ; do
19899                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19900         done
19901         wait
19902
19903         $LCTL get_param mdc.*.rpc_stats
19904
19905         rm -rf $DIR/$tdir
19906 }
19907 run_test 182a "Test parallel modify metadata operations from mdc"
19908
19909 test_182b() {
19910         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19911         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19912         local dcount=1000
19913         local tcount=10
19914         local stime
19915         local etime
19916         local delta
19917
19918         do_facet mds1 $LCTL list_param \
19919                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19920                 skip "MDS lacks parallel RPC handling"
19921
19922         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19923
19924         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19925                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19926
19927         stime=$(date +%s)
19928         createmany -i 0 -d $DIR/$tdir/t- $tcount
19929
19930         for (( i = 0; i < $tcount; i++ )) ; do
19931                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19932         done
19933         wait
19934         etime=$(date +%s)
19935         delta=$((etime - stime))
19936         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19937
19938         stime=$(date +%s)
19939         for (( i = 0; i < $tcount; i++ )) ; do
19940                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19941         done
19942         wait
19943         etime=$(date +%s)
19944         delta=$((etime - stime))
19945         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19946
19947         rm -rf $DIR/$tdir
19948
19949         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19950
19951         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19952
19953         stime=$(date +%s)
19954         createmany -i 0 -d $DIR/$tdir/t- $tcount
19955
19956         for (( i = 0; i < $tcount; i++ )) ; do
19957                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19958         done
19959         wait
19960         etime=$(date +%s)
19961         delta=$((etime - stime))
19962         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19963
19964         stime=$(date +%s)
19965         for (( i = 0; i < $tcount; i++ )) ; do
19966                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19967         done
19968         wait
19969         etime=$(date +%s)
19970         delta=$((etime - stime))
19971         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19972
19973         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19974 }
19975 run_test 182b "Test parallel modify metadata operations from osp"
19976
19977 test_183() { # LU-2275
19978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19979         remote_mds_nodsh && skip "remote MDS with nodsh"
19980         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19981                 skip "Need MDS version at least 2.3.56"
19982
19983         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19984         echo aaa > $DIR/$tdir/$tfile
19985
19986 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19987         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19988
19989         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19990         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19991
19992         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19993
19994         # Flush negative dentry cache
19995         touch $DIR/$tdir/$tfile
19996
19997         # We are not checking for any leaked references here, they'll
19998         # become evident next time we do cleanup with module unload.
19999         rm -rf $DIR/$tdir
20000 }
20001 run_test 183 "No crash or request leak in case of strange dispositions ========"
20002
20003 # test suite 184 is for LU-2016, LU-2017
20004 test_184a() {
20005         check_swap_layouts_support
20006
20007         dir0=$DIR/$tdir/$testnum
20008         test_mkdir -p -c1 $dir0
20009         ref1=/etc/passwd
20010         ref2=/etc/group
20011         file1=$dir0/f1
20012         file2=$dir0/f2
20013         $LFS setstripe -c1 $file1
20014         cp $ref1 $file1
20015         $LFS setstripe -c2 $file2
20016         cp $ref2 $file2
20017         gen1=$($LFS getstripe -g $file1)
20018         gen2=$($LFS getstripe -g $file2)
20019
20020         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20021         gen=$($LFS getstripe -g $file1)
20022         [[ $gen1 != $gen ]] ||
20023                 error "Layout generation on $file1 does not change"
20024         gen=$($LFS getstripe -g $file2)
20025         [[ $gen2 != $gen ]] ||
20026                 error "Layout generation on $file2 does not change"
20027
20028         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20029         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20030
20031         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20032 }
20033 run_test 184a "Basic layout swap"
20034
20035 test_184b() {
20036         check_swap_layouts_support
20037
20038         dir0=$DIR/$tdir/$testnum
20039         mkdir -p $dir0 || error "creating dir $dir0"
20040         file1=$dir0/f1
20041         file2=$dir0/f2
20042         file3=$dir0/f3
20043         dir1=$dir0/d1
20044         dir2=$dir0/d2
20045         mkdir $dir1 $dir2
20046         $LFS setstripe -c1 $file1
20047         $LFS setstripe -c2 $file2
20048         $LFS setstripe -c1 $file3
20049         chown $RUNAS_ID $file3
20050         gen1=$($LFS getstripe -g $file1)
20051         gen2=$($LFS getstripe -g $file2)
20052
20053         $LFS swap_layouts $dir1 $dir2 &&
20054                 error "swap of directories layouts should fail"
20055         $LFS swap_layouts $dir1 $file1 &&
20056                 error "swap of directory and file layouts should fail"
20057         $RUNAS $LFS swap_layouts $file1 $file2 &&
20058                 error "swap of file we cannot write should fail"
20059         $LFS swap_layouts $file1 $file3 &&
20060                 error "swap of file with different owner should fail"
20061         /bin/true # to clear error code
20062 }
20063 run_test 184b "Forbidden layout swap (will generate errors)"
20064
20065 test_184c() {
20066         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20067         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20068         check_swap_layouts_support
20069         check_swap_layout_no_dom $DIR
20070
20071         local dir0=$DIR/$tdir/$testnum
20072         mkdir -p $dir0 || error "creating dir $dir0"
20073
20074         local ref1=$dir0/ref1
20075         local ref2=$dir0/ref2
20076         local file1=$dir0/file1
20077         local file2=$dir0/file2
20078         # create a file large enough for the concurrent test
20079         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20080         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20081         echo "ref file size: ref1($(stat -c %s $ref1))," \
20082              "ref2($(stat -c %s $ref2))"
20083
20084         cp $ref2 $file2
20085         dd if=$ref1 of=$file1 bs=16k &
20086         local DD_PID=$!
20087
20088         # Make sure dd starts to copy file, but wait at most 5 seconds
20089         local loops=0
20090         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20091
20092         $LFS swap_layouts $file1 $file2
20093         local rc=$?
20094         wait $DD_PID
20095         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20096         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20097
20098         # how many bytes copied before swapping layout
20099         local copied=$(stat -c %s $file2)
20100         local remaining=$(stat -c %s $ref1)
20101         remaining=$((remaining - copied))
20102         echo "Copied $copied bytes before swapping layout..."
20103
20104         cmp -n $copied $file1 $ref2 | grep differ &&
20105                 error "Content mismatch [0, $copied) of ref2 and file1"
20106         cmp -n $copied $file2 $ref1 ||
20107                 error "Content mismatch [0, $copied) of ref1 and file2"
20108         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20109                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20110
20111         # clean up
20112         rm -f $ref1 $ref2 $file1 $file2
20113 }
20114 run_test 184c "Concurrent write and layout swap"
20115
20116 test_184d() {
20117         check_swap_layouts_support
20118         check_swap_layout_no_dom $DIR
20119         [ -z "$(which getfattr 2>/dev/null)" ] &&
20120                 skip_env "no getfattr command"
20121
20122         local file1=$DIR/$tdir/$tfile-1
20123         local file2=$DIR/$tdir/$tfile-2
20124         local file3=$DIR/$tdir/$tfile-3
20125         local lovea1
20126         local lovea2
20127
20128         mkdir -p $DIR/$tdir
20129         touch $file1 || error "create $file1 failed"
20130         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20131                 error "create $file2 failed"
20132         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20133                 error "create $file3 failed"
20134         lovea1=$(get_layout_param $file1)
20135
20136         $LFS swap_layouts $file2 $file3 ||
20137                 error "swap $file2 $file3 layouts failed"
20138         $LFS swap_layouts $file1 $file2 ||
20139                 error "swap $file1 $file2 layouts failed"
20140
20141         lovea2=$(get_layout_param $file2)
20142         echo "$lovea1"
20143         echo "$lovea2"
20144         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20145
20146         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20147         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20148 }
20149 run_test 184d "allow stripeless layouts swap"
20150
20151 test_184e() {
20152         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20153                 skip "Need MDS version at least 2.6.94"
20154         check_swap_layouts_support
20155         check_swap_layout_no_dom $DIR
20156         [ -z "$(which getfattr 2>/dev/null)" ] &&
20157                 skip_env "no getfattr command"
20158
20159         local file1=$DIR/$tdir/$tfile-1
20160         local file2=$DIR/$tdir/$tfile-2
20161         local file3=$DIR/$tdir/$tfile-3
20162         local lovea
20163
20164         mkdir -p $DIR/$tdir
20165         touch $file1 || error "create $file1 failed"
20166         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20167                 error "create $file2 failed"
20168         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20169                 error "create $file3 failed"
20170
20171         $LFS swap_layouts $file1 $file2 ||
20172                 error "swap $file1 $file2 layouts failed"
20173
20174         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20175         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20176
20177         echo 123 > $file1 || error "Should be able to write into $file1"
20178
20179         $LFS swap_layouts $file1 $file3 ||
20180                 error "swap $file1 $file3 layouts failed"
20181
20182         echo 123 > $file1 || error "Should be able to write into $file1"
20183
20184         rm -rf $file1 $file2 $file3
20185 }
20186 run_test 184e "Recreate layout after stripeless layout swaps"
20187
20188 test_184f() {
20189         # Create a file with name longer than sizeof(struct stat) ==
20190         # 144 to see if we can get chars from the file name to appear
20191         # in the returned striping. Note that 'f' == 0x66.
20192         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20193
20194         mkdir -p $DIR/$tdir
20195         mcreate $DIR/$tdir/$file
20196         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20197                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20198         fi
20199 }
20200 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20201
20202 test_185() { # LU-2441
20203         # LU-3553 - no volatile file support in old servers
20204         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20205                 skip "Need MDS version at least 2.3.60"
20206
20207         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20208         touch $DIR/$tdir/spoo
20209         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20210         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20211                 error "cannot create/write a volatile file"
20212         [ "$FILESET" == "" ] &&
20213         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20214                 error "FID is still valid after close"
20215
20216         multiop_bg_pause $DIR/$tdir Vw4096_c
20217         local multi_pid=$!
20218
20219         local OLD_IFS=$IFS
20220         IFS=":"
20221         local fidv=($fid)
20222         IFS=$OLD_IFS
20223         # assume that the next FID for this client is sequential, since stdout
20224         # is unfortunately eaten by multiop_bg_pause
20225         local n=$((${fidv[1]} + 1))
20226         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20227         if [ "$FILESET" == "" ]; then
20228                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20229                         error "FID is missing before close"
20230         fi
20231         kill -USR1 $multi_pid
20232         # 1 second delay, so if mtime change we will see it
20233         sleep 1
20234         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20235         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20236 }
20237 run_test 185 "Volatile file support"
20238
20239 function create_check_volatile() {
20240         local idx=$1
20241         local tgt
20242
20243         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20244         local PID=$!
20245         sleep 1
20246         local FID=$(cat /tmp/${tfile}.fid)
20247         [ "$FID" == "" ] && error "can't get FID for volatile"
20248         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20249         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20250         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20251         kill -USR1 $PID
20252         wait
20253         sleep 1
20254         cancel_lru_locks mdc # flush opencache
20255         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20256         return 0
20257 }
20258
20259 test_185a(){
20260         # LU-12516 - volatile creation via .lustre
20261         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20262                 skip "Need MDS version at least 2.3.55"
20263
20264         create_check_volatile 0
20265         [ $MDSCOUNT -lt 2 ] && return 0
20266
20267         # DNE case
20268         create_check_volatile 1
20269
20270         return 0
20271 }
20272 run_test 185a "Volatile file creation in .lustre/fid/"
20273
20274 test_187a() {
20275         remote_mds_nodsh && skip "remote MDS with nodsh"
20276         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20277                 skip "Need MDS version at least 2.3.0"
20278
20279         local dir0=$DIR/$tdir/$testnum
20280         mkdir -p $dir0 || error "creating dir $dir0"
20281
20282         local file=$dir0/file1
20283         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20284         stack_trap "rm -f $file"
20285         local dv1=$($LFS data_version $file)
20286         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20287         local dv2=$($LFS data_version $file)
20288         [[ $dv1 != $dv2 ]] ||
20289                 error "data version did not change on write $dv1 == $dv2"
20290 }
20291 run_test 187a "Test data version change"
20292
20293 test_187b() {
20294         remote_mds_nodsh && skip "remote MDS with nodsh"
20295         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20296                 skip "Need MDS version at least 2.3.0"
20297
20298         local dir0=$DIR/$tdir/$testnum
20299         mkdir -p $dir0 || error "creating dir $dir0"
20300
20301         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20302         [[ ${DV[0]} != ${DV[1]} ]] ||
20303                 error "data version did not change on write"\
20304                       " ${DV[0]} == ${DV[1]}"
20305
20306         # clean up
20307         rm -f $file1
20308 }
20309 run_test 187b "Test data version change on volatile file"
20310
20311 test_200() {
20312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20313         remote_mgs_nodsh && skip "remote MGS with nodsh"
20314         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20315
20316         local POOL=${POOL:-cea1}
20317         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20318         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20319         # Pool OST targets
20320         local first_ost=0
20321         local last_ost=$(($OSTCOUNT - 1))
20322         local ost_step=2
20323         local ost_list=$(seq $first_ost $ost_step $last_ost)
20324         local ost_range="$first_ost $last_ost $ost_step"
20325         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20326         local file_dir=$POOL_ROOT/file_tst
20327         local subdir=$test_path/subdir
20328         local rc=0
20329
20330         while : ; do
20331                 # former test_200a test_200b
20332                 pool_add $POOL                          || { rc=$? ; break; }
20333                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20334                 # former test_200c test_200d
20335                 mkdir -p $test_path
20336                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20337                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20338                 mkdir -p $subdir
20339                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20340                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20341                                                         || { rc=$? ; break; }
20342                 # former test_200e test_200f
20343                 local files=$((OSTCOUNT*3))
20344                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20345                                                         || { rc=$? ; break; }
20346                 pool_create_files $POOL $file_dir $files "$ost_list" \
20347                                                         || { rc=$? ; break; }
20348                 # former test_200g test_200h
20349                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20350                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20351
20352                 # former test_201a test_201b test_201c
20353                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20354
20355                 local f=$test_path/$tfile
20356                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20357                 pool_remove $POOL $f                    || { rc=$? ; break; }
20358                 break
20359         done
20360
20361         destroy_test_pools
20362
20363         return $rc
20364 }
20365 run_test 200 "OST pools"
20366
20367 # usage: default_attr <count | size | offset>
20368 default_attr() {
20369         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20370 }
20371
20372 # usage: check_default_stripe_attr
20373 check_default_stripe_attr() {
20374         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20375         case $1 in
20376         --stripe-count|-c)
20377                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20378         --stripe-size|-S)
20379                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20380         --stripe-index|-i)
20381                 EXPECTED=-1;;
20382         *)
20383                 error "unknown getstripe attr '$1'"
20384         esac
20385
20386         [ $ACTUAL == $EXPECTED ] ||
20387                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20388 }
20389
20390 test_204a() {
20391         test_mkdir $DIR/$tdir
20392         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20393
20394         check_default_stripe_attr --stripe-count
20395         check_default_stripe_attr --stripe-size
20396         check_default_stripe_attr --stripe-index
20397 }
20398 run_test 204a "Print default stripe attributes"
20399
20400 test_204b() {
20401         test_mkdir $DIR/$tdir
20402         $LFS setstripe --stripe-count 1 $DIR/$tdir
20403
20404         check_default_stripe_attr --stripe-size
20405         check_default_stripe_attr --stripe-index
20406 }
20407 run_test 204b "Print default stripe size and offset"
20408
20409 test_204c() {
20410         test_mkdir $DIR/$tdir
20411         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20412
20413         check_default_stripe_attr --stripe-count
20414         check_default_stripe_attr --stripe-index
20415 }
20416 run_test 204c "Print default stripe count and offset"
20417
20418 test_204d() {
20419         test_mkdir $DIR/$tdir
20420         $LFS setstripe --stripe-index 0 $DIR/$tdir
20421
20422         check_default_stripe_attr --stripe-count
20423         check_default_stripe_attr --stripe-size
20424 }
20425 run_test 204d "Print default stripe count and size"
20426
20427 test_204e() {
20428         test_mkdir $DIR/$tdir
20429         $LFS setstripe -d $DIR/$tdir
20430
20431         # LU-16904 check if root is set as PFL layout
20432         local numcomp=$($LFS getstripe --component-count $MOUNT)
20433
20434         if [[ $numcomp -gt 0 ]]; then
20435                 check_default_stripe_attr --stripe-count
20436         else
20437                 check_default_stripe_attr --stripe-count --raw
20438         fi
20439         check_default_stripe_attr --stripe-size --raw
20440         check_default_stripe_attr --stripe-index --raw
20441 }
20442 run_test 204e "Print raw stripe attributes"
20443
20444 test_204f() {
20445         test_mkdir $DIR/$tdir
20446         $LFS setstripe --stripe-count 1 $DIR/$tdir
20447
20448         check_default_stripe_attr --stripe-size --raw
20449         check_default_stripe_attr --stripe-index --raw
20450 }
20451 run_test 204f "Print raw stripe size and offset"
20452
20453 test_204g() {
20454         test_mkdir $DIR/$tdir
20455         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20456
20457         check_default_stripe_attr --stripe-count --raw
20458         check_default_stripe_attr --stripe-index --raw
20459 }
20460 run_test 204g "Print raw stripe count and offset"
20461
20462 test_204h() {
20463         test_mkdir $DIR/$tdir
20464         $LFS setstripe --stripe-index 0 $DIR/$tdir
20465
20466         check_default_stripe_attr --stripe-count --raw
20467         check_default_stripe_attr --stripe-size --raw
20468 }
20469 run_test 204h "Print raw stripe count and size"
20470
20471 # Figure out which job scheduler is being used, if any,
20472 # or use a fake one
20473 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20474         JOBENV=SLURM_JOB_ID
20475 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20476         JOBENV=LSB_JOBID
20477 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20478         JOBENV=PBS_JOBID
20479 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20480         JOBENV=LOADL_STEP_ID
20481 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20482         JOBENV=JOB_ID
20483 else
20484         $LCTL list_param jobid_name > /dev/null 2>&1
20485         if [ $? -eq 0 ]; then
20486                 JOBENV=nodelocal
20487         else
20488                 JOBENV=FAKE_JOBID
20489         fi
20490 fi
20491 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20492
20493 verify_jobstats() {
20494         local cmd=($1)
20495         shift
20496         local facets="$@"
20497
20498 # we don't really need to clear the stats for this test to work, since each
20499 # command has a unique jobid, but it makes debugging easier if needed.
20500 #       for facet in $facets; do
20501 #               local dev=$(convert_facet2label $facet)
20502 #               # clear old jobstats
20503 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20504 #       done
20505
20506         # use a new JobID for each test, or we might see an old one
20507         [ "$JOBENV" = "FAKE_JOBID" ] &&
20508                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20509
20510         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20511
20512         [ "$JOBENV" = "nodelocal" ] && {
20513                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20514                 $LCTL set_param jobid_name=$FAKE_JOBID
20515                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20516         }
20517
20518         log "Test: ${cmd[*]}"
20519         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20520
20521         if [ $JOBENV = "FAKE_JOBID" ]; then
20522                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20523         else
20524                 ${cmd[*]}
20525         fi
20526
20527         # all files are created on OST0000
20528         for facet in $facets; do
20529                 local stats="*.$(convert_facet2label $facet).job_stats"
20530
20531                 # strip out libtool wrappers for in-tree executables
20532                 if (( $(do_facet $facet lctl get_param $stats |
20533                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20534                         do_facet $facet lctl get_param $stats
20535                         error "No jobstats for $JOBVAL found on $facet::$stats"
20536                 fi
20537         done
20538 }
20539
20540 jobstats_set() {
20541         local new_jobenv=$1
20542
20543         set_persistent_param_and_check client "jobid_var" \
20544                 "$FSNAME.sys.jobid_var" $new_jobenv
20545 }
20546
20547 test_205a() { # Job stats
20548         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20549         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20550                 skip "Need MDS version with at least 2.7.1"
20551         remote_mgs_nodsh && skip "remote MGS with nodsh"
20552         remote_mds_nodsh && skip "remote MDS with nodsh"
20553         remote_ost_nodsh && skip "remote OST with nodsh"
20554         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20555                 skip "Server doesn't support jobstats"
20556         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20557
20558         local old_jobenv=$($LCTL get_param -n jobid_var)
20559         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20560         stack_trap "jobstats_set $old_jobenv" EXIT
20561
20562         changelog_register
20563
20564         local old_jobid_name=$($LCTL get_param jobid_name)
20565         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20566
20567         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20568                                 mdt.*.job_cleanup_interval | head -n 1)
20569         local new_interval=5
20570         do_facet $SINGLEMDS \
20571                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20572         stack_trap "do_facet $SINGLEMDS \
20573                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20574         local start=$SECONDS
20575
20576         local cmd
20577         # mkdir
20578         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20579         verify_jobstats "$cmd" "$SINGLEMDS"
20580         # rmdir
20581         cmd="rmdir $DIR/$tdir"
20582         verify_jobstats "$cmd" "$SINGLEMDS"
20583         # mkdir on secondary MDT
20584         if [ $MDSCOUNT -gt 1 ]; then
20585                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20586                 verify_jobstats "$cmd" "mds2"
20587         fi
20588         # mknod
20589         cmd="mknod $DIR/$tfile c 1 3"
20590         verify_jobstats "$cmd" "$SINGLEMDS"
20591         # unlink
20592         cmd="rm -f $DIR/$tfile"
20593         verify_jobstats "$cmd" "$SINGLEMDS"
20594         # create all files on OST0000 so verify_jobstats can find OST stats
20595         # open & close
20596         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20597         verify_jobstats "$cmd" "$SINGLEMDS"
20598         # setattr
20599         cmd="touch $DIR/$tfile"
20600         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20601         # write
20602         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20603         verify_jobstats "$cmd" "ost1"
20604         # read
20605         cancel_lru_locks osc
20606         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20607         verify_jobstats "$cmd" "ost1"
20608         # truncate
20609         cmd="$TRUNCATE $DIR/$tfile 0"
20610         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20611         # rename
20612         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20613         verify_jobstats "$cmd" "$SINGLEMDS"
20614         # jobstats expiry - sleep until old stats should be expired
20615         local left=$((new_interval + 5 - (SECONDS - start)))
20616         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20617                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20618                         "0" $left
20619         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20620         verify_jobstats "$cmd" "$SINGLEMDS"
20621         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20622             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20623
20624         # Ensure that jobid are present in changelog (if supported by MDS)
20625         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20626                 changelog_dump | tail -10
20627                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20628                 [ $jobids -eq 9 ] ||
20629                         error "Wrong changelog jobid count $jobids != 9"
20630
20631                 # LU-5862
20632                 JOBENV="disable"
20633                 jobstats_set $JOBENV
20634                 touch $DIR/$tfile
20635                 changelog_dump | grep $tfile
20636                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20637                 [ $jobids -eq 0 ] ||
20638                         error "Unexpected jobids when jobid_var=$JOBENV"
20639         fi
20640
20641         # test '%j' access to environment variable - if supported
20642         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20643                 JOBENV="JOBCOMPLEX"
20644                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20645
20646                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20647         fi
20648
20649         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20650                 JOBENV="JOBCOMPLEX"
20651                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20652
20653                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20654         fi
20655
20656         # test '%j' access to per-session jobid - if supported
20657         if lctl list_param jobid_this_session > /dev/null 2>&1
20658         then
20659                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20660                 lctl set_param jobid_this_session=$USER
20661
20662                 JOBENV="JOBCOMPLEX"
20663                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20664
20665                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20666         fi
20667 }
20668 run_test 205a "Verify job stats"
20669
20670 # LU-13117, LU-13597, LU-16599
20671 test_205b() {
20672         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20673                 skip "Need MDS version at least 2.13.54.91"
20674
20675         local job_stats="mdt.*.job_stats"
20676         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20677
20678         do_facet mds1 $LCTL set_param $job_stats=clear
20679
20680         # Setting jobid_var to USER might not be supported
20681         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20682         $LCTL set_param jobid_var=USER || true
20683         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20684         $LCTL set_param jobid_name="%j.%e.%u"
20685
20686         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20687         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20688                 { do_facet mds1 $LCTL get_param $job_stats;
20689                   error "Unexpected jobid found"; }
20690         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20691                 { do_facet mds1 $LCTL get_param $job_stats;
20692                   error "wrong job_stats format found"; }
20693
20694         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20695                 echo "MDS does not yet escape jobid" && return 0
20696
20697         mkdir_on_mdt0 $DIR/$tdir
20698         $LCTL set_param jobid_var=TEST205b
20699         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20700         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20701                       awk '/has\\x20sp/ {print $3}')
20702         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20703                   error "jobid not escaped"; }
20704
20705         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20706                 # need to run such a command on mds1:
20707                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20708                 #
20709                 # there might be multiple MDTs on single mds server, so need to
20710                 # specifiy MDT0000. Or the command will fail due to other MDTs
20711                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20712                         error "cannot clear escaped jobid in job_stats";
20713         else
20714                 echo "MDS does not support clearing escaped jobid"
20715         fi
20716 }
20717 run_test 205b "Verify job stats jobid and output format"
20718
20719 # LU-13733
20720 test_205c() {
20721         $LCTL set_param llite.*.stats=0
20722         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20723         $LCTL get_param llite.*.stats
20724         $LCTL get_param llite.*.stats | grep \
20725                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20726                         error "wrong client stats format found"
20727 }
20728 run_test 205c "Verify client stats format"
20729
20730 test_205d() {
20731         local file=$DIR/$tdir/$tfile
20732
20733         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20734                 skip "need lustre >= 2.15.53 for lljobstat"
20735         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20736                 skip "need lustre >= 2.15.53 for lljobstat"
20737         verify_yaml_available || skip_env "YAML verification not installed"
20738
20739         test_mkdir -i 0 $DIR/$tdir
20740         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20741         stack_trap "rm -rf $DIR/$tdir"
20742
20743         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20744                 error "failed to write data to $file"
20745         mv $file $file.2
20746
20747         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20748         echo -n 'verify rename_stats...'
20749         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20750                 verify_yaml || error "rename_stats is not valid YAML"
20751         echo " OK"
20752
20753         echo -n 'verify mdt job_stats...'
20754         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20755                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20756         echo " OK"
20757
20758         echo -n 'verify ost job_stats...'
20759         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20760                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20761         echo " OK"
20762 }
20763 run_test 205d "verify the format of some stats files"
20764
20765 test_205e() {
20766         local ops_comma
20767         local file=$DIR/$tdir/$tfile
20768         local -a cli_params
20769
20770         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20771                 skip "need lustre >= 2.15.53 for lljobstat"
20772         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20773                 skip "need lustre >= 2.15.53 for lljobstat"
20774         verify_yaml_available || skip_env "YAML verification not installed"
20775
20776         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20777         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20778         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20779
20780         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20781         stack_trap "rm -rf $DIR/$tdir"
20782
20783         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20784                 error "failed to create $file on ost1"
20785         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20786                 error "failed to write data to $file"
20787
20788         do_facet mds1 "$LCTL get_param *.*.job_stats"
20789         do_facet ost1 "$LCTL get_param *.*.job_stats"
20790
20791         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20792         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20793                 error "The output of lljobstat is not an valid YAML"
20794
20795         # verify that job dd.0 does exist and has some ops on ost1
20796         # typically this line is like:
20797         # - 205e.dd.0:            {ops: 20, ...}
20798         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20799                     awk '$2=="205e.dd.0:" {print $4}')
20800
20801         (( ${ops_comma%,} >= 10 )) ||
20802                 error "cannot find job 205e.dd.0 with ops >= 10"
20803 }
20804 run_test 205e "verify the output of lljobstat"
20805
20806 test_205f() {
20807         verify_yaml_available || skip_env "YAML verification not installed"
20808
20809         # check both qos_ost_weights and qos_mdt_weights
20810         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20811         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20812                 error "qos_ost_weights is not valid YAML"
20813 }
20814 run_test 205f "verify qos_ost_weights YAML format "
20815
20816 __test_205_jobstats_dump() {
20817         local -a pids
20818         local nbr_instance=$1
20819
20820         while true; do
20821                 if (( ${#pids[@]} >= nbr_instance )); then
20822                         wait ${pids[@]}
20823                         pids=()
20824                 fi
20825
20826                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20827                 pids+=( $! )
20828         done
20829 }
20830
20831 __test_205_cleanup() {
20832         kill $@
20833         # Clear all job entries
20834         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20835 }
20836
20837 test_205g() {
20838         local -a mds1_params
20839         local -a cli_params
20840         local pids
20841         local interval=5
20842
20843         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20844         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20845         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20846
20847         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20848         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20849         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20850
20851         # start jobs loop
20852         export TEST205G_ID=205g
20853         stack_trap "unset TEST205G_ID" EXIT
20854         while true; do
20855                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20856         done & pids="$! "
20857
20858         __test_205_jobstats_dump 4 & pids+="$! "
20859         stack_trap "__test_205_cleanup $pids" EXIT INT
20860
20861         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20862 }
20863 run_test 205g "stress test for job_stats procfile"
20864
20865 test_205h() {
20866         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20867                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20868         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20869
20870         local dir=$DIR/$tdir
20871         local f=$dir/$tfile
20872         local f2=$dir/$tfile-2
20873         local f3=$dir/$tfile-3
20874         local subdir=$DIR/dir
20875         local val
20876
20877         local mdts=$(comma_list $(mdts_nodes))
20878         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20879         local client_saved=$($LCTL get_param -n jobid_var)
20880
20881         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20882         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20883
20884         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20885                 error "failed to set job_xattr parameter to user.job"
20886         $LCTL set_param jobid_var=procname.uid ||
20887                 error "failed to set jobid_var parameter"
20888
20889         test_mkdir $dir
20890
20891         touch $f
20892         val=$(getfattr -n user.job $f | grep user.job)
20893         [[ $val = user.job=\"touch.0\" ]] ||
20894                 error "expected user.job=\"touch.0\", got '$val'"
20895
20896         mkdir $subdir
20897         val=$(getfattr -n user.job $subdir | grep user.job)
20898         [[ $val = user.job=\"mkdir.0\" ]] ||
20899                 error "expected user.job=\"mkdir.0\", got '$val'"
20900
20901         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20902                 error "failed to set job_xattr parameter to NONE"
20903
20904         touch $f2
20905         val=$(getfattr -d $f2)
20906         [[ -z $val ]] ||
20907                 error "expected no user xattr, got '$val'"
20908
20909         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20910                 error "failed to set job_xattr parameter to trusted.job"
20911
20912         touch $f3
20913         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20914         [[ $val = trusted.job=\"touch.0\" ]] ||
20915                 error "expected trusted.job=\"touch.0\", got '$val'"
20916 }
20917 run_test 205h "check jobid xattr is stored correctly"
20918
20919 test_205i() {
20920         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20921                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20922
20923         local mdts=$(comma_list $(mdts_nodes))
20924         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20925
20926         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20927
20928         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20929                 error "failed to set mdt.*.job_xattr to user.1234567"
20930
20931         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20932                 error "failed to reject too long job_xattr name"
20933
20934         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20935                 error "failed to reject job_xattr name in bad format"
20936
20937         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20938                 error "failed to reject job_xattr name with invalid character"
20939
20940         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20941                         xargs $LCTL set_param" &&
20942                 error "failed to reject job_xattr name with non-ascii character"
20943
20944         return 0
20945 }
20946 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20947
20948 # LU-1480, LU-1773 and LU-1657
20949 test_206() {
20950         mkdir -p $DIR/$tdir
20951         $LFS setstripe -c -1 $DIR/$tdir
20952 #define OBD_FAIL_LOV_INIT 0x1403
20953         $LCTL set_param fail_loc=0xa0001403
20954         $LCTL set_param fail_val=1
20955         touch $DIR/$tdir/$tfile || true
20956 }
20957 run_test 206 "fail lov_init_raid0() doesn't lbug"
20958
20959 test_207a() {
20960         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20961         local fsz=`stat -c %s $DIR/$tfile`
20962         cancel_lru_locks mdc
20963
20964         # do not return layout in getattr intent
20965 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20966         $LCTL set_param fail_loc=0x170
20967         local sz=`stat -c %s $DIR/$tfile`
20968
20969         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20970
20971         rm -rf $DIR/$tfile
20972 }
20973 run_test 207a "can refresh layout at glimpse"
20974
20975 test_207b() {
20976         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20977         local cksum=`md5sum $DIR/$tfile`
20978         local fsz=`stat -c %s $DIR/$tfile`
20979         cancel_lru_locks mdc
20980         cancel_lru_locks osc
20981
20982         # do not return layout in getattr intent
20983 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20984         $LCTL set_param fail_loc=0x171
20985
20986         # it will refresh layout after the file is opened but before read issues
20987         echo checksum is "$cksum"
20988         echo "$cksum" |md5sum -c --quiet || error "file differs"
20989
20990         rm -rf $DIR/$tfile
20991 }
20992 run_test 207b "can refresh layout at open"
20993
20994 test_208() {
20995         # FIXME: in this test suite, only RD lease is used. This is okay
20996         # for now as only exclusive open is supported. After generic lease
20997         # is done, this test suite should be revised. - Jinshan
20998
20999         remote_mds_nodsh && skip "remote MDS with nodsh"
21000         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21001                 skip "Need MDS version at least 2.4.52"
21002
21003         echo "==== test 1: verify get lease work"
21004         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21005
21006         echo "==== test 2: verify lease can be broken by upcoming open"
21007         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21008         local PID=$!
21009         sleep 2
21010
21011         $MULTIOP $DIR/$tfile oO_RDWR:c
21012         kill -USR1 $PID && wait $PID || error "break lease error"
21013
21014         echo "==== test 3: verify lease can't be granted if an open already exists"
21015         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21016         local PID=$!
21017         sleep 2
21018
21019         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21020         kill -USR1 $PID && wait $PID || error "open file error"
21021
21022         echo "==== test 4: lease can sustain over recovery"
21023         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21024         PID=$!
21025         sleep 2
21026
21027         fail mds1
21028
21029         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21030
21031         echo "==== test 5: lease broken can't be regained by replay"
21032         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21033         PID=$!
21034         sleep 2
21035
21036         # open file to break lease and then recovery
21037         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21038         fail mds1
21039
21040         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21041
21042         rm -f $DIR/$tfile
21043 }
21044 run_test 208 "Exclusive open"
21045
21046 test_209() {
21047         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21048                 skip_env "must have disp_stripe"
21049
21050         touch $DIR/$tfile
21051         sync; sleep 5; sync;
21052
21053         echo 3 > /proc/sys/vm/drop_caches
21054         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21055                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21056         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21057
21058         # open/close 500 times
21059         for i in $(seq 500); do
21060                 cat $DIR/$tfile
21061         done
21062
21063         echo 3 > /proc/sys/vm/drop_caches
21064         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21065                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21066         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21067
21068         echo "before: $req_before, after: $req_after"
21069         [ $((req_after - req_before)) -ge 300 ] &&
21070                 error "open/close requests are not freed"
21071         return 0
21072 }
21073 run_test 209 "read-only open/close requests should be freed promptly"
21074
21075 test_210() {
21076         local pid
21077
21078         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21079         pid=$!
21080         sleep 1
21081
21082         $LFS getstripe $DIR/$tfile
21083         kill -USR1 $pid
21084         wait $pid || error "multiop failed"
21085
21086         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21087         pid=$!
21088         sleep 1
21089
21090         $LFS getstripe $DIR/$tfile
21091         kill -USR1 $pid
21092         wait $pid || error "multiop failed"
21093 }
21094 run_test 210 "lfs getstripe does not break leases"
21095
21096 function test_211() {
21097         local PID
21098         local id
21099         local rc
21100
21101         stack_trap "rm -f $DIR/$tfile" EXIT
21102         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21103                 error "can't create file"
21104         $LFS mirror extend -N $DIR/$tfile ||
21105                 error "can't create a replica"
21106         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21107         $LFS getstripe $DIR/$tfile
21108         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21109         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21110
21111         $MULTIOP $DIR/$tfile OeW_E+eUc &
21112         PID=$!
21113         sleep 0.3
21114
21115         id=$($LFS getstripe $DIR/$tfile |
21116                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21117         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21118                 error "removed last in-sync replica?"
21119
21120         kill -USR1 $PID
21121         wait $PID
21122         (( $? == 0 )) || error "failed split broke the lease"
21123 }
21124 run_test 211 "failed mirror split doesn't break write lease"
21125
21126 test_212() {
21127         size=`date +%s`
21128         size=$((size % 8192 + 1))
21129         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21130         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21131         rm -f $DIR/f212 $DIR/f212.xyz
21132 }
21133 run_test 212 "Sendfile test ============================================"
21134
21135 test_213() {
21136         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21137         cancel_lru_locks osc
21138         lctl set_param fail_loc=0x8000040f
21139         # generate a read lock
21140         cat $DIR/$tfile > /dev/null
21141         # write to the file, it will try to cancel the above read lock.
21142         cat /etc/hosts >> $DIR/$tfile
21143 }
21144 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21145
21146 test_214() { # for bug 20133
21147         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21148         for (( i=0; i < 340; i++ )) ; do
21149                 touch $DIR/$tdir/d214c/a$i
21150         done
21151
21152         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21153         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21154         ls $DIR/d214c || error "ls $DIR/d214c failed"
21155         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21156         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21157 }
21158 run_test 214 "hash-indexed directory test - bug 20133"
21159
21160 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21161 create_lnet_proc_files() {
21162         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21163 }
21164
21165 # counterpart of create_lnet_proc_files
21166 remove_lnet_proc_files() {
21167         rm -f $TMP/lnet_$1.sys
21168 }
21169
21170 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21171 # 3rd arg as regexp for body
21172 check_lnet_proc_stats() {
21173         local l=$(cat "$TMP/lnet_$1" |wc -l)
21174         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21175
21176         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21177 }
21178
21179 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21180 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21181 # optional and can be regexp for 2nd line (lnet.routes case)
21182 check_lnet_proc_entry() {
21183         local blp=2          # blp stands for 'position of 1st line of body'
21184         [ -z "$5" ] || blp=3 # lnet.routes case
21185
21186         local l=$(cat "$TMP/lnet_$1" |wc -l)
21187         # subtracting one from $blp because the body can be empty
21188         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21189
21190         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21191                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21192
21193         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21194                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21195
21196         # bail out if any unexpected line happened
21197         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21198         [ "$?" != 0 ] || error "$2 misformatted"
21199 }
21200
21201 test_215() { # for bugs 18102, 21079, 21517
21202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21203
21204         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21205         local P='[1-9][0-9]*'           # positive numeric
21206         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21207         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21208         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21209         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21210         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21211         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21212
21213         local L1 # regexp for 1st line
21214         local L2 # regexp for 2nd line (optional)
21215         local BR # regexp for the rest (body)
21216
21217         # lnet.stats should look as 11 space-separated non-negative numerics
21218         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21219         create_lnet_proc_files "stats"
21220         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21221         remove_lnet_proc_files "stats"
21222
21223         # lnet.routes should look like this:
21224         # Routing disabled/enabled
21225         # net hops priority state router
21226         # where net is a string like tcp0, hops > 0, priority >= 0,
21227         # state is up/down,
21228         # router is a string like 192.168.1.1@tcp2
21229         L1="^Routing (disabled|enabled)$"
21230         L2="^net +hops +priority +state +router$"
21231         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21232         create_lnet_proc_files "routes"
21233         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21234         remove_lnet_proc_files "routes"
21235
21236         # lnet.routers should look like this:
21237         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21238         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21239         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21240         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21241         L1="^ref +rtr_ref +alive +router$"
21242         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21243         create_lnet_proc_files "routers"
21244         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21245         remove_lnet_proc_files "routers"
21246
21247         # lnet.peers should look like this:
21248         # nid refs state last max rtr min tx min queue
21249         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21250         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21251         # numeric (0 or >0 or <0), queue >= 0.
21252         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21253         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21254         create_lnet_proc_files "peers"
21255         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21256         remove_lnet_proc_files "peers"
21257
21258         # lnet.buffers  should look like this:
21259         # pages count credits min
21260         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21261         L1="^pages +count +credits +min$"
21262         BR="^ +$N +$N +$I +$I$"
21263         create_lnet_proc_files "buffers"
21264         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21265         remove_lnet_proc_files "buffers"
21266
21267         # lnet.nis should look like this:
21268         # nid status alive refs peer rtr max tx min
21269         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21270         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21271         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21272         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21273         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21274         create_lnet_proc_files "nis"
21275         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21276         remove_lnet_proc_files "nis"
21277
21278         # can we successfully write to lnet.stats?
21279         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21280 }
21281 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21282
21283 test_216() { # bug 20317
21284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21285         remote_ost_nodsh && skip "remote OST with nodsh"
21286
21287         local node
21288         local facets=$(get_facets OST)
21289         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21290
21291         save_lustre_params client "osc.*.contention_seconds" > $p
21292         save_lustre_params $facets \
21293                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21294         save_lustre_params $facets \
21295                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21296         save_lustre_params $facets \
21297                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21298         clear_stats osc.*.osc_stats
21299
21300         # agressive lockless i/o settings
21301         do_nodes $(comma_list $(osts_nodes)) \
21302                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21303                         ldlm.namespaces.filter-*.contended_locks=0 \
21304                         ldlm.namespaces.filter-*.contention_seconds=60"
21305         lctl set_param -n osc.*.contention_seconds=60
21306
21307         $DIRECTIO write $DIR/$tfile 0 10 4096
21308         $CHECKSTAT -s 40960 $DIR/$tfile
21309
21310         # disable lockless i/o
21311         do_nodes $(comma_list $(osts_nodes)) \
21312                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21313                         ldlm.namespaces.filter-*.contended_locks=32 \
21314                         ldlm.namespaces.filter-*.contention_seconds=0"
21315         lctl set_param -n osc.*.contention_seconds=0
21316         clear_stats osc.*.osc_stats
21317
21318         dd if=/dev/zero of=$DIR/$tfile count=0
21319         $CHECKSTAT -s 0 $DIR/$tfile
21320
21321         restore_lustre_params <$p
21322         rm -f $p
21323         rm $DIR/$tfile
21324 }
21325 run_test 216 "check lockless direct write updates file size and kms correctly"
21326
21327 test_217() { # bug 22430
21328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21329
21330         local node
21331
21332         for node in $(nodes_list); do
21333                 local nid=$(host_nids_address $node $NETTYPE)
21334                 local node_ip=$(do_node $node getent ahostsv4 $node |
21335                                 awk '{ print $1; exit; }')
21336
21337                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21338                 # if hostname matches any NID, use hostname for better testing
21339                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21340                         echo "lctl ping node $node@$NETTYPE"
21341                         lctl ping $node@$NETTYPE ||
21342                                 error "ping $node@$NETTYPE failed rc=$?"
21343                 else # otherwise, at least test 'lctl ping' is working
21344                         echo "lctl ping nid $(h2nettype $nid)"
21345                         lctl ping $(h2nettype $nid) ||
21346                                 error "ping $(h2nettype $nid) failed rc=$?"
21347                         echo "skipping $node (no hyphen detected)"
21348                 fi
21349         done
21350
21351         return 0
21352 }
21353 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21354
21355 test_218() {
21356         # do directio so as not to populate the page cache
21357         log "creating a 10 Mb file"
21358         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21359                 error "multiop failed while creating a file"
21360         log "starting reads"
21361         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21362         log "truncating the file"
21363         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21364                 error "multiop failed while truncating the file"
21365         log "killing dd"
21366         kill %+ || true # reads might have finished
21367         echo "wait until dd is finished"
21368         wait
21369         log "removing the temporary file"
21370         rm -rf $DIR/$tfile || error "tmp file removal failed"
21371 }
21372 run_test 218 "parallel read and truncate should not deadlock"
21373
21374 test_219() {
21375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21376
21377         # write one partial page
21378         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21379         # set no grant so vvp_io_commit_write will do sync write
21380         $LCTL set_param fail_loc=0x411
21381         # write a full page at the end of file
21382         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21383
21384         $LCTL set_param fail_loc=0
21385         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21386         $LCTL set_param fail_loc=0x411
21387         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21388
21389         # LU-4201
21390         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21391         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21392 }
21393 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21394
21395 test_220() { #LU-325
21396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21397         remote_ost_nodsh && skip "remote OST with nodsh"
21398         remote_mds_nodsh && skip "remote MDS with nodsh"
21399         remote_mgs_nodsh && skip "remote MGS with nodsh"
21400
21401         local OSTIDX=0
21402
21403         # create on MDT0000 so the last_id and next_id are correct
21404         mkdir_on_mdt0 $DIR/$tdir
21405         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21406         OST=${OST%_UUID}
21407
21408         # on the mdt's osc
21409         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21410         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21411                         osp.$mdtosc_proc1.prealloc_last_id)
21412         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21413                         osp.$mdtosc_proc1.prealloc_next_id)
21414
21415         $LFS df -i
21416
21417         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21418         #define OBD_FAIL_OST_ENOINO              0x229
21419         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21420         create_pool $FSNAME.$TESTNAME || return 1
21421         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21422
21423         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21424
21425         MDSOBJS=$((last_id - next_id))
21426         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21427
21428         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21429         echo "OST still has $count kbytes free"
21430
21431         echo "create $MDSOBJS files @next_id..."
21432         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21433
21434         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21435                         osp.$mdtosc_proc1.prealloc_last_id)
21436         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21437                         osp.$mdtosc_proc1.prealloc_next_id)
21438
21439         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21440         $LFS df -i
21441
21442         echo "cleanup..."
21443
21444         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21445         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21446
21447         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21448                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21449         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21450                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21451         echo "unlink $MDSOBJS files @$next_id..."
21452         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21453 }
21454 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21455
21456 test_221() {
21457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21458
21459         dd if=`which date` of=$MOUNT/date oflag=sync
21460         chmod +x $MOUNT/date
21461
21462         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21463         $LCTL set_param fail_loc=0x80001401
21464
21465         $MOUNT/date > /dev/null
21466         rm -f $MOUNT/date
21467 }
21468 run_test 221 "make sure fault and truncate race to not cause OOM"
21469
21470 test_222a () {
21471         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21472
21473         rm -rf $DIR/$tdir
21474         test_mkdir $DIR/$tdir
21475         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21476         createmany -o $DIR/$tdir/$tfile 10
21477         cancel_lru_locks mdc
21478         cancel_lru_locks osc
21479         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21480         $LCTL set_param fail_loc=0x31a
21481         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21482         $LCTL set_param fail_loc=0
21483         rm -r $DIR/$tdir
21484 }
21485 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21486
21487 test_222b () {
21488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21489
21490         rm -rf $DIR/$tdir
21491         test_mkdir $DIR/$tdir
21492         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21493         createmany -o $DIR/$tdir/$tfile 10
21494         cancel_lru_locks mdc
21495         cancel_lru_locks osc
21496         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21497         $LCTL set_param fail_loc=0x31a
21498         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21499         $LCTL set_param fail_loc=0
21500 }
21501 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21502
21503 test_223 () {
21504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21505
21506         rm -rf $DIR/$tdir
21507         test_mkdir $DIR/$tdir
21508         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21509         createmany -o $DIR/$tdir/$tfile 10
21510         cancel_lru_locks mdc
21511         cancel_lru_locks osc
21512         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21513         $LCTL set_param fail_loc=0x31b
21514         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21515         $LCTL set_param fail_loc=0
21516         rm -r $DIR/$tdir
21517 }
21518 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21519
21520 test_224a() { # LU-1039, MRP-303
21521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21522         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21523         $LCTL set_param fail_loc=0x508
21524         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21525         $LCTL set_param fail_loc=0
21526         df $DIR
21527 }
21528 run_test 224a "Don't panic on bulk IO failure"
21529
21530 test_224bd_sub() { # LU-1039, MRP-303
21531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21532         local timeout=$1
21533
21534         shift
21535         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21536
21537         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21538
21539         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21540         cancel_lru_locks osc
21541         set_checksums 0
21542         stack_trap "set_checksums $ORIG_CSUM" EXIT
21543         local at_max_saved=0
21544
21545         # adaptive timeouts may prevent seeing the issue
21546         if at_is_enabled; then
21547                 at_max_saved=$(at_max_get mds)
21548                 at_max_set 0 mds client
21549                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21550         fi
21551
21552         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21553         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21554         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21555
21556         do_facet ost1 $LCTL set_param fail_loc=0
21557         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21558         df $DIR
21559 }
21560
21561 test_224b() {
21562         test_224bd_sub 3 error "dd failed"
21563 }
21564 run_test 224b "Don't panic on bulk IO failure"
21565
21566 test_224c() { # LU-6441
21567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21568         remote_mds_nodsh && skip "remote MDS with nodsh"
21569
21570         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21571         save_writethrough $p
21572         set_cache writethrough on
21573
21574         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21575         local at_max=$($LCTL get_param -n at_max)
21576         local timeout=$($LCTL get_param -n timeout)
21577         local test_at="at_max"
21578         local param_at="$FSNAME.sys.at_max"
21579         local test_timeout="timeout"
21580         local param_timeout="$FSNAME.sys.timeout"
21581
21582         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21583
21584         set_persistent_param_and_check client "$test_at" "$param_at" 0
21585         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21586
21587         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21588         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21589         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21590         stack_trap "rm -f $DIR/$tfile"
21591         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21592         sync
21593         do_facet ost1 "$LCTL set_param fail_loc=0"
21594
21595         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21596         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21597                 $timeout
21598
21599         $LCTL set_param -n $pages_per_rpc
21600         restore_lustre_params < $p
21601         rm -f $p
21602 }
21603 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21604
21605 test_224d() { # LU-11169
21606         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21607 }
21608 run_test 224d "Don't corrupt data on bulk IO timeout"
21609
21610 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21611 test_225a () {
21612         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21613         if [ -z ${MDSSURVEY} ]; then
21614                 skip_env "mds-survey not found"
21615         fi
21616         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21617                 skip "Need MDS version at least 2.2.51"
21618
21619         local mds=$(facet_host $SINGLEMDS)
21620         local target=$(do_nodes $mds 'lctl dl' |
21621                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21622
21623         local cmd1="file_count=1000 thrhi=4"
21624         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21625         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21626         local cmd="$cmd1 $cmd2 $cmd3"
21627
21628         rm -f ${TMP}/mds_survey*
21629         echo + $cmd
21630         eval $cmd || error "mds-survey with zero-stripe failed"
21631         cat ${TMP}/mds_survey*
21632         rm -f ${TMP}/mds_survey*
21633 }
21634 run_test 225a "Metadata survey sanity with zero-stripe"
21635
21636 test_225b () {
21637         if [ -z ${MDSSURVEY} ]; then
21638                 skip_env "mds-survey not found"
21639         fi
21640         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21641                 skip "Need MDS version at least 2.2.51"
21642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21643         remote_mds_nodsh && skip "remote MDS with nodsh"
21644         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21645                 skip_env "Need to mount OST to test"
21646         fi
21647
21648         local mds=$(facet_host $SINGLEMDS)
21649         local target=$(do_nodes $mds 'lctl dl' |
21650                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21651
21652         local cmd1="file_count=1000 thrhi=4"
21653         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21654         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21655         local cmd="$cmd1 $cmd2 $cmd3"
21656
21657         rm -f ${TMP}/mds_survey*
21658         echo + $cmd
21659         eval $cmd || error "mds-survey with stripe_count failed"
21660         cat ${TMP}/mds_survey*
21661         rm -f ${TMP}/mds_survey*
21662 }
21663 run_test 225b "Metadata survey sanity with stripe_count = 1"
21664
21665 mcreate_path2fid () {
21666         local mode=$1
21667         local major=$2
21668         local minor=$3
21669         local name=$4
21670         local desc=$5
21671         local path=$DIR/$tdir/$name
21672         local fid
21673         local rc
21674         local fid_path
21675
21676         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21677                 error "cannot create $desc"
21678
21679         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21680         rc=$?
21681         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21682
21683         fid_path=$($LFS fid2path $MOUNT $fid)
21684         rc=$?
21685         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21686
21687         [ "$path" == "$fid_path" ] ||
21688                 error "fid2path returned $fid_path, expected $path"
21689
21690         echo "pass with $path and $fid"
21691 }
21692
21693 test_226a () {
21694         rm -rf $DIR/$tdir
21695         mkdir -p $DIR/$tdir
21696
21697         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21698         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21699         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21700         mcreate_path2fid 0040666 0 0 dir "directory"
21701         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21702         mcreate_path2fid 0100666 0 0 file "regular file"
21703         mcreate_path2fid 0120666 0 0 link "symbolic link"
21704         mcreate_path2fid 0140666 0 0 sock "socket"
21705 }
21706 run_test 226a "call path2fid and fid2path on files of all type"
21707
21708 test_226b () {
21709         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21710
21711         local MDTIDX=1
21712
21713         rm -rf $DIR/$tdir
21714         mkdir -p $DIR/$tdir
21715         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21716                 error "create remote directory failed"
21717         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21718         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21719                                 "character special file (null)"
21720         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21721                                 "character special file (no device)"
21722         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21723         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21724                                 "block special file (loop)"
21725         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21726         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21727         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21728 }
21729 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21730
21731 test_226c () {
21732         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21733         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21734                 skip "Need MDS version at least 2.13.55"
21735
21736         local submnt=/mnt/submnt
21737         local srcfile=/etc/passwd
21738         local dstfile=$submnt/passwd
21739         local path
21740         local fid
21741
21742         rm -rf $DIR/$tdir
21743         rm -rf $submnt
21744         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21745                 error "create remote directory failed"
21746         mkdir -p $submnt || error "create $submnt failed"
21747         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21748                 error "mount $submnt failed"
21749         stack_trap "umount $submnt" EXIT
21750
21751         cp $srcfile $dstfile
21752         fid=$($LFS path2fid $dstfile)
21753         path=$($LFS fid2path $submnt "$fid")
21754         [ "$path" = "$dstfile" ] ||
21755                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21756 }
21757 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21758
21759 test_226d () {
21760         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21761                 skip "Need client at least version 2.15.57"
21762
21763         # Define First test dataset
21764         local testdirs_01=$DIR/$tdir
21765         local testdata_01=$testdirs_01/${tdir}_01
21766         local testresult_01=${tdir}_01
21767         # Define Second test dataset
21768         local testdirs_02=$DIR/$tdir/$tdir
21769         local testdata_02=$testdirs_02/${tdir}_02
21770         local testresult_02=${tdir}_02
21771         # Define third test dataset (top level)
21772         local testdata_03=$DIR/${tdir}_03
21773         local testresult_03=${tdir}_03
21774
21775         # Create first test dataset
21776         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21777         touch $testdata_01 || error "cannot create file $testdata_01"
21778
21779         # Create second test dataset
21780         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21781         touch $testdata_02 || error "cannot create file $testdata_02"
21782
21783         # Create third test dataset
21784         touch $testdata_03 || error "cannot create file $testdata_03"
21785
21786         local fid01=$($LFS getstripe -F "$testdata_01") ||
21787                 error "getstripe failed on $testdata_01"
21788         local fid02=$($LFS getstripe -F "$testdata_02") ||
21789                 error "getstripe failed on $testdata_01"
21790         local fid03=$($LFS getstripe -F "$testdata_03") ||
21791                 error "getstripe failed on $testdata_03"
21792
21793         # Verify only -n option
21794         local out1=$($LFS fid2path -n $DIR $fid01) ||
21795                 error "fid2path failed on $fid01"
21796         local out2=$($LFS fid2path -n $DIR $fid02) ||
21797                 error "fid2path failed on $fid02"
21798         local out3=$($LFS fid2path -n $DIR $fid03) ||
21799                 error "fid2path failed on $fid03"
21800
21801         [[ "$out1" == "$testresult_01" ]] ||
21802                 error "fid2path failed: Expected $testresult_01 got $out1"
21803         [[ "$out2" == "$testresult_02" ]] ||
21804                 error "fid2path failed: Expected $testresult_02 got $out2"
21805         [[ "$out3" == "$testresult_03" ]] ||
21806                 error "fid2path failed: Expected $testresult_03 got $out3"
21807
21808         # Verify with option -fn together
21809         out1=$($LFS fid2path -fn $DIR $fid01) ||
21810                 error "fid2path -fn failed on $fid01"
21811         out2=$($LFS fid2path -fn $DIR $fid02) ||
21812                 error "fid2path -fn failed on $fid02"
21813         out3=$($LFS fid2path -fn $DIR $fid03) ||
21814                 error "fid2path -fn failed on $fid03"
21815
21816         local tmpout=$(echo $out1 | cut -d" " -f2)
21817         [[ "$tmpout" == "$testresult_01" ]] ||
21818                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21819
21820         tmpout=$(echo $out2 | cut -d" " -f2)
21821         [[ "$tmpout" == "$testresult_02" ]] ||
21822                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21823
21824         tmpout=$(echo $out3 | cut -d" " -f2)
21825         [[ "$tmpout" == "$testresult_03" ]] ||
21826                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21827 }
21828 run_test 226d "verify fid2path with -n and -fn option"
21829
21830 test_226e () {
21831         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21832                 skip "Need client at least version 2.15.56"
21833
21834         # Define filename with 'newline' and a space
21835         local testfile="Test"$'\n'"file 01"
21836         # Define link name with multiple 'newline' and a space
21837         local linkfile="Link"$'\n'"file "$'\n'"01"
21838         # Remove prior hard link
21839         rm -f $DIR/"$linkfile"
21840
21841         # Create file
21842         touch $DIR/"$testfile"
21843         # Create link
21844         ln $DIR/"$testfile" $DIR/"$linkfile"
21845
21846         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21847                 error "getstripe failed on $DIR/$testfile"
21848
21849         # Call with -0 option
21850         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21851                 echo "FILE:" | grep -c "FILE:")
21852
21853         # With -0 option the output should be exactly 2 lines.
21854         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21855 }
21856 run_test 226e "Verify path2fid -0 option with newline and space"
21857
21858 # LU-1299 Executing or running ldd on a truncated executable does not
21859 # cause an out-of-memory condition.
21860 test_227() {
21861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21862         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21863
21864         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21865         chmod +x $MOUNT/date
21866
21867         $MOUNT/date > /dev/null
21868         ldd $MOUNT/date > /dev/null
21869         rm -f $MOUNT/date
21870 }
21871 run_test 227 "running truncated executable does not cause OOM"
21872
21873 # LU-1512 try to reuse idle OI blocks
21874 test_228a() {
21875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21876         remote_mds_nodsh && skip "remote MDS with nodsh"
21877         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21878
21879         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21880         local myDIR=$DIR/$tdir
21881
21882         mkdir -p $myDIR
21883         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21884         $LCTL set_param fail_loc=0x80001002
21885         createmany -o $myDIR/t- 10000
21886         $LCTL set_param fail_loc=0
21887         # The guard is current the largest FID holder
21888         touch $myDIR/guard
21889         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21890                     tr -d '[')
21891         local IDX=$(($SEQ % 64))
21892
21893         do_facet $SINGLEMDS sync
21894         # Make sure journal flushed.
21895         sleep 6
21896         local blk1=$(do_facet $SINGLEMDS \
21897                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21898                      grep Blockcount | awk '{print $4}')
21899
21900         # Remove old files, some OI blocks will become idle.
21901         unlinkmany $myDIR/t- 10000
21902         # Create new files, idle OI blocks should be reused.
21903         createmany -o $myDIR/t- 2000
21904         do_facet $SINGLEMDS sync
21905         # Make sure journal flushed.
21906         sleep 6
21907         local blk2=$(do_facet $SINGLEMDS \
21908                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21909                      grep Blockcount | awk '{print $4}')
21910
21911         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21912 }
21913 run_test 228a "try to reuse idle OI blocks"
21914
21915 test_228b() {
21916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21917         remote_mds_nodsh && skip "remote MDS with nodsh"
21918         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21919
21920         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21921         local myDIR=$DIR/$tdir
21922
21923         mkdir -p $myDIR
21924         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21925         $LCTL set_param fail_loc=0x80001002
21926         createmany -o $myDIR/t- 10000
21927         $LCTL set_param fail_loc=0
21928         # The guard is current the largest FID holder
21929         touch $myDIR/guard
21930         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21931                     tr -d '[')
21932         local IDX=$(($SEQ % 64))
21933
21934         do_facet $SINGLEMDS sync
21935         # Make sure journal flushed.
21936         sleep 6
21937         local blk1=$(do_facet $SINGLEMDS \
21938                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21939                      grep Blockcount | awk '{print $4}')
21940
21941         # Remove old files, some OI blocks will become idle.
21942         unlinkmany $myDIR/t- 10000
21943
21944         # stop the MDT
21945         stop $SINGLEMDS || error "Fail to stop MDT."
21946         # remount the MDT
21947         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21948                 error "Fail to start MDT."
21949
21950         client_up || error "Fail to df."
21951         # Create new files, idle OI blocks should be reused.
21952         createmany -o $myDIR/t- 2000
21953         do_facet $SINGLEMDS sync
21954         # Make sure journal flushed.
21955         sleep 6
21956         local blk2=$(do_facet $SINGLEMDS \
21957                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21958                      grep Blockcount | awk '{print $4}')
21959
21960         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21961 }
21962 run_test 228b "idle OI blocks can be reused after MDT restart"
21963
21964 #LU-1881
21965 test_228c() {
21966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21967         remote_mds_nodsh && skip "remote MDS with nodsh"
21968         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21969
21970         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21971         local myDIR=$DIR/$tdir
21972
21973         mkdir -p $myDIR
21974         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21975         $LCTL set_param fail_loc=0x80001002
21976         # 20000 files can guarantee there are index nodes in the OI file
21977         createmany -o $myDIR/t- 20000
21978         $LCTL set_param fail_loc=0
21979         # The guard is current the largest FID holder
21980         touch $myDIR/guard
21981         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21982                     tr -d '[')
21983         local IDX=$(($SEQ % 64))
21984
21985         do_facet $SINGLEMDS sync
21986         # Make sure journal flushed.
21987         sleep 6
21988         local blk1=$(do_facet $SINGLEMDS \
21989                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21990                      grep Blockcount | awk '{print $4}')
21991
21992         # Remove old files, some OI blocks will become idle.
21993         unlinkmany $myDIR/t- 20000
21994         rm -f $myDIR/guard
21995         # The OI file should become empty now
21996
21997         # Create new files, idle OI blocks should be reused.
21998         createmany -o $myDIR/t- 2000
21999         do_facet $SINGLEMDS sync
22000         # Make sure journal flushed.
22001         sleep 6
22002         local blk2=$(do_facet $SINGLEMDS \
22003                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22004                      grep Blockcount | awk '{print $4}')
22005
22006         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22007 }
22008 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22009
22010 test_229() { # LU-2482, LU-3448
22011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22012         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22013         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22014                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22015
22016         rm -f $DIR/$tfile
22017
22018         # Create a file with a released layout and stripe count 2.
22019         $MULTIOP $DIR/$tfile H2c ||
22020                 error "failed to create file with released layout"
22021
22022         $LFS getstripe -v $DIR/$tfile
22023
22024         local pattern=$($LFS getstripe -L $DIR/$tfile)
22025         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22026
22027         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22028                 error "getstripe"
22029         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22030         stat $DIR/$tfile || error "failed to stat released file"
22031
22032         chown $RUNAS_ID $DIR/$tfile ||
22033                 error "chown $RUNAS_ID $DIR/$tfile failed"
22034
22035         chgrp $RUNAS_ID $DIR/$tfile ||
22036                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22037
22038         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22039         rm $DIR/$tfile || error "failed to remove released file"
22040 }
22041 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22042
22043 test_230a() {
22044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22045         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22046         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22047                 skip "Need MDS version at least 2.11.52"
22048
22049         local MDTIDX=1
22050
22051         test_mkdir $DIR/$tdir
22052         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22053         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22054         [ $mdt_idx -ne 0 ] &&
22055                 error "create local directory on wrong MDT $mdt_idx"
22056
22057         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22058                         error "create remote directory failed"
22059         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22060         [ $mdt_idx -ne $MDTIDX ] &&
22061                 error "create remote directory on wrong MDT $mdt_idx"
22062
22063         createmany -o $DIR/$tdir/test_230/t- 10 ||
22064                 error "create files on remote directory failed"
22065         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22066         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22067         rm -r $DIR/$tdir || error "unlink remote directory failed"
22068 }
22069 run_test 230a "Create remote directory and files under the remote directory"
22070
22071 test_230b() {
22072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22073         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22074         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22075                 skip "Need MDS version at least 2.11.52"
22076
22077         local MDTIDX=1
22078         local mdt_index
22079         local i
22080         local file
22081         local pid
22082         local stripe_count
22083         local migrate_dir=$DIR/$tdir/migrate_dir
22084         local other_dir=$DIR/$tdir/other_dir
22085
22086         test_mkdir $DIR/$tdir
22087         test_mkdir -i0 -c1 $migrate_dir
22088         test_mkdir -i0 -c1 $other_dir
22089         for ((i=0; i<10; i++)); do
22090                 mkdir -p $migrate_dir/dir_${i}
22091                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22092                         error "create files under remote dir failed $i"
22093         done
22094
22095         cp /etc/passwd $migrate_dir/$tfile
22096         cp /etc/passwd $other_dir/$tfile
22097         chattr +SAD $migrate_dir
22098         chattr +SAD $migrate_dir/$tfile
22099
22100         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22101         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22102         local old_dir_mode=$(stat -c%f $migrate_dir)
22103         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22104
22105         mkdir -p $migrate_dir/dir_default_stripe2
22106         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22107         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22108
22109         mkdir -p $other_dir
22110         ln $migrate_dir/$tfile $other_dir/luna
22111         ln $migrate_dir/$tfile $migrate_dir/sofia
22112         ln $other_dir/$tfile $migrate_dir/david
22113         ln -s $migrate_dir/$tfile $other_dir/zachary
22114         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22115         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22116
22117         local len
22118         local lnktgt
22119
22120         # inline symlink
22121         for len in 58 59 60; do
22122                 lnktgt=$(str_repeat 'l' $len)
22123                 touch $migrate_dir/$lnktgt
22124                 ln -s $lnktgt $migrate_dir/${len}char_ln
22125         done
22126
22127         # PATH_MAX
22128         for len in 4094 4095; do
22129                 lnktgt=$(str_repeat 'l' $len)
22130                 ln -s $lnktgt $migrate_dir/${len}char_ln
22131         done
22132
22133         # NAME_MAX
22134         for len in 254 255; do
22135                 touch $migrate_dir/$(str_repeat 'l' $len)
22136         done
22137
22138         $LFS migrate -m $MDTIDX $migrate_dir ||
22139                 error "fails on migrating remote dir to MDT1"
22140
22141         echo "migratate to MDT1, then checking.."
22142         for ((i = 0; i < 10; i++)); do
22143                 for file in $(find $migrate_dir/dir_${i}); do
22144                         mdt_index=$($LFS getstripe -m $file)
22145                         # broken symlink getstripe will fail
22146                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22147                                 error "$file is not on MDT${MDTIDX}"
22148                 done
22149         done
22150
22151         # the multiple link file should still in MDT0
22152         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22153         [ $mdt_index == 0 ] ||
22154                 error "$file is not on MDT${MDTIDX}"
22155
22156         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22157         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22158                 error " expect $old_dir_flag get $new_dir_flag"
22159
22160         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22161         [ "$old_file_flag" = "$new_file_flag" ] ||
22162                 error " expect $old_file_flag get $new_file_flag"
22163
22164         local new_dir_mode=$(stat -c%f $migrate_dir)
22165         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22166                 error "expect mode $old_dir_mode get $new_dir_mode"
22167
22168         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22169         [ "$old_file_mode" = "$new_file_mode" ] ||
22170                 error "expect mode $old_file_mode get $new_file_mode"
22171
22172         diff /etc/passwd $migrate_dir/$tfile ||
22173                 error "$tfile different after migration"
22174
22175         diff /etc/passwd $other_dir/luna ||
22176                 error "luna different after migration"
22177
22178         diff /etc/passwd $migrate_dir/sofia ||
22179                 error "sofia different after migration"
22180
22181         diff /etc/passwd $migrate_dir/david ||
22182                 error "david different after migration"
22183
22184         diff /etc/passwd $other_dir/zachary ||
22185                 error "zachary different after migration"
22186
22187         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22188                 error "${tfile}_ln different after migration"
22189
22190         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22191                 error "${tfile}_ln_other different after migration"
22192
22193         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22194         [ $stripe_count = 2 ] ||
22195                 error "dir strpe_count $d != 2 after migration."
22196
22197         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22198         [ $stripe_count = 2 ] ||
22199                 error "file strpe_count $d != 2 after migration."
22200
22201         #migrate back to MDT0
22202         MDTIDX=0
22203
22204         $LFS migrate -m $MDTIDX $migrate_dir ||
22205                 error "fails on migrating remote dir to MDT0"
22206
22207         echo "migrate back to MDT0, checking.."
22208         for file in $(find $migrate_dir); do
22209                 mdt_index=$($LFS getstripe -m $file)
22210                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22211                         error "$file is not on MDT${MDTIDX}"
22212         done
22213
22214         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22215         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22216                 error " expect $old_dir_flag get $new_dir_flag"
22217
22218         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22219         [ "$old_file_flag" = "$new_file_flag" ] ||
22220                 error " expect $old_file_flag get $new_file_flag"
22221
22222         local new_dir_mode=$(stat -c%f $migrate_dir)
22223         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22224                 error "expect mode $old_dir_mode get $new_dir_mode"
22225
22226         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22227         [ "$old_file_mode" = "$new_file_mode" ] ||
22228                 error "expect mode $old_file_mode get $new_file_mode"
22229
22230         diff /etc/passwd ${migrate_dir}/$tfile ||
22231                 error "$tfile different after migration"
22232
22233         diff /etc/passwd ${other_dir}/luna ||
22234                 error "luna different after migration"
22235
22236         diff /etc/passwd ${migrate_dir}/sofia ||
22237                 error "sofia different after migration"
22238
22239         diff /etc/passwd ${other_dir}/zachary ||
22240                 error "zachary different after migration"
22241
22242         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22243                 error "${tfile}_ln different after migration"
22244
22245         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22246                 error "${tfile}_ln_other different after migration"
22247
22248         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22249         [ $stripe_count = 2 ] ||
22250                 error "dir strpe_count $d != 2 after migration."
22251
22252         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22253         [ $stripe_count = 2 ] ||
22254                 error "file strpe_count $d != 2 after migration."
22255
22256         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22257 }
22258 run_test 230b "migrate directory"
22259
22260 test_230c() {
22261         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22262         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22263         remote_mds_nodsh && skip "remote MDS with nodsh"
22264         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22265                 skip "Need MDS version at least 2.11.52"
22266
22267         local MDTIDX=1
22268         local total=3
22269         local mdt_index
22270         local file
22271         local migrate_dir=$DIR/$tdir/migrate_dir
22272
22273         #If migrating directory fails in the middle, all entries of
22274         #the directory is still accessiable.
22275         test_mkdir $DIR/$tdir
22276         test_mkdir -i0 -c1 $migrate_dir
22277         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22278         stat $migrate_dir
22279         createmany -o $migrate_dir/f $total ||
22280                 error "create files under ${migrate_dir} failed"
22281
22282         # fail after migrating top dir, and this will fail only once, so the
22283         # first sub file migration will fail (currently f3), others succeed.
22284         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22285         do_facet mds1 lctl set_param fail_loc=0x1801
22286         local t=$(ls $migrate_dir | wc -l)
22287         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22288                 error "migrate should fail"
22289         local u=$(ls $migrate_dir | wc -l)
22290         [ "$u" == "$t" ] || error "$u != $t during migration"
22291
22292         # add new dir/file should succeed
22293         mkdir $migrate_dir/dir ||
22294                 error "mkdir failed under migrating directory"
22295         touch $migrate_dir/file ||
22296                 error "create file failed under migrating directory"
22297
22298         # add file with existing name should fail
22299         for file in $migrate_dir/f*; do
22300                 stat $file > /dev/null || error "stat $file failed"
22301                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22302                         error "open(O_CREAT|O_EXCL) $file should fail"
22303                 $MULTIOP $file m && error "create $file should fail"
22304                 touch $DIR/$tdir/remote_dir/$tfile ||
22305                         error "touch $tfile failed"
22306                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22307                         error "link $file should fail"
22308                 mdt_index=$($LFS getstripe -m $file)
22309                 if [ $mdt_index == 0 ]; then
22310                         # file failed to migrate is not allowed to rename to
22311                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22312                                 error "rename to $file should fail"
22313                 else
22314                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22315                                 error "rename to $file failed"
22316                 fi
22317                 echo hello >> $file || error "write $file failed"
22318         done
22319
22320         # resume migration with different options should fail
22321         $LFS migrate -m 0 $migrate_dir &&
22322                 error "migrate -m 0 $migrate_dir should fail"
22323
22324         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22325                 error "migrate -c 2 $migrate_dir should fail"
22326
22327         # resume migration should succeed
22328         $LFS migrate -m $MDTIDX $migrate_dir ||
22329                 error "migrate $migrate_dir failed"
22330
22331         echo "Finish migration, then checking.."
22332         for file in $(find $migrate_dir); do
22333                 mdt_index=$($LFS getstripe -m $file)
22334                 [ $mdt_index == $MDTIDX ] ||
22335                         error "$file is not on MDT${MDTIDX}"
22336         done
22337
22338         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22339 }
22340 run_test 230c "check directory accessiblity if migration failed"
22341
22342 test_230d() {
22343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22344         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22345         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22346                 skip "Need MDS version at least 2.11.52"
22347         # LU-11235
22348         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22349
22350         local migrate_dir=$DIR/$tdir/migrate_dir
22351         local old_index
22352         local new_index
22353         local old_count
22354         local new_count
22355         local new_hash
22356         local mdt_index
22357         local i
22358         local j
22359
22360         old_index=$((RANDOM % MDSCOUNT))
22361         old_count=$((MDSCOUNT - old_index))
22362         new_index=$((RANDOM % MDSCOUNT))
22363         new_count=$((MDSCOUNT - new_index))
22364         new_hash=1 # for all_char
22365
22366         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22367         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22368
22369         test_mkdir $DIR/$tdir
22370         test_mkdir -i $old_index -c $old_count $migrate_dir
22371
22372         for ((i=0; i<100; i++)); do
22373                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22374                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22375                         error "create files under remote dir failed $i"
22376         done
22377
22378         echo -n "Migrate from MDT$old_index "
22379         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22380         echo -n "to MDT$new_index"
22381         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22382         echo
22383
22384         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22385         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22386                 error "migrate remote dir error"
22387
22388         echo "Finish migration, then checking.."
22389         for file in $(find $migrate_dir -maxdepth 1); do
22390                 mdt_index=$($LFS getstripe -m $file)
22391                 if [ $mdt_index -lt $new_index ] ||
22392                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22393                         error "$file is on MDT$mdt_index"
22394                 fi
22395         done
22396
22397         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22398 }
22399 run_test 230d "check migrate big directory"
22400
22401 test_230e() {
22402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22404         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22405                 skip "Need MDS version at least 2.11.52"
22406
22407         local i
22408         local j
22409         local a_fid
22410         local b_fid
22411
22412         mkdir_on_mdt0 $DIR/$tdir
22413         mkdir $DIR/$tdir/migrate_dir
22414         mkdir $DIR/$tdir/other_dir
22415         touch $DIR/$tdir/migrate_dir/a
22416         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22417         ls $DIR/$tdir/other_dir
22418
22419         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22420                 error "migrate dir fails"
22421
22422         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22423         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22424
22425         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22426         [ $mdt_index == 0 ] || error "a is not on MDT0"
22427
22428         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22429                 error "migrate dir fails"
22430
22431         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22432         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22433
22434         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22435         [ $mdt_index == 1 ] || error "a is not on MDT1"
22436
22437         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22438         [ $mdt_index == 1 ] || error "b is not on MDT1"
22439
22440         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22441         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22442
22443         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22444
22445         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22446 }
22447 run_test 230e "migrate mulitple local link files"
22448
22449 test_230f() {
22450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22451         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22452         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22453                 skip "Need MDS version at least 2.11.52"
22454
22455         local a_fid
22456         local ln_fid
22457
22458         mkdir -p $DIR/$tdir
22459         mkdir $DIR/$tdir/migrate_dir
22460         $LFS mkdir -i1 $DIR/$tdir/other_dir
22461         touch $DIR/$tdir/migrate_dir/a
22462         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22463         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22464         ls $DIR/$tdir/other_dir
22465
22466         # a should be migrated to MDT1, since no other links on MDT0
22467         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22468                 error "#1 migrate dir fails"
22469         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22470         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22471         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22472         [ $mdt_index == 1 ] || error "a is not on MDT1"
22473
22474         # a should stay on MDT1, because it is a mulitple link file
22475         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22476                 error "#2 migrate dir fails"
22477         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22478         [ $mdt_index == 1 ] || error "a is not on MDT1"
22479
22480         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22481                 error "#3 migrate dir fails"
22482
22483         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22484         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22485         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22486
22487         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22488         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22489
22490         # a should be migrated to MDT0, since no other links on MDT1
22491         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22492                 error "#4 migrate dir fails"
22493         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22494         [ $mdt_index == 0 ] || error "a is not on MDT0"
22495
22496         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22497 }
22498 run_test 230f "migrate mulitple remote link files"
22499
22500 test_230g() {
22501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22502         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22503         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22504                 skip "Need MDS version at least 2.11.52"
22505
22506         mkdir -p $DIR/$tdir/migrate_dir
22507
22508         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22509                 error "migrating dir to non-exist MDT succeeds"
22510         true
22511 }
22512 run_test 230g "migrate dir to non-exist MDT"
22513
22514 test_230h() {
22515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22516         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22517         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22518                 skip "Need MDS version at least 2.11.52"
22519
22520         local mdt_index
22521
22522         mkdir -p $DIR/$tdir/migrate_dir
22523
22524         $LFS migrate -m1 $DIR &&
22525                 error "migrating mountpoint1 should fail"
22526
22527         $LFS migrate -m1 $DIR/$tdir/.. &&
22528                 error "migrating mountpoint2 should fail"
22529
22530         # same as mv
22531         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22532                 error "migrating $tdir/migrate_dir/.. should fail"
22533
22534         true
22535 }
22536 run_test 230h "migrate .. and root"
22537
22538 test_230i() {
22539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22540         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22541         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22542                 skip "Need MDS version at least 2.11.52"
22543
22544         mkdir -p $DIR/$tdir/migrate_dir
22545
22546         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22547                 error "migration fails with a tailing slash"
22548
22549         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22550                 error "migration fails with two tailing slashes"
22551 }
22552 run_test 230i "lfs migrate -m tolerates trailing slashes"
22553
22554 test_230j() {
22555         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22556         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22557                 skip "Need MDS version at least 2.11.52"
22558
22559         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22560         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22561                 error "create $tfile failed"
22562         cat /etc/passwd > $DIR/$tdir/$tfile
22563
22564         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22565
22566         cmp /etc/passwd $DIR/$tdir/$tfile ||
22567                 error "DoM file mismatch after migration"
22568 }
22569 run_test 230j "DoM file data not changed after dir migration"
22570
22571 test_230k() {
22572         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22573         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22574                 skip "Need MDS version at least 2.11.56"
22575
22576         local total=20
22577         local files_on_starting_mdt=0
22578
22579         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22580         $LFS getdirstripe $DIR/$tdir
22581         for i in $(seq $total); do
22582                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22583                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22584                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22585         done
22586
22587         echo "$files_on_starting_mdt files on MDT0"
22588
22589         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22590         $LFS getdirstripe $DIR/$tdir
22591
22592         files_on_starting_mdt=0
22593         for i in $(seq $total); do
22594                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22595                         error "file $tfile.$i mismatch after migration"
22596                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22597                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22598         done
22599
22600         echo "$files_on_starting_mdt files on MDT1 after migration"
22601         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22602
22603         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22604         $LFS getdirstripe $DIR/$tdir
22605
22606         files_on_starting_mdt=0
22607         for i in $(seq $total); do
22608                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22609                         error "file $tfile.$i mismatch after 2nd migration"
22610                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22611                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22612         done
22613
22614         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22615         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22616
22617         true
22618 }
22619 run_test 230k "file data not changed after dir migration"
22620
22621 test_230l() {
22622         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22623         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22624                 skip "Need MDS version at least 2.11.56"
22625
22626         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22627         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22628                 error "create files under remote dir failed $i"
22629         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22630 }
22631 run_test 230l "readdir between MDTs won't crash"
22632
22633 test_230m() {
22634         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22635         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22636                 skip "Need MDS version at least 2.11.56"
22637
22638         local MDTIDX=1
22639         local mig_dir=$DIR/$tdir/migrate_dir
22640         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22641         local shortstr="b"
22642         local val
22643
22644         echo "Creating files and dirs with xattrs"
22645         test_mkdir $DIR/$tdir
22646         test_mkdir -i0 -c1 $mig_dir
22647         mkdir $mig_dir/dir
22648         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22649                 error "cannot set xattr attr1 on dir"
22650         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22651                 error "cannot set xattr attr2 on dir"
22652         touch $mig_dir/dir/f0
22653         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22654                 error "cannot set xattr attr1 on file"
22655         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22656                 error "cannot set xattr attr2 on file"
22657         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22658         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22659         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22660         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22661         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22662         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22663         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22664         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22665         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22666
22667         echo "Migrating to MDT1"
22668         $LFS migrate -m $MDTIDX $mig_dir ||
22669                 error "fails on migrating dir to MDT1"
22670
22671         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22672         echo "Checking xattrs"
22673         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22674         [ "$val" = $longstr ] ||
22675                 error "expecting xattr1 $longstr on dir, found $val"
22676         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22677         [ "$val" = $shortstr ] ||
22678                 error "expecting xattr2 $shortstr on dir, found $val"
22679         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22680         [ "$val" = $longstr ] ||
22681                 error "expecting xattr1 $longstr on file, found $val"
22682         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22683         [ "$val" = $shortstr ] ||
22684                 error "expecting xattr2 $shortstr on file, found $val"
22685 }
22686 run_test 230m "xattrs not changed after dir migration"
22687
22688 test_230n() {
22689         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22690         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22691                 skip "Need MDS version at least 2.13.53"
22692
22693         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22694         cat /etc/hosts > $DIR/$tdir/$tfile
22695         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22696         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22697
22698         cmp /etc/hosts $DIR/$tdir/$tfile ||
22699                 error "File data mismatch after migration"
22700 }
22701 run_test 230n "Dir migration with mirrored file"
22702
22703 test_230o() {
22704         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22705         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22706                 skip "Need MDS version at least 2.13.52"
22707
22708         local mdts=$(comma_list $(mdts_nodes))
22709         local timeout=100
22710         local restripe_status
22711         local delta
22712         local i
22713
22714         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22715
22716         # in case "crush" hash type is not set
22717         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22718
22719         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22720                            mdt.*MDT0000.enable_dir_restripe)
22721         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22722         stack_trap "do_nodes $mdts $LCTL set_param \
22723                     mdt.*.enable_dir_restripe=$restripe_status"
22724
22725         mkdir $DIR/$tdir
22726         createmany -m $DIR/$tdir/f 100 ||
22727                 error "create files under remote dir failed $i"
22728         createmany -d $DIR/$tdir/d 100 ||
22729                 error "create dirs under remote dir failed $i"
22730
22731         for i in $(seq 2 $MDSCOUNT); do
22732                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22733                 $LFS setdirstripe -c $i $DIR/$tdir ||
22734                         error "split -c $i $tdir failed"
22735                 wait_update $HOSTNAME \
22736                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22737                         error "dir split not finished"
22738                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22739                         awk '/migrate/ {sum += $2} END { print sum }')
22740                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22741                 # delta is around total_files/stripe_count
22742                 (( $delta < 200 / (i - 1) + 4 )) ||
22743                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22744         done
22745 }
22746 run_test 230o "dir split"
22747
22748 test_230p() {
22749         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22750         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22751                 skip "Need MDS version at least 2.13.52"
22752
22753         local mdts=$(comma_list $(mdts_nodes))
22754         local timeout=100
22755         local restripe_status
22756         local delta
22757         local c
22758
22759         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22760
22761         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22762
22763         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22764                            mdt.*MDT0000.enable_dir_restripe)
22765         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22766         stack_trap "do_nodes $mdts $LCTL set_param \
22767                     mdt.*.enable_dir_restripe=$restripe_status"
22768
22769         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22770         createmany -m $DIR/$tdir/f 100 ||
22771                 error "create files under remote dir failed"
22772         createmany -d $DIR/$tdir/d 100 ||
22773                 error "create dirs under remote dir failed"
22774
22775         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22776                 local mdt_hash="crush"
22777
22778                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22779                 $LFS setdirstripe -c $c $DIR/$tdir ||
22780                         error "split -c $c $tdir failed"
22781                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22782                         mdt_hash="$mdt_hash,fixed"
22783                 elif [ $c -eq 1 ]; then
22784                         mdt_hash="none"
22785                 fi
22786                 wait_update $HOSTNAME \
22787                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22788                         error "dir merge not finished"
22789                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22790                         awk '/migrate/ {sum += $2} END { print sum }')
22791                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22792                 # delta is around total_files/stripe_count
22793                 (( delta < 200 / c + 4 )) ||
22794                         error "$delta files migrated >= $((200 / c + 4))"
22795         done
22796 }
22797 run_test 230p "dir merge"
22798
22799 test_230q() {
22800         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22801         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22802                 skip "Need MDS version at least 2.13.52"
22803
22804         local mdts=$(comma_list $(mdts_nodes))
22805         local saved_threshold=$(do_facet mds1 \
22806                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22807         local saved_delta=$(do_facet mds1 \
22808                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22809         local threshold=100
22810         local delta=2
22811         local total=0
22812         local stripe_count=0
22813         local stripe_index
22814         local nr_files
22815         local create
22816
22817         # test with fewer files on ZFS
22818         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22819
22820         stack_trap "do_nodes $mdts $LCTL set_param \
22821                     mdt.*.dir_split_count=$saved_threshold"
22822         stack_trap "do_nodes $mdts $LCTL set_param \
22823                     mdt.*.dir_split_delta=$saved_delta"
22824         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22825         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22826         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22827         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22828         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22829         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22830
22831         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22832         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22833
22834         create=$((threshold * 3 / 2))
22835         while [ $stripe_count -lt $MDSCOUNT ]; do
22836                 createmany -m $DIR/$tdir/f $total $create ||
22837                         error "create sub files failed"
22838                 stat $DIR/$tdir > /dev/null
22839                 total=$((total + create))
22840                 stripe_count=$((stripe_count + delta))
22841                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22842
22843                 wait_update $HOSTNAME \
22844                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22845                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22846
22847                 wait_update $HOSTNAME \
22848                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22849                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22850
22851                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22852                 echo "$nr_files/$total files on MDT$stripe_index after split"
22853                 # allow 10% margin of imbalance with crush hash
22854                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22855                         error "$nr_files files on MDT$stripe_index after split"
22856
22857                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22858                 [ $nr_files -eq $total ] ||
22859                         error "total sub files $nr_files != $total"
22860         done
22861
22862         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22863
22864         echo "fixed layout directory won't auto split"
22865         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22866         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22867                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22868         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22869                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22870 }
22871 run_test 230q "dir auto split"
22872
22873 test_230r() {
22874         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22875         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22876         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22877                 skip "Need MDS version at least 2.13.54"
22878
22879         # maximum amount of local locks:
22880         # parent striped dir - 2 locks
22881         # new stripe in parent to migrate to - 1 lock
22882         # source and target - 2 locks
22883         # Total 5 locks for regular file
22884         mkdir -p $DIR/$tdir
22885         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22886         touch $DIR/$tdir/dir1/eee
22887
22888         # create 4 hardlink for 4 more locks
22889         # Total: 9 locks > RS_MAX_LOCKS (8)
22890         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22891         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22892         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22893         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22894         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22895         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22896         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22897         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22898
22899         cancel_lru_locks mdc
22900
22901         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22902                 error "migrate dir fails"
22903
22904         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22905 }
22906 run_test 230r "migrate with too many local locks"
22907
22908 test_230s() {
22909         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22910                 skip "Need MDS version at least 2.14.52"
22911
22912         local mdts=$(comma_list $(mdts_nodes))
22913         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22914                                 mdt.*MDT0000.enable_dir_restripe)
22915
22916         stack_trap "do_nodes $mdts $LCTL set_param \
22917                     mdt.*.enable_dir_restripe=$restripe_status"
22918
22919         local st
22920         for st in 0 1; do
22921                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22922                 test_mkdir $DIR/$tdir
22923                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22924                         error "$LFS mkdir should return EEXIST if target exists"
22925                 rmdir $DIR/$tdir
22926         done
22927 }
22928 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22929
22930 test_230t()
22931 {
22932         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22933         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22934                 skip "Need MDS version at least 2.14.50"
22935
22936         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22937         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22938         $LFS project -p 1 -s $DIR/$tdir ||
22939                 error "set $tdir project id failed"
22940         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22941                 error "set subdir project id failed"
22942         local pbefore="$($LFS project -d $DIR/$tdir)"
22943         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22944         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22945
22946         local pafter="$($LFS project -d $DIR/$tdir)"
22947         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22948         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22949         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22950
22951         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22952                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22953
22954         # check rename works, even if source parent projid differs (LU-17016)
22955         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22956         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22957
22958         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22959         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22960                 error "subdir failed rename for different source parent projid"
22961         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22962
22963         [[ "$fid_before" == "$fid_after" ]] ||
22964                 error "fid before '$fid_before' != after '$fid_after'"
22965 }
22966 run_test 230t "migrate directory with project ID set"
22967
22968 test_230u()
22969 {
22970         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22971         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22972                 skip "Need MDS version at least 2.14.53"
22973
22974         local count
22975
22976         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22977         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22978         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22979         for i in $(seq 0 $((MDSCOUNT - 1))); do
22980                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22981                 echo "$count dirs migrated to MDT$i"
22982         done
22983         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22984         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22985 }
22986 run_test 230u "migrate directory by QOS"
22987
22988 test_230v()
22989 {
22990         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22991         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22992                 skip "Need MDS version at least 2.14.53"
22993
22994         local count
22995
22996         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22997         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22998         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22999         for i in $(seq 0 $((MDSCOUNT - 1))); do
23000                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23001                 echo "$count subdirs migrated to MDT$i"
23002                 (( i == 3 )) && (( count > 0 )) &&
23003                         error "subdir shouldn't be migrated to MDT3"
23004         done
23005         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23006         (( count == 3 )) || error "dirs migrated to $count MDTs"
23007 }
23008 run_test 230v "subdir migrated to the MDT where its parent is located"
23009
23010 test_230w() {
23011         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23012         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23013                 skip "Need MDS version at least 2.15.0"
23014
23015         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23016         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23017         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23018
23019         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23020                 error "migrate failed"
23021
23022         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23023                 error "$tdir stripe count mismatch"
23024
23025         for i in $(seq 0 9); do
23026                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23027                         error "d$i is striped"
23028         done
23029 }
23030 run_test 230w "non-recursive mode dir migration"
23031
23032 test_230x() {
23033         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23034         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23035                 skip "Need MDS version at least 2.15.0"
23036
23037         mkdir -p $DIR/$tdir || error "mkdir failed"
23038         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23039
23040         local mdt_name=$(mdtname_from_index 0)
23041         local low=$(do_facet mds2 $LCTL get_param -n \
23042                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23043         local high=$(do_facet mds2 $LCTL get_param -n \
23044                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23045         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23046         local maxage=$(do_facet mds2 $LCTL get_param -n \
23047                 osp.*$mdt_name-osp-MDT0001.maxage)
23048
23049         stack_trap "do_facet mds2 $LCTL set_param -n \
23050                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23051                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23052         stack_trap "do_facet mds2 $LCTL set_param -n \
23053                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23054
23055         do_facet mds2 $LCTL set_param -n \
23056                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23057         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23058         sleep 4
23059         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23060                 error "migrate $tdir should fail"
23061
23062         do_facet mds2 $LCTL set_param -n \
23063                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23064         do_facet mds2 $LCTL set_param -n \
23065                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23066         sleep 4
23067         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23068                 error "migrate failed"
23069         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23070                 error "$tdir stripe count mismatch"
23071 }
23072 run_test 230x "dir migration check space"
23073
23074 test_230y() {
23075         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23076         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23077                 skip "Need MDS version at least 2.15.55.45"
23078
23079         local pid
23080
23081         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23082         $LFS getdirstripe $DIR/$tdir
23083         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23084         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23085         pid=$!
23086         sleep 1
23087
23088         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23089         do_facet mds2 lctl set_param fail_loc=0x1802
23090
23091         wait $pid
23092         do_facet mds2 lctl set_param fail_loc=0
23093         $LFS getdirstripe $DIR/$tdir
23094         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23095         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23096 }
23097 run_test 230y "unlink dir with bad hash type"
23098
23099 test_230z() {
23100         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23101         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23102                 skip "Need MDS version at least 2.15.55.45"
23103
23104         local pid
23105
23106         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23107         $LFS getdirstripe $DIR/$tdir
23108         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23109         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23110         pid=$!
23111         sleep 1
23112
23113         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23114         do_facet mds2 lctl set_param fail_loc=0x1802
23115
23116         wait $pid
23117         do_facet mds2 lctl set_param fail_loc=0
23118         $LFS getdirstripe $DIR/$tdir
23119
23120         # resume migration
23121         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23122                 error "resume migration failed"
23123         $LFS getdirstripe $DIR/$tdir
23124         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23125                 error "migration is not finished"
23126 }
23127 run_test 230z "resume dir migration with bad hash type"
23128
23129 test_231a()
23130 {
23131         # For simplicity this test assumes that max_pages_per_rpc
23132         # is the same across all OSCs
23133         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23134         local bulk_size=$((max_pages * PAGE_SIZE))
23135         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23136                                        head -n 1)
23137
23138         mkdir -p $DIR/$tdir
23139         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23140                 error "failed to set stripe with -S ${brw_size}M option"
23141         stack_trap "rm -rf $DIR/$tdir"
23142
23143         # clear the OSC stats
23144         $LCTL set_param osc.*.stats=0 &>/dev/null
23145         stop_writeback
23146
23147         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23148         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23149                 oflag=direct &>/dev/null || error "dd failed"
23150
23151         sync; sleep 1; sync # just to be safe
23152         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23153         if [ x$nrpcs != "x1" ]; then
23154                 $LCTL get_param osc.*.stats
23155                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23156         fi
23157
23158         start_writeback
23159         # Drop the OSC cache, otherwise we will read from it
23160         cancel_lru_locks osc
23161
23162         # clear the OSC stats
23163         $LCTL set_param osc.*.stats=0 &>/dev/null
23164
23165         # Client reads $bulk_size.
23166         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23167                 iflag=direct &>/dev/null || error "dd failed"
23168
23169         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23170         if [ x$nrpcs != "x1" ]; then
23171                 $LCTL get_param osc.*.stats
23172                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23173         fi
23174 }
23175 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23176
23177 test_231b() {
23178         mkdir -p $DIR/$tdir
23179         stack_trap "rm -rf $DIR/$tdir"
23180         local i
23181         for i in {0..1023}; do
23182                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23183                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23184                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23185         done
23186         sync
23187 }
23188 run_test 231b "must not assert on fully utilized OST request buffer"
23189
23190 test_232a() {
23191         mkdir -p $DIR/$tdir
23192         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23193
23194         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23195         do_facet ost1 $LCTL set_param fail_loc=0x31c
23196
23197         # ignore dd failure
23198         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23199         stack_trap "rm -f $DIR/$tdir/$tfile"
23200
23201         do_facet ost1 $LCTL set_param fail_loc=0
23202         umount_client $MOUNT || error "umount failed"
23203         mount_client $MOUNT || error "mount failed"
23204         stop ost1 || error "cannot stop ost1"
23205         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23206 }
23207 run_test 232a "failed lock should not block umount"
23208
23209 test_232b() {
23210         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23211                 skip "Need MDS version at least 2.10.58"
23212
23213         mkdir -p $DIR/$tdir
23214         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23215         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23216         stack_trap "rm -f $DIR/$tdir/$tfile"
23217         sync
23218         cancel_lru_locks osc
23219
23220         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23221         do_facet ost1 $LCTL set_param fail_loc=0x31c
23222
23223         # ignore failure
23224         $LFS data_version $DIR/$tdir/$tfile || true
23225
23226         do_facet ost1 $LCTL set_param fail_loc=0
23227         umount_client $MOUNT || error "umount failed"
23228         mount_client $MOUNT || error "mount failed"
23229         stop ost1 || error "cannot stop ost1"
23230         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23231 }
23232 run_test 232b "failed data version lock should not block umount"
23233
23234 test_233a() {
23235         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23236                 skip "Need MDS version at least 2.3.64"
23237         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23238
23239         local fid=$($LFS path2fid $MOUNT)
23240
23241         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23242                 error "cannot access $MOUNT using its FID '$fid'"
23243 }
23244 run_test 233a "checking that OBF of the FS root succeeds"
23245
23246 test_233b() {
23247         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23248                 skip "Need MDS version at least 2.5.90"
23249         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23250
23251         local fid=$($LFS path2fid $MOUNT/.lustre)
23252
23253         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23254                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23255
23256         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23257         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23258                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23259 }
23260 run_test 233b "checking that OBF of the FS .lustre succeeds"
23261
23262 test_234() {
23263         local p="$TMP/sanityN-$TESTNAME.parameters"
23264         save_lustre_params client "llite.*.xattr_cache" > $p
23265         lctl set_param llite.*.xattr_cache 1 ||
23266                 skip_env "xattr cache is not supported"
23267
23268         mkdir -p $DIR/$tdir || error "mkdir failed"
23269         touch $DIR/$tdir/$tfile || error "touch failed"
23270         # OBD_FAIL_LLITE_XATTR_ENOMEM
23271         $LCTL set_param fail_loc=0x1405
23272         getfattr -n user.attr $DIR/$tdir/$tfile &&
23273                 error "getfattr should have failed with ENOMEM"
23274         $LCTL set_param fail_loc=0x0
23275         rm -rf $DIR/$tdir
23276
23277         restore_lustre_params < $p
23278         rm -f $p
23279 }
23280 run_test 234 "xattr cache should not crash on ENOMEM"
23281
23282 test_235() {
23283         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23284                 skip "Need MDS version at least 2.4.52"
23285
23286         flock_deadlock $DIR/$tfile
23287         local RC=$?
23288         case $RC in
23289                 0)
23290                 ;;
23291                 124) error "process hangs on a deadlock"
23292                 ;;
23293                 *) error "error executing flock_deadlock $DIR/$tfile"
23294                 ;;
23295         esac
23296 }
23297 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23298
23299 #LU-2935
23300 test_236() {
23301         check_swap_layouts_support
23302
23303         local ref1=/etc/passwd
23304         local ref2=/etc/group
23305         local file1=$DIR/$tdir/f1
23306         local file2=$DIR/$tdir/f2
23307
23308         test_mkdir -c1 $DIR/$tdir
23309         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23310         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23311         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23312         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23313         local fd=$(free_fd)
23314         local cmd="exec $fd<>$file2"
23315         eval $cmd
23316         rm $file2
23317         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23318                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23319         cmd="exec $fd>&-"
23320         eval $cmd
23321         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23322
23323         #cleanup
23324         rm -rf $DIR/$tdir
23325 }
23326 run_test 236 "Layout swap on open unlinked file"
23327
23328 # LU-4659 linkea consistency
23329 test_238() {
23330         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23331                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23332                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23333                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23334
23335         touch $DIR/$tfile
23336         ln $DIR/$tfile $DIR/$tfile.lnk
23337         touch $DIR/$tfile.new
23338         mv $DIR/$tfile.new $DIR/$tfile
23339         local fid1=$($LFS path2fid $DIR/$tfile)
23340         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23341         local path1=$($LFS fid2path $FSNAME "$fid1")
23342         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23343         local path2=$($LFS fid2path $FSNAME "$fid2")
23344         [ $tfile.lnk == $path2 ] ||
23345                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23346         rm -f $DIR/$tfile*
23347 }
23348 run_test 238 "Verify linkea consistency"
23349
23350 test_239A() { # was test_239
23351         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23352                 skip "Need MDS version at least 2.5.60"
23353
23354         local list=$(comma_list $(mdts_nodes))
23355
23356         mkdir -p $DIR/$tdir
23357         createmany -o $DIR/$tdir/f- 5000
23358         unlinkmany $DIR/$tdir/f- 5000
23359         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23360                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23361         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23362                         osp.*MDT*.sync_in_flight" | calc_sum)
23363         [ "$changes" -eq 0 ] || error "$changes not synced"
23364 }
23365 run_test 239A "osp_sync test"
23366
23367 test_239a() { #LU-5297
23368         remote_mds_nodsh && skip "remote MDS with nodsh"
23369
23370         touch $DIR/$tfile
23371         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23372         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23373         chgrp $RUNAS_GID $DIR/$tfile
23374         wait_delete_completed
23375 }
23376 run_test 239a "process invalid osp sync record correctly"
23377
23378 test_239b() { #LU-5297
23379         remote_mds_nodsh && skip "remote MDS with nodsh"
23380
23381         touch $DIR/$tfile1
23382         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23383         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23384         chgrp $RUNAS_GID $DIR/$tfile1
23385         wait_delete_completed
23386         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23387         touch $DIR/$tfile2
23388         chgrp $RUNAS_GID $DIR/$tfile2
23389         wait_delete_completed
23390 }
23391 run_test 239b "process osp sync record with ENOMEM error correctly"
23392
23393 test_240() {
23394         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23395         remote_mds_nodsh && skip "remote MDS with nodsh"
23396
23397         mkdir -p $DIR/$tdir
23398
23399         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23400                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23401         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23402                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23403
23404         umount_client $MOUNT || error "umount failed"
23405         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23406         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23407         mount_client $MOUNT || error "failed to mount client"
23408
23409         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23410         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23411 }
23412 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23413
23414 test_241_bio() {
23415         local count=$1
23416         local bsize=$2
23417
23418         for LOOP in $(seq $count); do
23419                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23420                 cancel_lru_locks $OSC || true
23421         done
23422 }
23423
23424 test_241_dio() {
23425         local count=$1
23426         local bsize=$2
23427
23428         for LOOP in $(seq $1); do
23429                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23430                         2>/dev/null
23431         done
23432 }
23433
23434 test_241a() { # was test_241
23435         local bsize=$PAGE_SIZE
23436
23437         (( bsize < 40960 )) && bsize=40960
23438         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23439         ls -la $DIR/$tfile
23440         cancel_lru_locks $OSC
23441         test_241_bio 1000 $bsize &
23442         PID=$!
23443         test_241_dio 1000 $bsize
23444         wait $PID
23445 }
23446 run_test 241a "bio vs dio"
23447
23448 test_241b() {
23449         local bsize=$PAGE_SIZE
23450
23451         (( bsize < 40960 )) && bsize=40960
23452         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23453         ls -la $DIR/$tfile
23454         test_241_dio 1000 $bsize &
23455         PID=$!
23456         test_241_dio 1000 $bsize
23457         wait $PID
23458 }
23459 run_test 241b "dio vs dio"
23460
23461 test_242() {
23462         remote_mds_nodsh && skip "remote MDS with nodsh"
23463
23464         mkdir_on_mdt0 $DIR/$tdir
23465         touch $DIR/$tdir/$tfile
23466
23467         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23468         do_facet mds1 lctl set_param fail_loc=0x105
23469         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23470
23471         do_facet mds1 lctl set_param fail_loc=0
23472         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23473 }
23474 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23475
23476 test_243()
23477 {
23478         test_mkdir $DIR/$tdir
23479         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23480 }
23481 run_test 243 "various group lock tests"
23482
23483 test_244a()
23484 {
23485         test_mkdir $DIR/$tdir
23486         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23487         sendfile_grouplock $DIR/$tdir/$tfile || \
23488                 error "sendfile+grouplock failed"
23489         rm -rf $DIR/$tdir
23490 }
23491 run_test 244a "sendfile with group lock tests"
23492
23493 test_244b()
23494 {
23495         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23496
23497         local threads=50
23498         local size=$((1024*1024))
23499
23500         test_mkdir $DIR/$tdir
23501         for i in $(seq 1 $threads); do
23502                 local file=$DIR/$tdir/file_$((i / 10))
23503                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23504                 local pids[$i]=$!
23505         done
23506         for i in $(seq 1 $threads); do
23507                 wait ${pids[$i]}
23508         done
23509 }
23510 run_test 244b "multi-threaded write with group lock"
23511
23512 test_245a() {
23513         local flagname="multi_mod_rpcs"
23514         local connect_data_name="max_mod_rpcs"
23515         local out
23516
23517         # check if multiple modify RPCs flag is set
23518         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23519                 grep "connect_flags:")
23520         echo "$out"
23521
23522         echo "$out" | grep -qw $flagname
23523         if [ $? -ne 0 ]; then
23524                 echo "connect flag $flagname is not set"
23525                 return
23526         fi
23527
23528         # check if multiple modify RPCs data is set
23529         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23530         echo "$out"
23531
23532         echo "$out" | grep -qw $connect_data_name ||
23533                 error "import should have connect data $connect_data_name"
23534 }
23535 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23536
23537 test_245b() {
23538         local flagname="multi_mod_rpcs"
23539         local connect_data_name="max_mod_rpcs"
23540         local out
23541
23542         remote_mds_nodsh && skip "remote MDS with nodsh"
23543         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23544
23545         # check if multiple modify RPCs flag is set
23546         out=$(do_facet mds1 \
23547               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23548               grep "connect_flags:")
23549         echo "$out"
23550
23551         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23552
23553         # check if multiple modify RPCs data is set
23554         out=$(do_facet mds1 \
23555               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23556
23557         [[ "$out" =~ $connect_data_name ]] ||
23558                 {
23559                         echo "$out"
23560                         error "missing connect data $connect_data_name"
23561                 }
23562 }
23563 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23564
23565 cleanup_247() {
23566         local submount=$1
23567
23568         trap 0
23569         umount_client $submount
23570         rmdir $submount
23571 }
23572
23573 test_247a() {
23574         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23575                 grep -q subtree ||
23576                 skip_env "Fileset feature is not supported"
23577
23578         local submount=${MOUNT}_$tdir
23579
23580         mkdir $MOUNT/$tdir
23581         mkdir -p $submount || error "mkdir $submount failed"
23582         FILESET="$FILESET/$tdir" mount_client $submount ||
23583                 error "mount $submount failed"
23584         trap "cleanup_247 $submount" EXIT
23585         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23586         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23587                 error "read $MOUNT/$tdir/$tfile failed"
23588         cleanup_247 $submount
23589 }
23590 run_test 247a "mount subdir as fileset"
23591
23592 test_247b() {
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         rm -rf $MOUNT/$tdir
23599         mkdir -p $submount || error "mkdir $submount failed"
23600         SKIP_FILESET=1
23601         FILESET="$FILESET/$tdir" mount_client $submount &&
23602                 error "mount $submount should fail"
23603         rmdir $submount
23604 }
23605 run_test 247b "mount subdir that dose not exist"
23606
23607 test_247c() {
23608         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23609                 skip_env "Fileset feature is not supported"
23610
23611         local submount=${MOUNT}_$tdir
23612
23613         mkdir -p $MOUNT/$tdir/dir1
23614         mkdir -p $submount || error "mkdir $submount failed"
23615         trap "cleanup_247 $submount" EXIT
23616         FILESET="$FILESET/$tdir" mount_client $submount ||
23617                 error "mount $submount failed"
23618         local fid=$($LFS path2fid $MOUNT/)
23619         $LFS fid2path $submount $fid && error "fid2path should fail"
23620         cleanup_247 $submount
23621 }
23622 run_test 247c "running fid2path outside subdirectory root"
23623
23624 test_247d() {
23625         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23626                 skip "Fileset feature is not supported"
23627
23628         local submount=${MOUNT}_$tdir
23629
23630         mkdir -p $MOUNT/$tdir/dir1
23631         mkdir -p $submount || error "mkdir $submount failed"
23632         FILESET="$FILESET/$tdir" mount_client $submount ||
23633                 error "mount $submount failed"
23634         trap "cleanup_247 $submount" EXIT
23635
23636         local td=$submount/dir1
23637         local fid=$($LFS path2fid $td)
23638         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23639
23640         # check that we get the same pathname back
23641         local rootpath
23642         local found
23643         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23644                 echo "$rootpath $fid"
23645                 found=$($LFS fid2path $rootpath "$fid")
23646                 [ -n "$found" ] || error "fid2path should succeed"
23647                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23648         done
23649         # check wrong root path format
23650         rootpath=$submount"_wrong"
23651         found=$($LFS fid2path $rootpath "$fid")
23652         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23653
23654         cleanup_247 $submount
23655 }
23656 run_test 247d "running fid2path inside subdirectory root"
23657
23658 # LU-8037
23659 test_247e() {
23660         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23661                 grep -q subtree ||
23662                 skip "Fileset feature is not supported"
23663
23664         local submount=${MOUNT}_$tdir
23665
23666         mkdir $MOUNT/$tdir
23667         mkdir -p $submount || error "mkdir $submount failed"
23668         FILESET="$FILESET/.." mount_client $submount &&
23669                 error "mount $submount should fail"
23670         rmdir $submount
23671 }
23672 run_test 247e "mount .. as fileset"
23673
23674 test_247f() {
23675         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23676         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23677                 skip "Need at least version 2.14.50.162"
23678         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23679                 skip "Fileset feature is not supported"
23680
23681         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23682         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23683                 error "mkdir remote failed"
23684         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23685                 error "mkdir remote/subdir failed"
23686         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23687                 error "mkdir striped failed"
23688         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23689
23690         local submount=${MOUNT}_$tdir
23691
23692         mkdir -p $submount || error "mkdir $submount failed"
23693         stack_trap "rmdir $submount"
23694
23695         local dir
23696         local fileset=$FILESET
23697         local mdts=$(comma_list $(mdts_nodes))
23698
23699         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23700         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23701                 $tdir/striped/subdir $tdir/striped/.; do
23702                 FILESET="$fileset/$dir" mount_client $submount ||
23703                         error "mount $dir failed"
23704                 umount_client $submount
23705         done
23706 }
23707 run_test 247f "mount striped or remote directory as fileset"
23708
23709 test_subdir_mount_lock()
23710 {
23711         local testdir=$1
23712         local submount=${MOUNT}_$(basename $testdir)
23713
23714         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23715
23716         mkdir -p $submount || error "mkdir $submount failed"
23717         stack_trap "rmdir $submount"
23718
23719         FILESET="$fileset/$testdir" mount_client $submount ||
23720                 error "mount $FILESET failed"
23721         stack_trap "umount $submount"
23722
23723         local mdts=$(comma_list $(mdts_nodes))
23724
23725         local nrpcs
23726
23727         stat $submount > /dev/null || error "stat $submount failed"
23728         cancel_lru_locks $MDC
23729         stat $submount > /dev/null || error "stat $submount failed"
23730         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23731         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23732         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23733         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23734                 awk '/getattr/ {sum += $2} END {print sum}')
23735
23736         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23737 }
23738
23739 test_247g() {
23740         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23741
23742         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23743                 error "mkdir $tdir failed"
23744         test_subdir_mount_lock $tdir
23745 }
23746 run_test 247g "striped directory submount revalidate ROOT from cache"
23747
23748 test_247h() {
23749         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23750         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23751                 skip "Need MDS version at least 2.15.51"
23752
23753         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23754         test_subdir_mount_lock $tdir
23755         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23756         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23757                 error "mkdir $tdir.1 failed"
23758         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23759 }
23760 run_test 247h "remote directory submount revalidate ROOT from cache"
23761
23762 test_248a() {
23763         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23764         [ -z "$fast_read_sav" ] && skip "no fast read support"
23765
23766         # create a large file for fast read verification
23767         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23768
23769         # make sure the file is created correctly
23770         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23771                 { rm -f $DIR/$tfile; skip "file creation error"; }
23772
23773         echo "Test 1: verify that fast read is 4 times faster on cache read"
23774
23775         # small read with fast read enabled
23776         $LCTL set_param -n llite.*.fast_read=1
23777         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23778                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23779                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23780         # small read with fast read disabled
23781         $LCTL set_param -n llite.*.fast_read=0
23782         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23783                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23784                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23785
23786         # verify that fast read is 4 times faster for cache read
23787         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23788                 error_not_in_vm "fast read was not 4 times faster: " \
23789                            "$t_fast vs $t_slow"
23790
23791         echo "Test 2: verify the performance between big and small read"
23792         $LCTL set_param -n llite.*.fast_read=1
23793
23794         # 1k non-cache read
23795         cancel_lru_locks osc
23796         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23797                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23798                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23799
23800         # 1M non-cache read
23801         cancel_lru_locks osc
23802         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23803                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23804                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23805
23806         # verify that big IO is not 4 times faster than small IO
23807         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23808                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23809
23810         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23811         rm -f $DIR/$tfile
23812 }
23813 run_test 248a "fast read verification"
23814
23815 test_248b() {
23816         # Default short_io_bytes=16384, try both smaller and larger sizes.
23817         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23818         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23819         echo "bs=53248 count=113 normal buffered write"
23820         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23821                 error "dd of initial data file failed"
23822         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23823
23824         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23825         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23826                 error "dd with sync normal writes failed"
23827         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23828
23829         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23830         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23831                 error "dd with sync small writes failed"
23832         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23833
23834         cancel_lru_locks osc
23835
23836         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23837         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23838         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23839         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23840                 iflag=direct || error "dd with O_DIRECT small read failed"
23841         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23842         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23843                 error "compare $TMP/$tfile.1 failed"
23844
23845         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23846         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23847
23848         # just to see what the maximum tunable value is, and test parsing
23849         echo "test invalid parameter 2MB"
23850         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23851                 error "too-large short_io_bytes allowed"
23852         echo "test maximum parameter 512KB"
23853         # if we can set a larger short_io_bytes, run test regardless of version
23854         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23855                 # older clients may not allow setting it this large, that's OK
23856                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23857                         skip "Need at least client version 2.13.50"
23858                 error "medium short_io_bytes failed"
23859         fi
23860         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23861         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23862
23863         echo "test large parameter 64KB"
23864         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23865         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23866
23867         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23868         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23869                 error "dd with sync large writes failed"
23870         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23871
23872         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23873         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23874         num=$((113 * 4096 / PAGE_SIZE))
23875         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23876         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23877                 error "dd with O_DIRECT large writes failed"
23878         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23879                 error "compare $DIR/$tfile.3 failed"
23880
23881         cancel_lru_locks osc
23882
23883         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23884         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23885                 error "dd with O_DIRECT large read failed"
23886         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23887                 error "compare $TMP/$tfile.2 failed"
23888
23889         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23890         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23891                 error "dd with O_DIRECT large read failed"
23892         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23893                 error "compare $TMP/$tfile.3 failed"
23894 }
23895 run_test 248b "test short_io read and write for both small and large sizes"
23896
23897 test_248c() {
23898         $LCTL set_param llite.*.read_ahead_stats=c
23899         # This test compares whole file readahead to non-whole file readahead
23900         # The performance should be consistently slightly faster for whole file,
23901         # and the bug caused whole file readahead to be 80-100x slower, but to
23902         # account for possible test system lag, we require whole file to be
23903         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23904         # test
23905         local time1
23906         local time2
23907         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23908         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23909         counter=0
23910
23911         while [ $counter -lt 3 ]; do
23912                 # Increment the counter
23913                 ((counter++))
23914
23915                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23916                 rm -f $DIR/$tfile
23917                 touch $DIR/$tfile || error "(0) failed to create file"
23918                 # 64 MiB
23919                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23920                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23921                 echo "whole file readahead of 64 MiB took $time1 seconds"
23922                 $LCTL get_param llite.*.read_ahead_stats
23923
23924                 $LCTL set_param llite.*.read_ahead_stats=c
23925                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23926                 rm -f $DIR/$tfile
23927                 touch $DIR/$tfile || error "(2) failed to create file"
23928                 # 64 MiB
23929                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23930                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23931                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23932                 $LCTL get_param llite.*.read_ahead_stats
23933
23934                 # Check if time1 is not more than 1.5 times2
23935                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23936
23937                 if [[ $timecheck -eq 1 ]]; then
23938                         echo "Test passed on attempt $counter"
23939                         # Exit the loop
23940                         counter=4
23941                 else
23942                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
23943                 fi
23944         done
23945         if [ $counter -eq 3 ]; then
23946                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
23947         fi
23948
23949 }
23950 run_test 248c "verify whole file read behavior"
23951
23952 test_249() { # LU-7890
23953         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23954                 skip "Need at least version 2.8.54"
23955
23956         rm -f $DIR/$tfile
23957         $LFS setstripe -c 1 $DIR/$tfile
23958         # Offset 2T == 4k * 512M
23959         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23960                 error "dd to 2T offset failed"
23961 }
23962 run_test 249 "Write above 2T file size"
23963
23964 test_250() {
23965         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23966          && skip "no 16TB file size limit on ZFS"
23967
23968         $LFS setstripe -c 1 $DIR/$tfile
23969         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23970         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23971         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23972         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23973                 conv=notrunc,fsync && error "append succeeded"
23974         return 0
23975 }
23976 run_test 250 "Write above 16T limit"
23977
23978 test_251a() {
23979         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23980
23981         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23982         #Skip once - writing the first stripe will succeed
23983         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23984         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23985                 error "short write happened"
23986
23987         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23988         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23989                 error "short read happened"
23990
23991         rm -f $DIR/$tfile
23992 }
23993 run_test 251a "Handling short read and write correctly"
23994
23995 test_251b() {
23996         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
23997                 error "write $tfile failed"
23998
23999         sleep 2 && echo 12345 >> $DIR/$tfile &
24000
24001         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24002         $LCTL set_param fail_loc=0x1431 fail_val=5
24003         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24004         # 5 seconds, read 10 bytes, the short read should
24005         # report:
24006         #                start ->+ read_len -> offset_after_read read_count
24007         #     short read: 4096 ->+ 10 -> 4096 0
24008         # not:
24009         #     short read: 4096 ->+ 10 -> 4102 0
24010         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24011                         awk '/short read/ { print $7 }')
24012         (( off == 4096 )) ||
24013                 error "short read should set offset at 4096, not $off"
24014 }
24015 run_test 251b "short read restore offset correctly"
24016
24017 test_252() {
24018         remote_mds_nodsh && skip "remote MDS with nodsh"
24019         remote_ost_nodsh && skip "remote OST with nodsh"
24020         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24021                 skip_env "ldiskfs only test"
24022         fi
24023
24024         local tgt
24025         local dev
24026         local out
24027         local uuid
24028         local num
24029         local gen
24030
24031         # check lr_reader on OST0000
24032         tgt=ost1
24033         dev=$(facet_device $tgt)
24034         out=$(do_facet $tgt $LR_READER $dev)
24035         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24036         echo "$out"
24037         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24038         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24039                 error "Invalid uuid returned by $LR_READER on target $tgt"
24040         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24041
24042         # check lr_reader -c on MDT0000
24043         tgt=mds1
24044         dev=$(facet_device $tgt)
24045         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24046                 skip "$LR_READER does not support additional options"
24047         fi
24048         out=$(do_facet $tgt $LR_READER -c $dev)
24049         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24050         echo "$out"
24051         num=$(echo "$out" | grep -c "mdtlov")
24052         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24053                 error "Invalid number of mdtlov clients returned by $LR_READER"
24054         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24055
24056         # check lr_reader -cr on MDT0000
24057         out=$(do_facet $tgt $LR_READER -cr $dev)
24058         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24059         echo "$out"
24060         echo "$out" | grep -q "^reply_data:$" ||
24061                 error "$LR_READER should have returned 'reply_data' section"
24062         num=$(echo "$out" | grep -c "client_generation")
24063         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24064 }
24065 run_test 252 "check lr_reader tool"
24066
24067 test_253() {
24068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24069         remote_mds_nodsh && skip "remote MDS with nodsh"
24070         remote_mgs_nodsh && skip "remote MGS with nodsh"
24071         check_set_fallocate_or_skip
24072
24073         local ostidx=0
24074         local rc=0
24075         local ost_name=$(ostname_from_index $ostidx)
24076
24077         # on the mdt's osc
24078         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24079         do_facet $SINGLEMDS $LCTL get_param -n \
24080                 osp.$mdtosc_proc1.reserved_mb_high ||
24081                 skip  "remote MDS does not support reserved_mb_high"
24082
24083         rm -rf $DIR/$tdir
24084         wait_mds_ost_sync
24085         wait_delete_completed
24086         mkdir $DIR/$tdir
24087         stack_trap "rm -rf $DIR/$tdir"
24088
24089         pool_add $TESTNAME || error "Pool creation failed"
24090         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24091
24092         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24093                 error "Setstripe failed"
24094
24095         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24096
24097         local wms=$(ost_watermarks_get $ostidx)
24098
24099         ost_watermarks_set $ostidx 60 50
24100         stack_trap "ost_watermarks_set $ostidx $wms"
24101
24102         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24103         local size=$((free_kb * 1024))
24104
24105         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24106                 error "fallocate failed"
24107         sleep_maxage
24108
24109         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24110                         osp.$mdtosc_proc1.prealloc_status)
24111         echo "prealloc_status $oa_status"
24112
24113         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24114                 error "File creation should fail"
24115
24116         #object allocation was stopped, but we still able to append files
24117         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24118                 oflag=append || error "Append failed"
24119
24120         rm -f $DIR/$tdir/$tfile.0
24121         rm -f $DIR/$tdir/fill_ost$ostidx
24122
24123         wait_delete_completed
24124         sleep_maxage
24125
24126         for i in $(seq 10 12); do
24127                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24128                         2>/dev/null || error "File creation failed after rm"
24129         done
24130
24131         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24132                         osp.$mdtosc_proc1.prealloc_status)
24133         echo "prealloc_status $oa_status"
24134
24135         if (( oa_status != 0 )); then
24136                 error "Object allocation still disable after rm"
24137         fi
24138 }
24139 run_test 253 "Check object allocation limit"
24140
24141 test_254() {
24142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24143         remote_mds_nodsh && skip "remote MDS with nodsh"
24144
24145         local mdt=$(facet_svc $SINGLEMDS)
24146
24147         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24148                 skip "MDS does not support changelog_size"
24149
24150         local cl_user
24151
24152         changelog_register || error "changelog_register failed"
24153
24154         changelog_clear 0 || error "changelog_clear failed"
24155
24156         local size1=$(do_facet $SINGLEMDS \
24157                       $LCTL get_param -n mdd.$mdt.changelog_size)
24158         echo "Changelog size $size1"
24159
24160         rm -rf $DIR/$tdir
24161         $LFS mkdir -i 0 $DIR/$tdir
24162         # change something
24163         mkdir -p $DIR/$tdir/pics/2008/zachy
24164         touch $DIR/$tdir/pics/2008/zachy/timestamp
24165         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24166         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24167         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24168         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24169         rm $DIR/$tdir/pics/desktop.jpg
24170
24171         local size2=$(do_facet $SINGLEMDS \
24172                       $LCTL get_param -n mdd.$mdt.changelog_size)
24173         echo "Changelog size after work $size2"
24174
24175         (( $size2 > $size1 )) ||
24176                 error "new Changelog size=$size2 less than old size=$size1"
24177 }
24178 run_test 254 "Check changelog size"
24179
24180 ladvise_no_type()
24181 {
24182         local type=$1
24183         local file=$2
24184
24185         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24186                 awk -F: '{print $2}' | grep $type > /dev/null
24187         if [ $? -ne 0 ]; then
24188                 return 0
24189         fi
24190         return 1
24191 }
24192
24193 ladvise_no_ioctl()
24194 {
24195         local file=$1
24196
24197         lfs ladvise -a willread $file > /dev/null 2>&1
24198         if [ $? -eq 0 ]; then
24199                 return 1
24200         fi
24201
24202         lfs ladvise -a willread $file 2>&1 |
24203                 grep "Inappropriate ioctl for device" > /dev/null
24204         if [ $? -eq 0 ]; then
24205                 return 0
24206         fi
24207         return 1
24208 }
24209
24210 percent() {
24211         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24212 }
24213
24214 # run a random read IO workload
24215 # usage: random_read_iops <filename> <filesize> <iosize>
24216 random_read_iops() {
24217         local file=$1
24218         local fsize=$2
24219         local iosize=${3:-4096}
24220
24221         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24222                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24223 }
24224
24225 drop_file_oss_cache() {
24226         local file="$1"
24227         local nodes="$2"
24228
24229         $LFS ladvise -a dontneed $file 2>/dev/null ||
24230                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24231 }
24232
24233 ladvise_willread_performance()
24234 {
24235         local repeat=10
24236         local average_origin=0
24237         local average_cache=0
24238         local average_ladvise=0
24239
24240         for ((i = 1; i <= $repeat; i++)); do
24241                 echo "Iter $i/$repeat: reading without willread hint"
24242                 cancel_lru_locks osc
24243                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24244                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24245                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24246                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24247
24248                 cancel_lru_locks osc
24249                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24250                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24251                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24252
24253                 cancel_lru_locks osc
24254                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24255                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24256                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24257                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24258                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24259         done
24260         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24261         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24262         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24263
24264         speedup_cache=$(percent $average_cache $average_origin)
24265         speedup_ladvise=$(percent $average_ladvise $average_origin)
24266
24267         echo "Average uncached read: $average_origin"
24268         echo "Average speedup with OSS cached read:" \
24269                 "$average_cache = +$speedup_cache%"
24270         echo "Average speedup with ladvise willread:" \
24271                 "$average_ladvise = +$speedup_ladvise%"
24272
24273         local lowest_speedup=20
24274         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24275                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24276                      "got $speedup_cache%. Skipping ladvise willread check."
24277                 return 0
24278         fi
24279
24280         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24281         # it is still good to run until then to exercise 'ladvise willread'
24282         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24283                 [ "$ost1_FSTYPE" = "zfs" ] &&
24284                 echo "osd-zfs does not support dontneed or drop_caches" &&
24285                 return 0
24286
24287         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24288         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24289                 error_not_in_vm "Speedup with willread is less than " \
24290                         "$lowest_speedup%, got $speedup_ladvise%"
24291 }
24292
24293 test_255a() {
24294         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24295                 skip "lustre < 2.8.54 does not support ladvise "
24296         remote_ost_nodsh && skip "remote OST with nodsh"
24297
24298         stack_trap "rm -f $DIR/$tfile"
24299         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24300
24301         ladvise_no_type willread $DIR/$tfile &&
24302                 skip "willread ladvise is not supported"
24303
24304         ladvise_no_ioctl $DIR/$tfile &&
24305                 skip "ladvise ioctl is not supported"
24306
24307         local size_mb=100
24308         local size=$((size_mb * 1048576))
24309         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24310                 error "dd to $DIR/$tfile failed"
24311
24312         lfs ladvise -a willread $DIR/$tfile ||
24313                 error "Ladvise failed with no range argument"
24314
24315         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24316                 error "Ladvise failed with no -l or -e argument"
24317
24318         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24319                 error "Ladvise failed with only -e argument"
24320
24321         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24322                 error "Ladvise failed with only -l argument"
24323
24324         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24325                 error "End offset should not be smaller than start offset"
24326
24327         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24328                 error "End offset should not be equal to start offset"
24329
24330         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24331                 error "Ladvise failed with overflowing -s argument"
24332
24333         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24334                 error "Ladvise failed with overflowing -e argument"
24335
24336         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24337                 error "Ladvise failed with overflowing -l argument"
24338
24339         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24340                 error "Ladvise succeeded with conflicting -l and -e arguments"
24341
24342         echo "Synchronous ladvise should wait"
24343         local delay=8
24344 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24345         do_nodes $(comma_list $(osts_nodes)) \
24346                 $LCTL set_param fail_val=$delay fail_loc=0x237
24347         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24348                 $LCTL set_param fail_loc=0"
24349
24350         local start_ts=$SECONDS
24351         lfs ladvise -a willread $DIR/$tfile ||
24352                 error "Ladvise failed with no range argument"
24353         local end_ts=$SECONDS
24354         local inteval_ts=$((end_ts - start_ts))
24355
24356         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24357                 error "Synchronous advice didn't wait reply"
24358         fi
24359
24360         echo "Asynchronous ladvise shouldn't wait"
24361         local start_ts=$SECONDS
24362         lfs ladvise -a willread -b $DIR/$tfile ||
24363                 error "Ladvise failed with no range argument"
24364         local end_ts=$SECONDS
24365         local inteval_ts=$((end_ts - start_ts))
24366
24367         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24368                 error "Asynchronous advice blocked"
24369         fi
24370
24371         ladvise_willread_performance
24372 }
24373 run_test 255a "check 'lfs ladvise -a willread'"
24374
24375 facet_meminfo() {
24376         local facet=$1
24377         local info=$2
24378
24379         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24380 }
24381
24382 test_255b() {
24383         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24384                 skip "lustre < 2.8.54 does not support ladvise "
24385         remote_ost_nodsh && skip "remote OST with nodsh"
24386
24387         stack_trap "rm -f $DIR/$tfile"
24388         lfs setstripe -c 1 -i 0 $DIR/$tfile
24389
24390         ladvise_no_type dontneed $DIR/$tfile &&
24391                 skip "dontneed ladvise is not supported"
24392
24393         ladvise_no_ioctl $DIR/$tfile &&
24394                 skip "ladvise ioctl is not supported"
24395
24396         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24397                 [ "$ost1_FSTYPE" = "zfs" ] &&
24398                 skip "zfs-osd does not support 'ladvise dontneed'"
24399
24400         local size_mb=100
24401         local size=$((size_mb * 1048576))
24402         # In order to prevent disturbance of other processes, only check 3/4
24403         # of the memory usage
24404         local kibibytes=$((size_mb * 1024 * 3 / 4))
24405
24406         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24407                 error "dd to $DIR/$tfile failed"
24408
24409         #force write to complete before dropping OST cache & checking memory
24410         sync
24411
24412         local total=$(facet_meminfo ost1 MemTotal)
24413         echo "Total memory: $total KiB"
24414
24415         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24416         local before_read=$(facet_meminfo ost1 Cached)
24417         echo "Cache used before read: $before_read KiB"
24418
24419         lfs ladvise -a willread $DIR/$tfile ||
24420                 error "Ladvise willread failed"
24421         local after_read=$(facet_meminfo ost1 Cached)
24422         echo "Cache used after read: $after_read KiB"
24423
24424         lfs ladvise -a dontneed $DIR/$tfile ||
24425                 error "Ladvise dontneed again failed"
24426         local no_read=$(facet_meminfo ost1 Cached)
24427         echo "Cache used after dontneed ladvise: $no_read KiB"
24428
24429         if [ $total -lt $((before_read + kibibytes)) ]; then
24430                 echo "Memory is too small, abort checking"
24431                 return 0
24432         fi
24433
24434         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24435                 error "Ladvise willread should use more memory" \
24436                         "than $kibibytes KiB"
24437         fi
24438
24439         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24440                 error "Ladvise dontneed should release more memory" \
24441                         "than $kibibytes KiB"
24442         fi
24443 }
24444 run_test 255b "check 'lfs ladvise -a dontneed'"
24445
24446 test_255c() {
24447         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24448                 skip "lustre < 2.10.50 does not support lockahead"
24449
24450         local ost1_imp=$(get_osc_import_name client ost1)
24451         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24452                          cut -d'.' -f2)
24453         local count
24454         local new_count
24455         local difference
24456         local i
24457         local rc
24458
24459         test_mkdir -p $DIR/$tdir
24460         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24461
24462         #test 10 returns only success/failure
24463         i=10
24464         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24465         rc=$?
24466         if [ $rc -eq 255 ]; then
24467                 error "Ladvise test${i} failed, ${rc}"
24468         fi
24469
24470         #test 11 counts lock enqueue requests, all others count new locks
24471         i=11
24472         count=$(do_facet ost1 \
24473                 $LCTL get_param -n ost.OSS.ost.stats)
24474         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24475
24476         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24477         rc=$?
24478         if [ $rc -eq 255 ]; then
24479                 error "Ladvise test${i} failed, ${rc}"
24480         fi
24481
24482         new_count=$(do_facet ost1 \
24483                 $LCTL get_param -n ost.OSS.ost.stats)
24484         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24485                    awk '{ print $2 }')
24486
24487         difference="$((new_count - count))"
24488         if [ $difference -ne $rc ]; then
24489                 error "Ladvise test${i}, bad enqueue count, returned " \
24490                       "${rc}, actual ${difference}"
24491         fi
24492
24493         for i in $(seq 12 21); do
24494                 # If we do not do this, we run the risk of having too many
24495                 # locks and starting lock cancellation while we are checking
24496                 # lock counts.
24497                 cancel_lru_locks osc
24498
24499                 count=$($LCTL get_param -n \
24500                        ldlm.namespaces.$imp_name.lock_unused_count)
24501
24502                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24503                 rc=$?
24504                 if [ $rc -eq 255 ]; then
24505                         error "Ladvise test ${i} failed, ${rc}"
24506                 fi
24507
24508                 new_count=$($LCTL get_param -n \
24509                        ldlm.namespaces.$imp_name.lock_unused_count)
24510                 difference="$((new_count - count))"
24511
24512                 # Test 15 output is divided by 100 to map down to valid return
24513                 if [ $i -eq 15 ]; then
24514                         rc="$((rc * 100))"
24515                 fi
24516
24517                 if [ $difference -ne $rc ]; then
24518                         error "Ladvise test ${i}, bad lock count, returned " \
24519                               "${rc}, actual ${difference}"
24520                 fi
24521         done
24522
24523         #test 22 returns only success/failure
24524         i=22
24525         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24526         rc=$?
24527         if [ $rc -eq 255 ]; then
24528                 error "Ladvise test${i} failed, ${rc}"
24529         fi
24530 }
24531 run_test 255c "suite of ladvise lockahead tests"
24532
24533 test_256() {
24534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24535         remote_mds_nodsh && skip "remote MDS with nodsh"
24536         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24537         changelog_users $SINGLEMDS | grep "^cl" &&
24538                 skip "active changelog user"
24539
24540         local cl_user
24541         local cat_sl
24542         local mdt_dev
24543
24544         mdt_dev=$(facet_device $SINGLEMDS)
24545         echo $mdt_dev
24546
24547         changelog_register || error "changelog_register failed"
24548
24549         rm -rf $DIR/$tdir
24550         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24551
24552         changelog_clear 0 || error "changelog_clear failed"
24553
24554         # change something
24555         touch $DIR/$tdir/{1..10}
24556
24557         # stop the MDT
24558         stop $SINGLEMDS || error "Fail to stop MDT"
24559
24560         # remount the MDT
24561         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24562                 error "Fail to start MDT"
24563
24564         #after mount new plainllog is used
24565         touch $DIR/$tdir/{11..19}
24566         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24567         stack_trap "rm -f $tmpfile"
24568         cat_sl=$(do_facet $SINGLEMDS "sync; \
24569                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24570                  llog_reader $tmpfile | grep -c type=1064553b")
24571         do_facet $SINGLEMDS llog_reader $tmpfile
24572
24573         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24574
24575         changelog_clear 0 || error "changelog_clear failed"
24576
24577         cat_sl=$(do_facet $SINGLEMDS "sync; \
24578                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24579                  llog_reader $tmpfile | grep -c type=1064553b")
24580
24581         if (( cat_sl == 2 )); then
24582                 error "Empty plain llog was not deleted from changelog catalog"
24583         elif (( cat_sl != 1 )); then
24584                 error "Active plain llog shouldn't be deleted from catalog"
24585         fi
24586 }
24587 run_test 256 "Check llog delete for empty and not full state"
24588
24589 test_257() {
24590         remote_mds_nodsh && skip "remote MDS with nodsh"
24591         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24592                 skip "Need MDS version at least 2.8.55"
24593
24594         test_mkdir $DIR/$tdir
24595
24596         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24597                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24598         stat $DIR/$tdir
24599
24600 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24601         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24602         local facet=mds$((mdtidx + 1))
24603         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24604         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24605
24606         stop $facet || error "stop MDS failed"
24607         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24608                 error "start MDS fail"
24609         wait_recovery_complete $facet
24610 }
24611 run_test 257 "xattr locks are not lost"
24612
24613 # Verify we take the i_mutex when security requires it
24614 test_258a() {
24615 #define OBD_FAIL_IMUTEX_SEC 0x141c
24616         $LCTL set_param fail_loc=0x141c
24617         touch $DIR/$tfile
24618         chmod u+s $DIR/$tfile
24619         chmod a+rwx $DIR/$tfile
24620         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24621         RC=$?
24622         if [ $RC -ne 0 ]; then
24623                 error "error, failed to take i_mutex, rc=$?"
24624         fi
24625         rm -f $DIR/$tfile
24626 }
24627 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24628
24629 # Verify we do NOT take the i_mutex in the normal case
24630 test_258b() {
24631 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24632         $LCTL set_param fail_loc=0x141d
24633         touch $DIR/$tfile
24634         chmod a+rwx $DIR
24635         chmod a+rw $DIR/$tfile
24636         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24637         RC=$?
24638         if [ $RC -ne 0 ]; then
24639                 error "error, took i_mutex unnecessarily, rc=$?"
24640         fi
24641         rm -f $DIR/$tfile
24642
24643 }
24644 run_test 258b "verify i_mutex security behavior"
24645
24646 test_259() {
24647         local file=$DIR/$tfile
24648         local before
24649         local after
24650
24651         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24652
24653         stack_trap "rm -f $file" EXIT
24654
24655         wait_delete_completed
24656         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24657         echo "before: $before"
24658
24659         $LFS setstripe -i 0 -c 1 $file
24660         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24661         sync_all_data
24662         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24663         echo "after write: $after"
24664
24665 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24666         do_facet ost1 $LCTL set_param fail_loc=0x2301
24667         $TRUNCATE $file 0
24668         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24669         echo "after truncate: $after"
24670
24671         stop ost1
24672         do_facet ost1 $LCTL set_param fail_loc=0
24673         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24674         sleep 2
24675         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24676         echo "after restart: $after"
24677         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24678                 error "missing truncate?"
24679
24680         return 0
24681 }
24682 run_test 259 "crash at delayed truncate"
24683
24684 test_260() {
24685 #define OBD_FAIL_MDC_CLOSE               0x806
24686         $LCTL set_param fail_loc=0x80000806
24687         touch $DIR/$tfile
24688
24689 }
24690 run_test 260 "Check mdc_close fail"
24691
24692 ### Data-on-MDT sanity tests ###
24693 test_270a() {
24694         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24695                 skip "Need MDS version at least 2.10.55 for DoM"
24696
24697         # create DoM file
24698         local dom=$DIR/$tdir/dom_file
24699         local tmp=$DIR/$tdir/tmp_file
24700
24701         mkdir_on_mdt0 $DIR/$tdir
24702
24703         # basic checks for DoM component creation
24704         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24705                 error "Can set MDT layout to non-first entry"
24706
24707         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24708                 error "Can define multiple entries as MDT layout"
24709
24710         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24711
24712         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24713         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24714         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24715
24716         local mdtidx=$($LFS getstripe -m $dom)
24717         local mdtname=MDT$(printf %04x $mdtidx)
24718         local facet=mds$((mdtidx + 1))
24719         local space_check=1
24720
24721         # Skip free space checks with ZFS
24722         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24723
24724         # write
24725         sync
24726         local size_tmp=$((65536 * 3))
24727         local mdtfree1=$(do_facet $facet \
24728                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24729
24730         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24731         # check also direct IO along write
24732         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24733         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24734         sync
24735         cmp $tmp $dom || error "file data is different"
24736         [ $(stat -c%s $dom) == $size_tmp ] ||
24737                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24738         if [ $space_check == 1 ]; then
24739                 local mdtfree2=$(do_facet $facet \
24740                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24741
24742                 # increase in usage from by $size_tmp
24743                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24744                         error "MDT free space wrong after write: " \
24745                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24746         fi
24747
24748         # truncate
24749         local size_dom=10000
24750
24751         $TRUNCATE $dom $size_dom
24752         [ $(stat -c%s $dom) == $size_dom ] ||
24753                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24754         if [ $space_check == 1 ]; then
24755                 mdtfree1=$(do_facet $facet \
24756                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24757                 # decrease in usage from $size_tmp to new $size_dom
24758                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24759                   $(((size_tmp - size_dom) / 1024)) ] ||
24760                         error "MDT free space is wrong after truncate: " \
24761                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24762         fi
24763
24764         # append
24765         cat $tmp >> $dom
24766         sync
24767         size_dom=$((size_dom + size_tmp))
24768         [ $(stat -c%s $dom) == $size_dom ] ||
24769                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24770         if [ $space_check == 1 ]; then
24771                 mdtfree2=$(do_facet $facet \
24772                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24773                 # increase in usage by $size_tmp from previous
24774                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24775                         error "MDT free space is wrong after append: " \
24776                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24777         fi
24778
24779         # delete
24780         rm $dom
24781         if [ $space_check == 1 ]; then
24782                 mdtfree1=$(do_facet $facet \
24783                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24784                 # decrease in usage by $size_dom from previous
24785                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24786                         error "MDT free space is wrong after removal: " \
24787                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24788         fi
24789
24790         # combined striping
24791         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24792                 error "Can't create DoM + OST striping"
24793
24794         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24795         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24796         # check also direct IO along write
24797         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24798         sync
24799         cmp $tmp $dom || error "file data is different"
24800         [ $(stat -c%s $dom) == $size_tmp ] ||
24801                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24802         rm $dom $tmp
24803
24804         return 0
24805 }
24806 run_test 270a "DoM: basic functionality tests"
24807
24808 test_270b() {
24809         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24810                 skip "Need MDS version at least 2.10.55"
24811
24812         local dom=$DIR/$tdir/dom_file
24813         local max_size=1048576
24814
24815         mkdir -p $DIR/$tdir
24816         $LFS setstripe -E $max_size -L mdt $dom
24817
24818         # truncate over the limit
24819         $TRUNCATE $dom $(($max_size + 1)) &&
24820                 error "successful truncate over the maximum size"
24821         # write over the limit
24822         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24823                 error "successful write over the maximum size"
24824         # append over the limit
24825         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24826         echo "12345" >> $dom && error "successful append over the maximum size"
24827         rm $dom
24828
24829         return 0
24830 }
24831 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24832
24833 test_270c() {
24834         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24835                 skip "Need MDS version at least 2.10.55"
24836
24837         mkdir -p $DIR/$tdir
24838         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24839
24840         # check files inherit DoM EA
24841         touch $DIR/$tdir/first
24842         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24843                 error "bad pattern"
24844         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24845                 error "bad stripe count"
24846         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24847                 error "bad stripe size"
24848
24849         # check directory inherits DoM EA and uses it as default
24850         mkdir $DIR/$tdir/subdir
24851         touch $DIR/$tdir/subdir/second
24852         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24853                 error "bad pattern in sub-directory"
24854         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24855                 error "bad stripe count in sub-directory"
24856         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24857                 error "bad stripe size in sub-directory"
24858         return 0
24859 }
24860 run_test 270c "DoM: DoM EA inheritance tests"
24861
24862 test_270d() {
24863         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24864                 skip "Need MDS version at least 2.10.55"
24865
24866         mkdir -p $DIR/$tdir
24867         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24868
24869         # inherit default DoM striping
24870         mkdir $DIR/$tdir/subdir
24871         touch $DIR/$tdir/subdir/f1
24872
24873         # change default directory striping
24874         $LFS setstripe -c 1 $DIR/$tdir/subdir
24875         touch $DIR/$tdir/subdir/f2
24876         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24877                 error "wrong default striping in file 2"
24878         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24879                 error "bad pattern in file 2"
24880         return 0
24881 }
24882 run_test 270d "DoM: change striping from DoM to RAID0"
24883
24884 test_270e() {
24885         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24886                 skip "Need MDS version at least 2.10.55"
24887
24888         mkdir -p $DIR/$tdir/dom
24889         mkdir -p $DIR/$tdir/norm
24890         DOMFILES=20
24891         NORMFILES=10
24892         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24893         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24894
24895         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24896         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24897
24898         # find DoM files by layout
24899         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24900         [ $NUM -eq  $DOMFILES ] ||
24901                 error "lfs find -L: found $NUM, expected $DOMFILES"
24902         echo "Test 1: lfs find 20 DOM files by layout: OK"
24903
24904         # there should be 1 dir with default DOM striping
24905         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24906         [ $NUM -eq  1 ] ||
24907                 error "lfs find -L: found $NUM, expected 1 dir"
24908         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24909
24910         # find DoM files by stripe size
24911         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24912         [ $NUM -eq  $DOMFILES ] ||
24913                 error "lfs find -S: found $NUM, expected $DOMFILES"
24914         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24915
24916         # find files by stripe offset except DoM files
24917         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24918         [ $NUM -eq  $NORMFILES ] ||
24919                 error "lfs find -i: found $NUM, expected $NORMFILES"
24920         echo "Test 5: lfs find no DOM files by stripe index: OK"
24921         return 0
24922 }
24923 run_test 270e "DoM: lfs find with DoM files test"
24924
24925 test_270f() {
24926         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24927                 skip "Need MDS version at least 2.10.55"
24928
24929         local mdtname=${FSNAME}-MDT0000-mdtlov
24930         local dom=$DIR/$tdir/dom_file
24931         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24932                                                 lod.$mdtname.dom_stripesize)
24933         local dom_limit=131072
24934
24935         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24936         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24937                                                 lod.$mdtname.dom_stripesize)
24938         [ ${dom_limit} -eq ${dom_current} ] ||
24939                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24940
24941         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24942         $LFS setstripe -d $DIR/$tdir
24943         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24944                 error "Can't set directory default striping"
24945
24946         # exceed maximum stripe size
24947         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24948                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24949         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24950                 error "Able to create DoM component size more than LOD limit"
24951
24952         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24953         dom_current=$(do_facet mds1 $LCTL get_param -n \
24954                                                 lod.$mdtname.dom_stripesize)
24955         [ 0 -eq ${dom_current} ] ||
24956                 error "Can't set zero DoM stripe limit"
24957         rm $dom
24958
24959         # attempt to create DoM file on server with disabled DoM should
24960         # remove DoM entry from layout and be succeed
24961         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24962                 error "Can't create DoM file (DoM is disabled)"
24963         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24964                 error "File has DoM component while DoM is disabled"
24965         rm $dom
24966
24967         # attempt to create DoM file with only DoM stripe should return error
24968         $LFS setstripe -E $dom_limit -L mdt $dom &&
24969                 error "Able to create DoM-only file while DoM is disabled"
24970
24971         # too low values to be aligned with smallest stripe size 64K
24972         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24973         dom_current=$(do_facet mds1 $LCTL get_param -n \
24974                                                 lod.$mdtname.dom_stripesize)
24975         [ 30000 -eq ${dom_current} ] &&
24976                 error "Can set too small DoM stripe limit"
24977
24978         # 64K is a minimal stripe size in Lustre, expect limit of that size
24979         [ 65536 -eq ${dom_current} ] ||
24980                 error "Limit is not set to 64K but ${dom_current}"
24981
24982         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24983         dom_current=$(do_facet mds1 $LCTL get_param -n \
24984                                                 lod.$mdtname.dom_stripesize)
24985         echo $dom_current
24986         [ 2147483648 -eq ${dom_current} ] &&
24987                 error "Can set too large DoM stripe limit"
24988
24989         do_facet mds1 $LCTL set_param -n \
24990                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24991         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24992                 error "Can't create DoM component size after limit change"
24993         do_facet mds1 $LCTL set_param -n \
24994                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24995         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24996                 error "Can't create DoM file after limit decrease"
24997         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24998                 error "Can create big DoM component after limit decrease"
24999         touch ${dom}_def ||
25000                 error "Can't create file with old default layout"
25001
25002         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25003         return 0
25004 }
25005 run_test 270f "DoM: maximum DoM stripe size checks"
25006
25007 test_270g() {
25008         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25009                 skip "Need MDS version at least 2.13.52"
25010         local dom=$DIR/$tdir/$tfile
25011
25012         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25013         local lodname=${FSNAME}-MDT0000-mdtlov
25014
25015         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25016         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25017         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25018         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25019
25020         local dom_limit=1024
25021         local dom_threshold="50%"
25022
25023         $LFS setstripe -d $DIR/$tdir
25024         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25025                 error "Can't set directory default striping"
25026
25027         do_facet mds1 $LCTL set_param -n \
25028                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25029         # set 0 threshold and create DOM file to change tunable stripesize
25030         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25031         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25032                 error "Failed to create $dom file"
25033         # now tunable dom_cur_stripesize should reach maximum
25034         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25035                                         lod.${lodname}.dom_stripesize_cur_kb)
25036         [[ $dom_current == $dom_limit ]] ||
25037                 error "Current DOM stripesize is not maximum"
25038         rm $dom
25039
25040         # set threshold for further tests
25041         do_facet mds1 $LCTL set_param -n \
25042                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25043         echo "DOM threshold is $dom_threshold free space"
25044         local dom_def
25045         local dom_set
25046         # Spoof bfree to exceed threshold
25047         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25048         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25049         for spfree in 40 20 0 15 30 55; do
25050                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25051                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25052                         error "Failed to create $dom file"
25053                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25054                                         lod.${lodname}.dom_stripesize_cur_kb)
25055                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25056                 [[ $dom_def != $dom_current ]] ||
25057                         error "Default stripe size was not changed"
25058                 if (( spfree > 0 )) ; then
25059                         dom_set=$($LFS getstripe -S $dom)
25060                         (( dom_set == dom_def * 1024 )) ||
25061                                 error "DOM component size is still old"
25062                 else
25063                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25064                                 error "DoM component is set with no free space"
25065                 fi
25066                 rm $dom
25067                 dom_current=$dom_def
25068         done
25069 }
25070 run_test 270g "DoM: default DoM stripe size depends on free space"
25071
25072 test_270h() {
25073         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25074                 skip "Need MDS version at least 2.13.53"
25075
25076         local mdtname=${FSNAME}-MDT0000-mdtlov
25077         local dom=$DIR/$tdir/$tfile
25078         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25079
25080         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25081         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25082
25083         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25084         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25085                 error "can't create OST file"
25086         # mirrored file with DOM entry in the second mirror
25087         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25088                 error "can't create mirror with DoM component"
25089
25090         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25091
25092         # DOM component in the middle and has other enries in the same mirror,
25093         # should succeed but lost DoM component
25094         $LFS setstripe --copy=${dom}_1 $dom ||
25095                 error "Can't create file from OST|DOM mirror layout"
25096         # check new file has no DoM layout after all
25097         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25098                 error "File has DoM component while DoM is disabled"
25099 }
25100 run_test 270h "DoM: DoM stripe removal when disabled on server"
25101
25102 test_270i() {
25103         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25104                 skip "Need MDS version at least 2.14.54"
25105
25106         mkdir $DIR/$tdir
25107         # DoM with plain layout
25108         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25109                 error "default plain layout with DoM must fail"
25110         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25111                 error "setstripe plain file layout with DoM must fail"
25112         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25113                 error "default DoM layout with bad striping must fail"
25114         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25115                 error "setstripe to DoM layout with bad striping must fail"
25116         return 0
25117 }
25118 run_test 270i "DoM: setting invalid DoM striping should fail"
25119
25120 test_270j() {
25121         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25122                 skip "Need MDS version at least 2.15.55.203"
25123
25124         local dom=$DIR/$tdir/$tfile
25125         local odv
25126         local ndv
25127
25128         mkdir -p $DIR/$tdir
25129
25130         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25131
25132         odv=$($LFS data_version $dom)
25133         chmod 666 $dom
25134         mv $dom ${dom}_moved
25135         link ${dom}_moved $dom
25136         setfattr -n user.attrx -v "some_attr" $dom
25137         ndv=$($LFS data_version $dom)
25138         (( $ndv == $odv )) ||
25139                 error "data version was changed by metadata operations"
25140
25141         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25142                 error "failed to write data into $dom"
25143         cancel_lru_locks mdc
25144         ndv=$($LFS data_version $dom)
25145         (( $ndv != $odv )) ||
25146                 error "data version wasn't changed on write"
25147
25148         odv=$ndv
25149         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25150         ndv=$($LFS data_version $dom)
25151         (( $ndv != $odv )) ||
25152                 error "data version wasn't changed on truncate down"
25153
25154         odv=$ndv
25155         $TRUNCATE $dom 25000
25156         ndv=$($LFS data_version $dom)
25157         (( $ndv != $odv )) ||
25158                 error "data version wasn't changed on truncate up"
25159
25160         # check also fallocate for ldiskfs
25161         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25162                 odv=$ndv
25163                 fallocate -l 1048576 $dom
25164                 ndv=$($LFS data_version $dom)
25165                 (( $ndv != $odv )) ||
25166                         error "data version wasn't changed on fallocate"
25167
25168                 odv=$ndv
25169                 fallocate -p --offset 4096 -l 4096 $dom
25170                 ndv=$($LFS data_version $dom)
25171                 (( $ndv != $odv )) ||
25172                         error "data version wasn't changed on fallocate punch"
25173         fi
25174 }
25175 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25176
25177 test_271a() {
25178         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25179                 skip "Need MDS version at least 2.10.55"
25180
25181         local dom=$DIR/$tdir/dom
25182
25183         mkdir -p $DIR/$tdir
25184
25185         $LFS setstripe -E 1024K -L mdt $dom
25186
25187         lctl set_param -n mdc.*.stats=clear
25188         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25189         cat $dom > /dev/null
25190         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25191         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25192         ls $dom
25193         rm -f $dom
25194 }
25195 run_test 271a "DoM: data is cached for read after write"
25196
25197 test_271b() {
25198         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25199                 skip "Need MDS version at least 2.10.55"
25200
25201         local dom=$DIR/$tdir/dom
25202
25203         mkdir -p $DIR/$tdir
25204
25205         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25206
25207         lctl set_param -n mdc.*.stats=clear
25208         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25209         cancel_lru_locks mdc
25210         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25211         # second stat to check size is cached on client
25212         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25213         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25214         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25215         rm -f $dom
25216 }
25217 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25218
25219 test_271ba() {
25220         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25221                 skip "Need MDS version at least 2.10.55"
25222
25223         local dom=$DIR/$tdir/dom
25224
25225         mkdir -p $DIR/$tdir
25226
25227         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25228
25229         lctl set_param -n mdc.*.stats=clear
25230         lctl set_param -n osc.*.stats=clear
25231         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25232         cancel_lru_locks mdc
25233         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25234         # second stat to check size is cached on client
25235         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25236         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25237         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25238         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25239         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25240         rm -f $dom
25241 }
25242 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25243
25244
25245 get_mdc_stats() {
25246         local mdtidx=$1
25247         local param=$2
25248         local mdt=MDT$(printf %04x $mdtidx)
25249
25250         if [ -z $param ]; then
25251                 lctl get_param -n mdc.*$mdt*.stats
25252         else
25253                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25254         fi
25255 }
25256
25257 test_271c() {
25258         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25259                 skip "Need MDS version at least 2.10.55"
25260
25261         local dom=$DIR/$tdir/dom
25262
25263         mkdir -p $DIR/$tdir
25264
25265         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25266
25267         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25268         local facet=mds$((mdtidx + 1))
25269
25270         cancel_lru_locks mdc
25271         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25272         createmany -o $dom 1000
25273         lctl set_param -n mdc.*.stats=clear
25274         smalliomany -w $dom 1000 200
25275         get_mdc_stats $mdtidx
25276         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25277         # Each file has 1 open, 1 IO enqueues, total 2000
25278         # but now we have also +1 getxattr for security.capability, total 3000
25279         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25280         unlinkmany $dom 1000
25281
25282         cancel_lru_locks mdc
25283         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25284         createmany -o $dom 1000
25285         lctl set_param -n mdc.*.stats=clear
25286         smalliomany -w $dom 1000 200
25287         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25288         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25289         # for OPEN and IO lock.
25290         [ $((enq - enq_2)) -ge 1000 ] ||
25291                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25292         unlinkmany $dom 1000
25293         return 0
25294 }
25295 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25296
25297 cleanup_271def_tests() {
25298         trap 0
25299         rm -f $1
25300 }
25301
25302 test_271d() {
25303         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25304                 skip "Need MDS version at least 2.10.57"
25305
25306         local dom=$DIR/$tdir/dom
25307         local tmp=$TMP/$tfile
25308         trap "cleanup_271def_tests $tmp" EXIT
25309
25310         mkdir -p $DIR/$tdir
25311
25312         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25313
25314         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25315
25316         cancel_lru_locks mdc
25317         dd if=/dev/urandom of=$tmp bs=1000 count=1
25318         dd if=$tmp of=$dom bs=1000 count=1
25319         cancel_lru_locks mdc
25320
25321         cat /etc/hosts >> $tmp
25322         lctl set_param -n mdc.*.stats=clear
25323
25324         # append data to the same file it should update local page
25325         echo "Append to the same page"
25326         cat /etc/hosts >> $dom
25327         local num=$(get_mdc_stats $mdtidx ost_read)
25328         local ra=$(get_mdc_stats $mdtidx req_active)
25329         local rw=$(get_mdc_stats $mdtidx req_waittime)
25330
25331         [ -z $num ] || error "$num READ RPC occured"
25332         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25333         echo "... DONE"
25334
25335         # compare content
25336         cmp $tmp $dom || error "file miscompare"
25337
25338         cancel_lru_locks mdc
25339         lctl set_param -n mdc.*.stats=clear
25340
25341         echo "Open and read file"
25342         cat $dom > /dev/null
25343         local num=$(get_mdc_stats $mdtidx ost_read)
25344         local ra=$(get_mdc_stats $mdtidx req_active)
25345         local rw=$(get_mdc_stats $mdtidx req_waittime)
25346
25347         [ -z $num ] || error "$num READ RPC occured"
25348         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25349         echo "... DONE"
25350
25351         # compare content
25352         cmp $tmp $dom || error "file miscompare"
25353
25354         return 0
25355 }
25356 run_test 271d "DoM: read on open (1K file in reply buffer)"
25357
25358 test_271f() {
25359         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25360                 skip "Need MDS version at least 2.10.57"
25361
25362         local dom=$DIR/$tdir/dom
25363         local tmp=$TMP/$tfile
25364         trap "cleanup_271def_tests $tmp" EXIT
25365
25366         mkdir -p $DIR/$tdir
25367
25368         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25369
25370         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25371
25372         cancel_lru_locks mdc
25373         dd if=/dev/urandom of=$tmp bs=265000 count=1
25374         dd if=$tmp of=$dom bs=265000 count=1
25375         cancel_lru_locks mdc
25376         cat /etc/hosts >> $tmp
25377         lctl set_param -n mdc.*.stats=clear
25378
25379         echo "Append to the same page"
25380         cat /etc/hosts >> $dom
25381         local num=$(get_mdc_stats $mdtidx ost_read)
25382         local ra=$(get_mdc_stats $mdtidx req_active)
25383         local rw=$(get_mdc_stats $mdtidx req_waittime)
25384
25385         [ -z $num ] || error "$num READ RPC occured"
25386         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25387         echo "... DONE"
25388
25389         # compare content
25390         cmp $tmp $dom || error "file miscompare"
25391
25392         cancel_lru_locks mdc
25393         lctl set_param -n mdc.*.stats=clear
25394
25395         echo "Open and read file"
25396         cat $dom > /dev/null
25397         local num=$(get_mdc_stats $mdtidx ost_read)
25398         local ra=$(get_mdc_stats $mdtidx req_active)
25399         local rw=$(get_mdc_stats $mdtidx req_waittime)
25400
25401         [ -z $num ] && num=0
25402         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25403         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25404         echo "... DONE"
25405
25406         # compare content
25407         cmp $tmp $dom || error "file miscompare"
25408
25409         return 0
25410 }
25411 run_test 271f "DoM: read on open (200K file and read tail)"
25412
25413 test_271g() {
25414         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25415                 skip "Skipping due to old client or server version"
25416
25417         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25418         # to get layout
25419         $CHECKSTAT -t file $DIR1/$tfile
25420
25421         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25422         MULTIOP_PID=$!
25423         sleep 1
25424         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25425         $LCTL set_param fail_loc=0x80000314
25426         rm $DIR1/$tfile || error "Unlink fails"
25427         RC=$?
25428         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25429         [ $RC -eq 0 ] || error "Failed write to stale object"
25430 }
25431 run_test 271g "Discard DoM data vs client flush race"
25432
25433 test_272a() {
25434         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25435                 skip "Need MDS version at least 2.11.50"
25436
25437         local dom=$DIR/$tdir/dom
25438         mkdir -p $DIR/$tdir
25439
25440         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25441         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25442                 error "failed to write data into $dom"
25443         local old_md5=$(md5sum $dom)
25444
25445         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25446                 error "failed to migrate to the same DoM component"
25447
25448         local new_md5=$(md5sum $dom)
25449
25450         [ "$old_md5" == "$new_md5" ] ||
25451                 error "md5sum differ: $old_md5, $new_md5"
25452
25453         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25454                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25455 }
25456 run_test 272a "DoM migration: new layout with the same DOM component"
25457
25458 test_272b() {
25459         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25460                 skip "Need MDS version at least 2.11.50"
25461
25462         local dom=$DIR/$tdir/dom
25463         mkdir -p $DIR/$tdir
25464         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25465         stack_trap "rm -rf $DIR/$tdir"
25466
25467         local mdtidx=$($LFS getstripe -m $dom)
25468         local mdtname=MDT$(printf %04x $mdtidx)
25469         local facet=mds$((mdtidx + 1))
25470
25471         local mdtfree1=$(do_facet $facet \
25472                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25473         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25474                 error "failed to write data into $dom"
25475         local old_md5=$(md5sum $dom)
25476         cancel_lru_locks mdc
25477         local mdtfree1=$(do_facet $facet \
25478                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25479
25480         $LFS migrate -c2 $dom ||
25481                 error "failed to migrate to the new composite layout"
25482         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25483                 error "MDT stripe was not removed"
25484         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25485                 error "$dir1 shouldn't have DATAVER EA"
25486
25487         cancel_lru_locks mdc
25488         local new_md5=$(md5sum $dom)
25489         [ "$old_md5" == "$new_md5" ] ||
25490                 error "$old_md5 != $new_md5"
25491
25492         # Skip free space checks with ZFS
25493         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25494                 local mdtfree2=$(do_facet $facet \
25495                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25496                 [ $mdtfree2 -gt $mdtfree1 ] ||
25497                         error "MDT space is not freed after migration"
25498         fi
25499         return 0
25500 }
25501 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25502
25503 test_272c() {
25504         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25505                 skip "Need MDS version at least 2.11.50"
25506
25507         local dom=$DIR/$tdir/$tfile
25508         mkdir -p $DIR/$tdir
25509         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25510         stack_trap "rm -rf $DIR/$tdir"
25511
25512         local mdtidx=$($LFS getstripe -m $dom)
25513         local mdtname=MDT$(printf %04x $mdtidx)
25514         local facet=mds$((mdtidx + 1))
25515
25516         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25517                 error "failed to write data into $dom"
25518         local old_md5=$(md5sum $dom)
25519         cancel_lru_locks mdc
25520         local mdtfree1=$(do_facet $facet \
25521                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25522
25523         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25524                 error "failed to migrate to the new composite layout"
25525         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25526                 error "MDT stripe was not removed"
25527
25528         cancel_lru_locks mdc
25529         local new_md5=$(md5sum $dom)
25530         [ "$old_md5" == "$new_md5" ] ||
25531                 error "$old_md5 != $new_md5"
25532
25533         # Skip free space checks with ZFS
25534         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25535                 local mdtfree2=$(do_facet $facet \
25536                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25537                 [ $mdtfree2 -gt $mdtfree1 ] ||
25538                         error "MDS space is not freed after migration"
25539         fi
25540         return 0
25541 }
25542 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25543
25544 test_272d() {
25545         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25546                 skip "Need MDS version at least 2.12.55"
25547
25548         local dom=$DIR/$tdir/$tfile
25549         mkdir -p $DIR/$tdir
25550         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25551
25552         local mdtidx=$($LFS getstripe -m $dom)
25553         local mdtname=MDT$(printf %04x $mdtidx)
25554         local facet=mds$((mdtidx + 1))
25555
25556         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25557                 error "failed to write data into $dom"
25558         local old_md5=$(md5sum $dom)
25559         cancel_lru_locks mdc
25560         local mdtfree1=$(do_facet $facet \
25561                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25562
25563         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25564                 error "failed mirroring to the new composite layout"
25565         $LFS mirror resync $dom ||
25566                 error "failed mirror resync"
25567         $LFS mirror split --mirror-id 1 -d $dom ||
25568                 error "failed mirror split"
25569
25570         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25571                 error "MDT stripe was not removed"
25572
25573         cancel_lru_locks mdc
25574         local new_md5=$(md5sum $dom)
25575         [ "$old_md5" == "$new_md5" ] ||
25576                 error "$old_md5 != $new_md5"
25577
25578         # Skip free space checks with ZFS
25579         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25580                 local mdtfree2=$(do_facet $facet \
25581                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25582                 [ $mdtfree2 -gt $mdtfree1 ] ||
25583                         error "MDS space is not freed after DOM mirror deletion"
25584         fi
25585         return 0
25586 }
25587 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25588
25589 test_272e() {
25590         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25591                 skip "Need MDS version at least 2.12.55"
25592
25593         local dom=$DIR/$tdir/$tfile
25594         mkdir -p $DIR/$tdir
25595         $LFS setstripe -c 2 $dom
25596
25597         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25598                 error "failed to write data into $dom"
25599         local old_md5=$(md5sum $dom)
25600         cancel_lru_locks
25601
25602         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25603                 error "failed mirroring to the DOM layout"
25604         $LFS mirror resync $dom ||
25605                 error "failed mirror resync"
25606         $LFS mirror split --mirror-id 1 -d $dom ||
25607                 error "failed mirror split"
25608
25609         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25610                 error "MDT stripe wasn't set"
25611
25612         cancel_lru_locks
25613         local new_md5=$(md5sum $dom)
25614         [ "$old_md5" == "$new_md5" ] ||
25615                 error "$old_md5 != $new_md5"
25616
25617         return 0
25618 }
25619 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25620
25621 test_272f() {
25622         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25623                 skip "Need MDS version at least 2.12.55"
25624
25625         local dom=$DIR/$tdir/$tfile
25626         mkdir -p $DIR/$tdir
25627         $LFS setstripe -c 2 $dom
25628
25629         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25630                 error "failed to write data into $dom"
25631         local old_md5=$(md5sum $dom)
25632         cancel_lru_locks
25633
25634         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25635                 error "failed migrating to the DOM file"
25636
25637         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25638                 error "MDT stripe wasn't set"
25639
25640         cancel_lru_locks
25641         local new_md5=$(md5sum $dom)
25642         [ "$old_md5" != "$new_md5" ] &&
25643                 error "$old_md5 != $new_md5"
25644
25645         return 0
25646 }
25647 run_test 272f "DoM migration: OST-striped file to DOM file"
25648
25649 test_273a() {
25650         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25651                 skip "Need MDS version at least 2.11.50"
25652
25653         # Layout swap cannot be done if either file has DOM component,
25654         # this will never be supported, migration should be used instead
25655
25656         local dom=$DIR/$tdir/$tfile
25657         mkdir -p $DIR/$tdir
25658
25659         $LFS setstripe -c2 ${dom}_plain
25660         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25661         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25662                 error "can swap layout with DoM component"
25663         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25664                 error "can swap layout with DoM component"
25665
25666         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25667         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25668                 error "can swap layout with DoM component"
25669         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25670                 error "can swap layout with DoM component"
25671         return 0
25672 }
25673 run_test 273a "DoM: layout swapping should fail with DOM"
25674
25675 test_273b() {
25676         mkdir -p $DIR/$tdir
25677         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25678
25679 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25680         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25681
25682         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25683 }
25684 run_test 273b "DoM: race writeback and object destroy"
25685
25686 test_273c() {
25687         mkdir -p $DIR/$tdir
25688         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25689
25690         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25691         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25692
25693         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25694 }
25695 run_test 273c "race writeback and object destroy"
25696
25697 test_275() {
25698         remote_ost_nodsh && skip "remote OST with nodsh"
25699         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25700                 skip "Need OST version >= 2.10.57"
25701
25702         local file=$DIR/$tfile
25703         local oss
25704
25705         oss=$(comma_list $(osts_nodes))
25706
25707         dd if=/dev/urandom of=$file bs=1M count=2 ||
25708                 error "failed to create a file"
25709         stack_trap "rm -f $file"
25710         cancel_lru_locks osc
25711
25712         #lock 1
25713         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25714                 error "failed to read a file"
25715
25716 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25717         $LCTL set_param fail_loc=0x8000031f
25718
25719         cancel_lru_locks osc &
25720         sleep 1
25721
25722 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25723         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25724         #IO takes another lock, but matches the PENDING one
25725         #and places it to the IO RPC
25726         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25727                 error "failed to read a file with PENDING lock"
25728 }
25729 run_test 275 "Read on a canceled duplicate lock"
25730
25731 test_276() {
25732         remote_ost_nodsh && skip "remote OST with nodsh"
25733         local pid
25734
25735         do_facet ost1 "(while true; do \
25736                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25737                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25738         pid=$!
25739
25740         for LOOP in $(seq 20); do
25741                 stop ost1
25742                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25743         done
25744         kill -9 $pid
25745         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25746                 rm $TMP/sanity_276_pid"
25747 }
25748 run_test 276 "Race between mount and obd_statfs"
25749
25750 test_277() {
25751         $LCTL set_param ldlm.namespaces.*.lru_size=0
25752         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25753         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25754                           awk '/^used_mb/ { print $2 }')
25755         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25757                 oflag=direct conv=notrunc
25758         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25759                     awk '/^used_mb/ { print $2 }')
25760         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25761 }
25762 run_test 277 "Direct IO shall drop page cache"
25763
25764 test_278() {
25765         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25766         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25767         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25768                 skip "needs the same host for mdt1 mdt2" && return
25769
25770         local pid1
25771         local pid2
25772
25773 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25774         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25775         stop mds2 &
25776         pid2=$!
25777
25778         stop mds1
25779
25780         echo "Starting MDTs"
25781         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25782         wait $pid2
25783 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25784 #will return NULL
25785         do_facet mds2 $LCTL set_param fail_loc=0
25786
25787         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25788         wait_recovery_complete mds2
25789 }
25790 run_test 278 "Race starting MDS between MDTs stop/start"
25791
25792 test_280() {
25793         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25794                 skip "Need MGS version at least 2.13.52"
25795         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25796         combined_mgs_mds || skip "needs combined MGS/MDT"
25797
25798         umount_client $MOUNT
25799 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25800         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25801
25802         mount_client $MOUNT &
25803         sleep 1
25804         stop mgs || error "stop mgs failed"
25805         #for a race mgs would crash
25806         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25807         # make sure we unmount client before remounting
25808         wait
25809         umount_client $MOUNT
25810         mount_client $MOUNT || error "mount client failed"
25811 }
25812 run_test 280 "Race between MGS umount and client llog processing"
25813
25814 cleanup_test_300() {
25815         trap 0
25816         umask $SAVE_UMASK
25817 }
25818
25819 test_striped_dir() {
25820         local mdt_index=$1
25821         local stripe_count=$2
25822         local overstriping=$3
25823         local stripe_index
25824         local getstripe_count
25825
25826         mkdir -p $DIR/$tdir
25827
25828         SAVE_UMASK=$(umask)
25829         trap cleanup_test_300 RETURN EXIT
25830
25831         if [ -z $overstriping ]; then
25832                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25833                                         -o 755 $DIR/$tdir/striped_dir ||
25834                         error "set striped dir error"
25835         else
25836                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25837                                         -o 755 $DIR/$tdir/striped_dir ||
25838                         error "set striped dir error"
25839         fi
25840
25841         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25842         [ "$mode" = "755" ] || error "expect 755 got $mode"
25843
25844         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25845                 error "getdirstripe failed"
25846         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25847         if [ "$getstripe_count" != "$stripe_count" ]; then
25848                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25849         fi
25850         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25851         if [ "$getstripe_count" != "$stripe_count" ]; then
25852                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25853         fi
25854
25855         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25856         if [ "$stripe_index" != "$mdt_index" ]; then
25857                 error "stripe_index is $stripe_index, expect $mdt_index"
25858         fi
25859
25860         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25861                 error "nlink error after create striped dir"
25862
25863         mkdir $DIR/$tdir/striped_dir/a
25864         mkdir $DIR/$tdir/striped_dir/b
25865
25866         stat $DIR/$tdir/striped_dir/a ||
25867                 error "create dir under striped dir failed"
25868         stat $DIR/$tdir/striped_dir/b ||
25869                 error "create dir under striped dir failed"
25870
25871         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25872                 error "nlink error after mkdir"
25873
25874         rmdir $DIR/$tdir/striped_dir/a
25875         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25876                 error "nlink error after rmdir"
25877
25878         rmdir $DIR/$tdir/striped_dir/b
25879         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25880                 error "nlink error after rmdir"
25881
25882         chattr +i $DIR/$tdir/striped_dir
25883         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25884                 error "immutable flags not working under striped dir!"
25885         chattr -i $DIR/$tdir/striped_dir
25886
25887         rmdir $DIR/$tdir/striped_dir ||
25888                 error "rmdir striped dir error"
25889
25890         cleanup_test_300
25891
25892         true
25893 }
25894
25895 test_300a() {
25896         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25897                 skip "skipped for lustre < 2.7.0"
25898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25899         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25900
25901         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25902         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25903 }
25904 run_test 300a "basic striped dir sanity test"
25905
25906 test_300b() {
25907         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25908                 skip "skipped for lustre < 2.7.0"
25909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25910         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25911
25912         local i
25913         local mtime1
25914         local mtime2
25915         local mtime3
25916
25917         test_mkdir $DIR/$tdir || error "mkdir fail"
25918         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25919                 error "set striped dir error"
25920         for i in {0..9}; do
25921                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25922                 sleep 1
25923                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25924                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25925                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25926                 sleep 1
25927                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25928                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25929                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25930         done
25931         true
25932 }
25933 run_test 300b "check ctime/mtime for striped dir"
25934
25935 test_300c() {
25936         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25937                 skip "skipped for lustre < 2.7.0"
25938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25939         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25940
25941         local file_count
25942
25943         mkdir_on_mdt0 $DIR/$tdir
25944         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25945                 error "set striped dir error"
25946
25947         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25948                 error "chown striped dir failed"
25949
25950         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25951                 error "create 5k files failed"
25952
25953         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25954
25955         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25956
25957         rm -rf $DIR/$tdir
25958 }
25959 run_test 300c "chown && check ls under striped directory"
25960
25961 test_300d() {
25962         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25963                 skip "skipped for lustre < 2.7.0"
25964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25965         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25966
25967         local stripe_count
25968         local file
25969
25970         mkdir -p $DIR/$tdir
25971         $LFS setstripe -c 2 $DIR/$tdir
25972
25973         #local striped directory
25974         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25975                 error "set striped dir error"
25976         #look at the directories for debug purposes
25977         ls -l $DIR/$tdir
25978         $LFS getdirstripe $DIR/$tdir
25979         ls -l $DIR/$tdir/striped_dir
25980         $LFS getdirstripe $DIR/$tdir/striped_dir
25981         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25982                 error "create 10 files failed"
25983
25984         #remote striped directory
25985         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25986                 error "set striped dir error"
25987         #look at the directories for debug purposes
25988         ls -l $DIR/$tdir
25989         $LFS getdirstripe $DIR/$tdir
25990         ls -l $DIR/$tdir/remote_striped_dir
25991         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25992         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25993                 error "create 10 files failed"
25994
25995         for file in $(find $DIR/$tdir); do
25996                 stripe_count=$($LFS getstripe -c $file)
25997                 [ $stripe_count -eq 2 ] ||
25998                         error "wrong stripe $stripe_count for $file"
25999         done
26000
26001         rm -rf $DIR/$tdir
26002 }
26003 run_test 300d "check default stripe under striped directory"
26004
26005 test_300e() {
26006         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26007                 skip "Need MDS version at least 2.7.55"
26008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26009         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26010
26011         local stripe_count
26012         local file
26013
26014         mkdir -p $DIR/$tdir
26015
26016         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26017                 error "set striped dir error"
26018
26019         touch $DIR/$tdir/striped_dir/a
26020         touch $DIR/$tdir/striped_dir/b
26021         touch $DIR/$tdir/striped_dir/c
26022
26023         mkdir $DIR/$tdir/striped_dir/dir_a
26024         mkdir $DIR/$tdir/striped_dir/dir_b
26025         mkdir $DIR/$tdir/striped_dir/dir_c
26026
26027         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26028                 error "set striped adir under striped dir error"
26029
26030         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26031                 error "set striped bdir under striped dir error"
26032
26033         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26034                 error "set striped cdir under striped dir error"
26035
26036         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26037                 error "rename dir under striped dir fails"
26038
26039         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26040                 error "rename dir under different stripes fails"
26041
26042         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26043                 error "rename file under striped dir should succeed"
26044
26045         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26046                 error "rename dir under striped dir should succeed"
26047
26048         rm -rf $DIR/$tdir
26049 }
26050 run_test 300e "check rename under striped directory"
26051
26052 test_300f() {
26053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26055         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26056                 skip "Need MDS version at least 2.7.55"
26057
26058         local stripe_count
26059         local file
26060
26061         rm -rf $DIR/$tdir
26062         mkdir -p $DIR/$tdir
26063
26064         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26065                 error "set striped dir error"
26066
26067         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26068                 error "set striped dir error"
26069
26070         touch $DIR/$tdir/striped_dir/a
26071         mkdir $DIR/$tdir/striped_dir/dir_a
26072         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26073                 error "create striped dir under striped dir fails"
26074
26075         touch $DIR/$tdir/striped_dir1/b
26076         mkdir $DIR/$tdir/striped_dir1/dir_b
26077         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26078                 error "create striped dir under striped dir fails"
26079
26080         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26081                 error "rename dir under different striped dir should fail"
26082
26083         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26084                 error "rename striped dir under diff striped dir should fail"
26085
26086         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26087                 error "rename file under diff striped dirs fails"
26088
26089         rm -rf $DIR/$tdir
26090 }
26091 run_test 300f "check rename cross striped directory"
26092
26093 test_300_check_default_striped_dir()
26094 {
26095         local dirname=$1
26096         local default_count=$2
26097         local default_index=$3
26098         local stripe_count
26099         local stripe_index
26100         local dir_stripe_index
26101         local dir
26102
26103         echo "checking $dirname $default_count $default_index"
26104         $LFS setdirstripe -D -c $default_count -i $default_index \
26105                                 -H all_char $DIR/$tdir/$dirname ||
26106                 error "set default stripe on striped dir error"
26107         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26108         [ $stripe_count -eq $default_count ] ||
26109                 error "expect $default_count get $stripe_count for $dirname"
26110
26111         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26112         [ $stripe_index -eq $default_index ] ||
26113                 error "expect $default_index get $stripe_index for $dirname"
26114
26115         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26116                                                 error "create dirs failed"
26117
26118         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26119         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26120         for dir in $(find $DIR/$tdir/$dirname/*); do
26121                 stripe_count=$($LFS getdirstripe -c $dir)
26122                 (( $stripe_count == $default_count )) ||
26123                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26124                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26125                 error "stripe count $default_count != $stripe_count for $dir"
26126
26127                 stripe_index=$($LFS getdirstripe -i $dir)
26128                 [ $default_index -eq -1 ] ||
26129                         [ $stripe_index -eq $default_index ] ||
26130                         error "$stripe_index != $default_index for $dir"
26131
26132                 #check default stripe
26133                 stripe_count=$($LFS getdirstripe -D -c $dir)
26134                 [ $stripe_count -eq $default_count ] ||
26135                 error "default count $default_count != $stripe_count for $dir"
26136
26137                 stripe_index=$($LFS getdirstripe -D -i $dir)
26138                 [ $stripe_index -eq $default_index ] ||
26139                 error "default index $default_index != $stripe_index for $dir"
26140         done
26141         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26142 }
26143
26144 test_300g() {
26145         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26146         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26147                 skip "Need MDS version at least 2.7.55"
26148
26149         local dir
26150         local stripe_count
26151         local stripe_index
26152
26153         mkdir_on_mdt0 $DIR/$tdir
26154         mkdir $DIR/$tdir/normal_dir
26155
26156         #Checking when client cache stripe index
26157         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26158         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26159                 error "create striped_dir failed"
26160
26161         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26162                 error "create dir0 fails"
26163         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26164         [ $stripe_index -eq 0 ] ||
26165                 error "dir0 expect index 0 got $stripe_index"
26166
26167         mkdir $DIR/$tdir/striped_dir/dir1 ||
26168                 error "create dir1 fails"
26169         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26170         [ $stripe_index -eq 1 ] ||
26171                 error "dir1 expect index 1 got $stripe_index"
26172
26173         #check default stripe count/stripe index
26174         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26175         test_300_check_default_striped_dir normal_dir 1 0
26176         test_300_check_default_striped_dir normal_dir -1 1
26177         test_300_check_default_striped_dir normal_dir 2 -1
26178
26179         #delete default stripe information
26180         echo "delete default stripeEA"
26181         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26182                 error "set default stripe on striped dir error"
26183
26184         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26185         for dir in $(find $DIR/$tdir/normal_dir/*); do
26186                 stripe_count=$($LFS getdirstripe -c $dir)
26187                 [ $stripe_count -eq 0 ] ||
26188                         error "expect 1 get $stripe_count for $dir"
26189         done
26190 }
26191 run_test 300g "check default striped directory for normal directory"
26192
26193 test_300h() {
26194         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26195         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26196                 skip "Need MDS version at least 2.7.55"
26197
26198         local dir
26199         local stripe_count
26200
26201         mkdir $DIR/$tdir
26202         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26203                 error "set striped dir error"
26204
26205         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26206         test_300_check_default_striped_dir striped_dir 1 0
26207         test_300_check_default_striped_dir striped_dir -1 1
26208         test_300_check_default_striped_dir striped_dir 2 -1
26209
26210         #delete default stripe information
26211         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26212                 error "set default stripe on striped dir error"
26213
26214         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26215         for dir in $(find $DIR/$tdir/striped_dir/*); do
26216                 stripe_count=$($LFS getdirstripe -c $dir)
26217                 [ $stripe_count -eq 0 ] ||
26218                         error "expect 1 get $stripe_count for $dir"
26219         done
26220 }
26221 run_test 300h "check default striped directory for striped directory"
26222
26223 test_300i() {
26224         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26225         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26226         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26227                 skip "Need MDS version at least 2.7.55"
26228
26229         local stripe_count
26230         local file
26231
26232         mkdir $DIR/$tdir
26233
26234         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26235                 error "set striped dir error"
26236
26237         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26238                 error "create files under striped dir failed"
26239
26240         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26241                 error "set striped hashdir error"
26242
26243         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26244                 error "create dir0 under hash dir failed"
26245         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26246                 error "create dir1 under hash dir failed"
26247         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26248                 error "create dir2 under hash dir failed"
26249
26250         # unfortunately, we need to umount to clear dir layout cache for now
26251         # once we fully implement dir layout, we can drop this
26252         umount_client $MOUNT || error "umount failed"
26253         mount_client $MOUNT || error "mount failed"
26254
26255         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26256         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26257         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26258
26259         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26260                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26261                         error "create crush2 dir $tdir/hashdir/d3 failed"
26262                 $LFS find -H crush2 $DIR/$tdir/hashdir
26263                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26264                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26265
26266                 # mkdir with an invalid hash type (hash=fail_val) from client
26267                 # should be replaced on MDS with a valid (default) hash type
26268                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26269                 $LCTL set_param fail_loc=0x1901 fail_val=99
26270                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26271
26272                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26273                 local expect=$(do_facet mds1 \
26274                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26275                 [[ $hash == $expect ]] ||
26276                         error "d99 hash '$hash' != expected hash '$expect'"
26277         fi
26278
26279         #set the stripe to be unknown hash type on read
26280         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26281         $LCTL set_param fail_loc=0x1901 fail_val=99
26282         for ((i = 0; i < 10; i++)); do
26283                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26284                         error "stat f-$i failed"
26285                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26286         done
26287
26288         touch $DIR/$tdir/striped_dir/f0 &&
26289                 error "create under striped dir with unknown hash should fail"
26290
26291         $LCTL set_param fail_loc=0
26292
26293         umount_client $MOUNT || error "umount failed"
26294         mount_client $MOUNT || error "mount failed"
26295
26296         return 0
26297 }
26298 run_test 300i "client handle unknown hash type striped directory"
26299
26300 test_300j() {
26301         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26303         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26304                 skip "Need MDS version at least 2.7.55"
26305
26306         local stripe_count
26307         local file
26308
26309         mkdir $DIR/$tdir
26310
26311         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26312         $LCTL set_param fail_loc=0x1702
26313         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26314                 error "set striped dir error"
26315
26316         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26317                 error "create files under striped dir failed"
26318
26319         $LCTL set_param fail_loc=0
26320
26321         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26322
26323         return 0
26324 }
26325 run_test 300j "test large update record"
26326
26327 test_300k() {
26328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26329         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26330         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26331                 skip "Need MDS version at least 2.7.55"
26332
26333         # this test needs a huge transaction
26334         local kb
26335         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26336              osd*.$FSNAME-MDT0000.kbytestotal")
26337         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26338
26339         local stripe_count
26340         local file
26341
26342         mkdir $DIR/$tdir
26343
26344         #define OBD_FAIL_LARGE_STRIPE   0x1703
26345         $LCTL set_param fail_loc=0x1703
26346         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26347                 error "set striped dir error"
26348         $LCTL set_param fail_loc=0
26349
26350         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26351                 error "getstripeddir fails"
26352         rm -rf $DIR/$tdir/striped_dir ||
26353                 error "unlink striped dir fails"
26354
26355         return 0
26356 }
26357 run_test 300k "test large striped directory"
26358
26359 test_300l() {
26360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26361         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26362         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26363                 skip "Need MDS version at least 2.7.55"
26364
26365         local stripe_index
26366
26367         test_mkdir -p $DIR/$tdir/striped_dir
26368         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26369                         error "chown $RUNAS_ID failed"
26370         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26371                 error "set default striped dir failed"
26372
26373         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26374         $LCTL set_param fail_loc=0x80000158
26375         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26376
26377         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26378         [ $stripe_index -eq 1 ] ||
26379                 error "expect 1 get $stripe_index for $dir"
26380 }
26381 run_test 300l "non-root user to create dir under striped dir with stale layout"
26382
26383 test_300m() {
26384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26385         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26386         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26387                 skip "Need MDS version at least 2.7.55"
26388
26389         mkdir -p $DIR/$tdir/striped_dir
26390         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26391                 error "set default stripes dir error"
26392
26393         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26394
26395         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26396         [ $stripe_count -eq 0 ] ||
26397                         error "expect 0 get $stripe_count for a"
26398
26399         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26400                 error "set default stripes dir error"
26401
26402         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26403
26404         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26405         [ $stripe_count -eq 0 ] ||
26406                         error "expect 0 get $stripe_count for b"
26407
26408         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26409                 error "set default stripes dir error"
26410
26411         mkdir $DIR/$tdir/striped_dir/c &&
26412                 error "default stripe_index is invalid, mkdir c should fails"
26413
26414         rm -rf $DIR/$tdir || error "rmdir fails"
26415 }
26416 run_test 300m "setstriped directory on single MDT FS"
26417
26418 cleanup_300n() {
26419         local list=$(comma_list $(mdts_nodes))
26420
26421         trap 0
26422         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26423 }
26424
26425 test_300n() {
26426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26427         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26428         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26429                 skip "Need MDS version at least 2.7.55"
26430         remote_mds_nodsh && skip "remote MDS with nodsh"
26431
26432         local stripe_index
26433         local list=$(comma_list $(mdts_nodes))
26434
26435         trap cleanup_300n RETURN EXIT
26436         mkdir -p $DIR/$tdir
26437         chmod 777 $DIR/$tdir
26438         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26439                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26440                 error "create striped dir succeeds with gid=0"
26441
26442         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26443         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26444                 error "create striped dir fails with gid=-1"
26445
26446         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26447         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26448                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26449                 error "set default striped dir succeeds with gid=0"
26450
26451
26452         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26453         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26454                 error "set default striped dir fails with gid=-1"
26455
26456
26457         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26458         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26459                                         error "create test_dir fails"
26460         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26461                                         error "create test_dir1 fails"
26462         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26463                                         error "create test_dir2 fails"
26464         cleanup_300n
26465 }
26466 run_test 300n "non-root user to create dir under striped dir with default EA"
26467
26468 test_300o() {
26469         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26470         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26471         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26472                 skip "Need MDS version at least 2.7.55"
26473
26474         local numfree1
26475         local numfree2
26476
26477         mkdir -p $DIR/$tdir
26478
26479         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26480         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26481         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26482                 skip "not enough free inodes $numfree1 $numfree2"
26483         fi
26484
26485         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26486         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26487         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26488                 skip "not enough free space $numfree1 $numfree2"
26489         fi
26490
26491         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26492                 error "setdirstripe fails"
26493
26494         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26495                 error "create dirs fails"
26496
26497         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26498         ls $DIR/$tdir/striped_dir > /dev/null ||
26499                 error "ls striped dir fails"
26500         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26501                 error "unlink big striped dir fails"
26502 }
26503 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26504
26505 test_300p() {
26506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26507         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26508         remote_mds_nodsh && skip "remote MDS with nodsh"
26509
26510         mkdir_on_mdt0 $DIR/$tdir
26511
26512         #define OBD_FAIL_OUT_ENOSPC     0x1704
26513         do_facet mds2 lctl set_param fail_loc=0x80001704
26514         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26515                  && error "create striped directory should fail"
26516
26517         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26518
26519         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26520         true
26521 }
26522 run_test 300p "create striped directory without space"
26523
26524 test_300q() {
26525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26526         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26527
26528         local fd=$(free_fd)
26529         local cmd="exec $fd<$tdir"
26530         cd $DIR
26531         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26532         eval $cmd
26533         cmd="exec $fd<&-"
26534         trap "eval $cmd" EXIT
26535         cd $tdir || error "cd $tdir fails"
26536         rmdir  ../$tdir || error "rmdir $tdir fails"
26537         mkdir local_dir && error "create dir succeeds"
26538         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26539         eval $cmd
26540         return 0
26541 }
26542 run_test 300q "create remote directory under orphan directory"
26543
26544 test_300r() {
26545         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26546                 skip "Need MDS version at least 2.7.55" && return
26547         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26548
26549         mkdir $DIR/$tdir
26550
26551         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26552                 error "set striped dir error"
26553
26554         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26555                 error "getstripeddir fails"
26556
26557         local stripe_count
26558         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26559                       awk '/lmv_stripe_count:/ { print $2 }')
26560
26561         [ $MDSCOUNT -ne $stripe_count ] &&
26562                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26563
26564         rm -rf $DIR/$tdir/striped_dir ||
26565                 error "unlink striped dir fails"
26566 }
26567 run_test 300r "test -1 striped directory"
26568
26569 test_300s_helper() {
26570         local count=$1
26571
26572         local stripe_dir=$DIR/$tdir/striped_dir.$count
26573
26574         $LFS mkdir -c $count $stripe_dir ||
26575                 error "lfs mkdir -c error"
26576
26577         $LFS getdirstripe $stripe_dir ||
26578                 error "lfs getdirstripe fails"
26579
26580         local stripe_count
26581         stripe_count=$($LFS getdirstripe $stripe_dir |
26582                       awk '/lmv_stripe_count:/ { print $2 }')
26583
26584         [ $count -ne $stripe_count ] &&
26585                 error_noexit "bad stripe count $stripe_count expected $count"
26586
26587         local dupe_stripes
26588         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26589                 awk '/0x/ {count[$1] += 1}; END {
26590                         for (idx in count) {
26591                                 if (count[idx]>1) {
26592                                         print "index " idx " count " count[idx]
26593                                 }
26594                         }
26595                 }')
26596
26597         if [[ -n "$dupe_stripes" ]] ; then
26598                 lfs getdirstripe $stripe_dir
26599                 error_noexit "Dupe MDT above: $dupe_stripes "
26600         fi
26601
26602         rm -rf $stripe_dir ||
26603                 error_noexit "unlink $stripe_dir fails"
26604 }
26605
26606 test_300s() {
26607         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26608                 skip "Need MDS version at least 2.7.55" && return
26609         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26610
26611         mkdir $DIR/$tdir
26612         for count in $(seq 2 $MDSCOUNT); do
26613                 test_300s_helper $count
26614         done
26615 }
26616 run_test 300s "test lfs mkdir -c without -i"
26617
26618 test_300t() {
26619         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26620                 skip "need MDS 2.14.55 or later"
26621         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26622
26623         local testdir="$DIR/$tdir/striped_dir"
26624         local dir1=$testdir/dir1
26625         local dir2=$testdir/dir2
26626
26627         mkdir -p $testdir
26628
26629         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26630                 error "failed to set default stripe count for $testdir"
26631
26632         mkdir $dir1
26633         local stripe_count=$($LFS getdirstripe -c $dir1)
26634
26635         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26636
26637         local max_count=$((MDSCOUNT - 1))
26638         local mdts=$(comma_list $(mdts_nodes))
26639
26640         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26641         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26642
26643         mkdir $dir2
26644         stripe_count=$($LFS getdirstripe -c $dir2)
26645
26646         (( $stripe_count == $max_count )) || error "wrong stripe count"
26647 }
26648 run_test 300t "test max_mdt_stripecount"
26649
26650 MDT_OVSTRP_VER="2.15.60"
26651 # 300u family tests MDT overstriping
26652 test_300ua() {
26653         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26654
26655         local setcount=$((MDSCOUNT * 2))
26656
26657         local expected_count
26658
26659         mkdir $DIR/$tdir
26660         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26661                 error "(0) failed basic overstriped dir creation test"
26662         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26663
26664         # This does a basic interop test - if the MDS does not support mdt
26665         # overstriping, we should get stripes == number of MDTs
26666         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26667                 expected_count=$MDSCOUNT
26668         else
26669                 expected_count=$setcount
26670         fi
26671         (( getstripe_count == expected_count )) ||
26672                 error "(1) incorrect stripe count for simple overstriped dir"
26673
26674         rm -rf $DIR/$tdir/${tdir}.0 ||
26675                 error "(2) unable to rm overstriped dir"
26676
26677         # Tests after this require overstriping support
26678         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26679                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26680
26681         test_striped_dir 0 $setcount true ||
26682                 error "(3)failed on overstriped dir"
26683         test_striped_dir 1 $setcount true ||
26684                 error "(4)failed on overstriped dir"
26685
26686         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26687
26688         test_striped_dir 0 $setcount true ||
26689                 error "(5)failed on overstriped dir"
26690 }
26691 run_test 300ua "basic overstriped dir sanity test"
26692
26693 test_300ub() {
26694         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26695                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26696         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26697
26698         mkdir $DIR/$tdir
26699
26700         echo "Testing invalid stripe count, failure expected"
26701         local setcount=$((MDSCOUNT * 2))
26702
26703         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26704         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26705
26706         (( getstripe_count <= MDSCOUNT )) ||
26707                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26708
26709         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26710         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26711         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26712
26713         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26714
26715         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26716         (( getstripe_count == maxcount )) ||
26717                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26718
26719         # Test specific striping with -i
26720         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26721
26722         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26723         (( getstripe_count == 4 )) ||
26724                 error "(2)stripe_count is $getstripe_count, expect 4"
26725
26726         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26727                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26728
26729         [[ -n "$nonzeroindices" ]] ||
26730                 error "(3) stripes indices not all 0: $nonzeroindices"
26731
26732         # Test specific striping with too many stripes on one MDT
26733         echo "Testing invalid striping, failure expected"
26734         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26735         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26736         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26737                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26738         echo "stripes on MDT0: $getstripe_count"
26739         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26740                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26741
26742         setcount=$((MDSCOUNT * 2))
26743         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26744                 error "(5) can't setdirstripe with manually set hash function"
26745
26746         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26747         (( getstripe_count == setcount )) ||
26748                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26749
26750         setcount=$((MDSCOUNT * 2))
26751         mkdir $DIR/${tdir}.5
26752         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26753                 error "(7) can't setdirstripe with manually set hash function"
26754         mkdir $DIR/${tdir}.5/${tdir}.6
26755
26756         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26757         (( getstripe_count == setcount )) ||
26758                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26759 }
26760 run_test 300ub "test MDT overstriping interface & limits"
26761
26762 test_300uc() {
26763         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26764                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26765         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26766
26767         mkdir $DIR/$tdir
26768
26769         local setcount=$((MDSCOUNT * 2))
26770
26771         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26772
26773         mkdir $DIR/$tdir/${tdir}.1
26774
26775         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26776
26777         (( getstripe_count == setcount )) ||
26778                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26779
26780         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26781
26782         local getstripe_count=$($LFS getdirstripe -c \
26783                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26784
26785         (( getstripe_count == setcount )) ||
26786                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26787 }
26788 run_test 300uc "test MDT overstriping as default & inheritance"
26789
26790 test_300ud() {
26791         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26792                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26793         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26794
26795         local mdts=$(comma_list $(mdts_nodes))
26796         local timeout=100
26797
26798         local restripe_status
26799         local delta
26800         local i
26801
26802         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26803
26804         # in case "crush" hash type is not set
26805         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26806
26807         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26808                            mdt.*MDT0000.enable_dir_restripe)
26809         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26810         stack_trap "do_nodes $mdts $LCTL set_param \
26811                     mdt.*.enable_dir_restripe=$restripe_status"
26812
26813         mkdir $DIR/$tdir
26814         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26815                 error "create files under remote dir failed $i"
26816         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26817                 error "create dirs under remote dir failed $i"
26818
26819         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26820
26821         (( setcount < 13 )) || setcount=12
26822         for i in $(seq 2 $setcount); do
26823                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26824                 $LFS setdirstripe -C $i $DIR/$tdir ||
26825                         error "split -C $i $tdir failed"
26826                 wait_update $HOSTNAME \
26827                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26828                         error "dir split not finished"
26829                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26830                         awk '/migrate/ {sum += $2} END { print sum }')
26831                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26832                 # delta is around total_files/stripe_count, deviation 3%
26833                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26834                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26835         done
26836 }
26837 run_test 300ud "dir split"
26838
26839 test_300ue() {
26840         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26841                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26842         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26843
26844         local mdts=$(comma_list $(mdts_nodes))
26845         local timeout=100
26846
26847         local restripe_status
26848         local delta
26849         local c
26850
26851         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26852
26853         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26854
26855         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26856                            mdt.*MDT0000.enable_dir_restripe)
26857         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26858         stack_trap "do_nodes $mdts $LCTL set_param \
26859                     mdt.*.enable_dir_restripe=$restripe_status"
26860
26861         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26862
26863         (( setcount < 13 )) || setcount=12
26864         test_mkdir -C $setcount -H crush $DIR/$tdir
26865         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26866                 error "create files under remote dir failed"
26867         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26868                 error "create dirs under remote dir failed"
26869
26870         for c in $(seq $((setcount - 1)) -1 1); do
26871                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26872                 $LFS setdirstripe -C $c $DIR/$tdir ||
26873                         error "split -C $c $tdir failed"
26874                 wait_update $HOSTNAME \
26875                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26876                         error "dir merge not finished"
26877                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26878                         awk '/migrate/ {sum += $2} END { print sum }')
26879                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26880                 # delta is around total_files/stripe_count, deviation 3%
26881                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26882                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26883         done
26884 }
26885 run_test 300ue "dir merge"
26886
26887 test_300uf() {
26888         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26889                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26890         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26891
26892         # maximum amount of local locks:
26893         # parent striped dir - 2 locks
26894         # new stripe in parent to migrate to - 1 lock
26895         # source and target - 2 locks
26896         # Total 5 locks for regular file
26897         #
26898         # NB: Overstriping should add several extra local locks
26899         # FIXME: Remove this once understood
26900         #lctl set_param *debug=-1 debug_mb=10000
26901         lctl clear
26902         lctl mark "touch/create"
26903         mkdir -p $DIR/$tdir
26904         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26905         local setcount=$((MDSCOUNT * 5))
26906
26907         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26908         touch $DIR/$tdir/dir1/eee
26909
26910         lctl mark "hardlinks"
26911         # create 4 hardlink for 4 more locks
26912         # Total: 9 locks > RS_MAX_LOCKS (8)
26913         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26914         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26915         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26916         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26917         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26918         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26919         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26920         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26921
26922         lctl mark "cancel lru"
26923         cancel_lru_locks mdc
26924
26925         lctl mark "migrate"
26926         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26927                 error "migrate dir fails"
26928
26929         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26930 }
26931 run_test 300uf "migrate with too many local locks"
26932
26933 test_300ug() {
26934         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26935                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26936         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26937
26938         mkdir -p $DIR/$tdir
26939         local migrate_dir=$DIR/$tdir/migrate_dir
26940         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26941         local setcount2=$((setcount - 2))
26942
26943         $LFS setdirstripe -c 2 $migrate_dir ||
26944                 error "(0) failed to create striped directory"
26945
26946         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26947                 error "(1)failed to migrate to overstriped directory"
26948         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26949
26950         (( getstripe_count == setcount )) ||
26951                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26952         touch $DIR/$tdir/migrate_dir/$tfile ||
26953                 error "(3)failed to create file in overstriped directory"
26954         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26955                 error "(4)failed to migrate overstriped directory"
26956         # Check stripe count after migration
26957         $LFS getdirstripe $migrate_dir
26958         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26959         (( getstripe_count == setcount2 )) ||
26960                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26961
26962         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
26963 }
26964 run_test 300ug "migrate overstriped dirs"
26965
26966 prepare_remote_file() {
26967         mkdir $DIR/$tdir/src_dir ||
26968                 error "create remote source failed"
26969
26970         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26971                  error "cp to remote source failed"
26972         touch $DIR/$tdir/src_dir/a
26973
26974         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26975                 error "create remote target dir failed"
26976
26977         touch $DIR/$tdir/tgt_dir/b
26978
26979         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26980                 error "rename dir cross MDT failed!"
26981
26982         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26983                 error "src_child still exists after rename"
26984
26985         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26986                 error "missing file(a) after rename"
26987
26988         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26989                 error "diff after rename"
26990 }
26991
26992 test_310a() {
26993         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26995
26996         local remote_file=$DIR/$tdir/tgt_dir/b
26997
26998         mkdir -p $DIR/$tdir
26999
27000         prepare_remote_file || error "prepare remote file failed"
27001
27002         #open-unlink file
27003         $OPENUNLINK $remote_file $remote_file ||
27004                 error "openunlink $remote_file failed"
27005         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27006 }
27007 run_test 310a "open unlink remote file"
27008
27009 test_310b() {
27010         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27012
27013         local remote_file=$DIR/$tdir/tgt_dir/b
27014
27015         mkdir -p $DIR/$tdir
27016
27017         prepare_remote_file || error "prepare remote file failed"
27018
27019         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27020         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27021         $CHECKSTAT -t file $remote_file || error "check file failed"
27022 }
27023 run_test 310b "unlink remote file with multiple links while open"
27024
27025 test_310c() {
27026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27027         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27028
27029         local remote_file=$DIR/$tdir/tgt_dir/b
27030
27031         mkdir -p $DIR/$tdir
27032
27033         prepare_remote_file || error "prepare remote file failed"
27034
27035         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27036         multiop_bg_pause $remote_file O_uc ||
27037                         error "mulitop failed for remote file"
27038         MULTIPID=$!
27039         $MULTIOP $DIR/$tfile Ouc
27040         kill -USR1 $MULTIPID
27041         wait $MULTIPID
27042 }
27043 run_test 310c "open-unlink remote file with multiple links"
27044
27045 #LU-4825
27046 test_311() {
27047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27048         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27049         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27050                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27051         remote_mds_nodsh && skip "remote MDS with nodsh"
27052
27053         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27054         local mdts=$(comma_list $(mdts_nodes))
27055
27056         mkdir -p $DIR/$tdir
27057         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27058         createmany -o $DIR/$tdir/$tfile. 1000
27059
27060         # statfs data is not real time, let's just calculate it
27061         old_iused=$((old_iused + 1000))
27062
27063         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27064                         osp.*OST0000*MDT0000.create_count")
27065         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27066                                 osp.*OST0000*MDT0000.max_create_count")
27067         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27068
27069         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27070         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27071         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27072
27073         unlinkmany $DIR/$tdir/$tfile. 1000
27074
27075         do_nodes $mdts "$LCTL set_param -n \
27076                         osp.*OST0000*.max_create_count=$max_count"
27077         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27078                 do_nodes $mdts "$LCTL set_param -n \
27079                                 osp.*OST0000*.create_count=$count"
27080         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27081                         grep "=0" && error "create_count is zero"
27082
27083         local new_iused
27084         for i in $(seq 120); do
27085                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27086                 # system may be too busy to destroy all objs in time, use
27087                 # a somewhat small value to not fail autotest
27088                 [ $((old_iused - new_iused)) -gt 400 ] && break
27089                 sleep 1
27090         done
27091
27092         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27093         [ $((old_iused - new_iused)) -gt 400 ] ||
27094                 error "objs not destroyed after unlink"
27095 }
27096 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27097
27098 zfs_get_objid()
27099 {
27100         local ost=$1
27101         local tf=$2
27102         local fid=($($LFS getstripe $tf | grep 0x))
27103         local seq=${fid[3]#0x}
27104         local objid=${fid[1]}
27105
27106         local vdevdir=$(dirname $(facet_vdevice $ost))
27107         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27108         local zfs_zapid=$(do_facet $ost $cmd |
27109                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27110                           awk '/Object/{getline; print $1}')
27111         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27112                           awk "/$objid = /"'{printf $3}')
27113
27114         echo $zfs_objid
27115 }
27116
27117 zfs_object_blksz() {
27118         local ost=$1
27119         local objid=$2
27120
27121         local vdevdir=$(dirname $(facet_vdevice $ost))
27122         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27123         local blksz=$(do_facet $ost $cmd $objid |
27124                       awk '/dblk/{getline; printf $4}')
27125
27126         case "${blksz: -1}" in
27127                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27128                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27129                 *) ;;
27130         esac
27131
27132         echo $blksz
27133 }
27134
27135 test_312() { # LU-4856
27136         remote_ost_nodsh && skip "remote OST with nodsh"
27137         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27138
27139         local max_blksz=$(do_facet ost1 \
27140                           $ZFS get -p recordsize $(facet_device ost1) |
27141                           awk '!/VALUE/{print $3}')
27142         local tf=$DIR/$tfile
27143
27144         $LFS setstripe -c1 $tf
27145         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27146
27147         # Get ZFS object id
27148         local zfs_objid=$(zfs_get_objid $facet $tf)
27149         # block size change by sequential overwrite
27150         local bs
27151
27152         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27153                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27154
27155                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27156                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27157         done
27158         rm -f $tf
27159
27160         $LFS setstripe -c1 $tf
27161         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27162
27163         # block size change by sequential append write
27164         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27165         zfs_objid=$(zfs_get_objid $facet $tf)
27166         local count
27167
27168         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27169                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27170                         oflag=sync conv=notrunc
27171
27172                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27173                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27174                         error "blksz error, actual $blksz, " \
27175                                 "expected: 2 * $count * $PAGE_SIZE"
27176         done
27177         rm -f $tf
27178
27179         # random write
27180         $LFS setstripe -c1 $tf
27181         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27182         zfs_objid=$(zfs_get_objid $facet $tf)
27183
27184         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27185         blksz=$(zfs_object_blksz $facet $zfs_objid)
27186         (( blksz == PAGE_SIZE )) ||
27187                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27188
27189         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27190         blksz=$(zfs_object_blksz $facet $zfs_objid)
27191         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27192
27193         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27194         blksz=$(zfs_object_blksz $facet $zfs_objid)
27195         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27196 }
27197 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27198
27199 test_313() {
27200         remote_ost_nodsh && skip "remote OST with nodsh"
27201
27202         local file=$DIR/$tfile
27203
27204         rm -f $file
27205         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27206
27207         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27208         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27209         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27210                 error "write should failed"
27211         do_facet ost1 "$LCTL set_param fail_loc=0"
27212         rm -f $file
27213 }
27214 run_test 313 "io should fail after last_rcvd update fail"
27215
27216 test_314() {
27217         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27218
27219         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27220         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27221         rm -f $DIR/$tfile
27222         wait_delete_completed
27223         do_facet ost1 "$LCTL set_param fail_loc=0"
27224 }
27225 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27226
27227 test_315() { # LU-618
27228         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27229
27230         local file=$DIR/$tfile
27231         rm -f $file
27232
27233         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27234                 error "multiop file write failed"
27235         $MULTIOP $file oO_RDONLY:r4063232_c &
27236         PID=$!
27237
27238         sleep 2
27239
27240         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27241         kill -USR1 $PID
27242
27243         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27244         rm -f $file
27245 }
27246 run_test 315 "read should be accounted"
27247
27248 test_316() {
27249         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27250         large_xattr_enabled || skip "ea_inode feature disabled"
27251
27252         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27253         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27254         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27255         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27256
27257         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27258 }
27259 run_test 316 "lfs migrate of file with large_xattr enabled"
27260
27261 test_317() {
27262         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27263                 skip "Need MDS version at least 2.11.53"
27264         if [ "$ost1_FSTYPE" == "zfs" ]; then
27265                 skip "LU-10370: no implementation for ZFS"
27266         fi
27267
27268         local trunc_sz
27269         local grant_blk_size
27270
27271         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27272                         awk '/grant_block_size:/ { print $2; exit; }')
27273         #
27274         # Create File of size 5M. Truncate it to below size's and verify
27275         # blocks count.
27276         #
27277         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27278                 error "Create file $DIR/$tfile failed"
27279         stack_trap "rm -f $DIR/$tfile" EXIT
27280
27281         for trunc_sz in 2097152 4097 4000 509 0; do
27282                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27283                         error "truncate $tfile to $trunc_sz failed"
27284                 local sz=$(stat --format=%s $DIR/$tfile)
27285                 local blk=$(stat --format=%b $DIR/$tfile)
27286                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27287                                      grant_blk_size) * 8))
27288
27289                 if [[ $blk -ne $trunc_blk ]]; then
27290                         $(which stat) $DIR/$tfile
27291                         error "Expected Block $trunc_blk got $blk for $tfile"
27292                 fi
27293
27294                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27295                         error "Expected Size $trunc_sz got $sz for $tfile"
27296         done
27297
27298         #
27299         # sparse file test
27300         # Create file with a hole and write actual 65536 bytes which aligned
27301         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27302         #
27303         local bs=65536
27304         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27305                 error "Create file : $DIR/$tfile"
27306
27307         #
27308         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27309         # blocks. The block count must drop to 8.
27310         #
27311         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27312                 ((bs - grant_blk_size) + 1)))
27313         $TRUNCATE $DIR/$tfile $trunc_sz ||
27314                 error "truncate $tfile to $trunc_sz failed"
27315
27316         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27317         sz=$(stat --format=%s $DIR/$tfile)
27318         blk=$(stat --format=%b $DIR/$tfile)
27319
27320         if [[ $blk -ne $trunc_bsz ]]; then
27321                 $(which stat) $DIR/$tfile
27322                 error "Expected Block $trunc_bsz got $blk for $tfile"
27323         fi
27324
27325         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27326                 error "Expected Size $trunc_sz got $sz for $tfile"
27327 }
27328 run_test 317 "Verify blocks get correctly update after truncate"
27329
27330 test_318() {
27331         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27332         local old_max_active=$($LCTL get_param -n \
27333                             ${llite_name}.max_read_ahead_async_active \
27334                             2>/dev/null)
27335
27336         $LCTL set_param llite.*.max_read_ahead_async_active=256
27337         local max_active=$($LCTL get_param -n \
27338                            ${llite_name}.max_read_ahead_async_active \
27339                            2>/dev/null)
27340         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27341
27342         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27343                 error "set max_read_ahead_async_active should succeed"
27344
27345         $LCTL set_param llite.*.max_read_ahead_async_active=512
27346         max_active=$($LCTL get_param -n \
27347                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27348         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27349
27350         # restore @max_active
27351         [ $old_max_active -ne 0 ] && $LCTL set_param \
27352                 llite.*.max_read_ahead_async_active=$old_max_active
27353
27354         local old_threshold=$($LCTL get_param -n \
27355                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27356         local max_per_file_mb=$($LCTL get_param -n \
27357                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27358
27359         local invalid=$(($max_per_file_mb + 1))
27360         $LCTL set_param \
27361                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27362                         && error "set $invalid should fail"
27363
27364         local valid=$(($invalid - 1))
27365         $LCTL set_param \
27366                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27367                         error "set $valid should succeed"
27368         local threshold=$($LCTL get_param -n \
27369                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27370         [ $threshold -eq $valid ] || error \
27371                 "expect threshold $valid got $threshold"
27372         $LCTL set_param \
27373                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27374 }
27375 run_test 318 "Verify async readahead tunables"
27376
27377 test_319() {
27378         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27379
27380         local before=$(date +%s)
27381         local evict
27382         local mdir=$DIR/$tdir
27383         local file=$mdir/xxx
27384
27385         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27386         touch $file
27387
27388 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27389         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27390         $LFS migrate -m1 $mdir &
27391
27392         sleep 1
27393         dd if=$file of=/dev/null
27394         wait
27395         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27396           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27397
27398         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27399 }
27400 run_test 319 "lost lease lock on migrate error"
27401
27402 test_350() {
27403         local mdts=$(comma_list $(mdts_nodes))
27404
27405         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27406         stack_trap "rm -r $DIR/$tdir"
27407
27408         #force 1/100 of replies to take "NID mismatch" codepath
27409         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27410         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27411
27412         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27413         stack_trap "killall -9 ls || killall -9 ls"
27414
27415         cp -a /etc $DIR/$tdir || error "cp failed"
27416 }
27417 run_test 350 "force NID mismatch path to be exercised"
27418
27419 test_360() {
27420         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27421                 skip "Need OST version at least 2.15.58.96"
27422         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27423
27424         check_set_fallocate_or_skip
27425         local param="osd-ldiskfs.delayed_unlink_mb"
27426         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27427
27428         do_facet ost1 "$LCTL set_param $param=1MiB"
27429         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27430
27431         mkdir $DIR/$tdir/
27432         do_facet ost1 $LCTL set_param debug=+inode
27433         do_facet ost1 $LCTL clear
27434         local files=100
27435
27436         for ((i = 0; i < $files; i++)); do
27437                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27438                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27439         done
27440         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27441
27442         for ((i = 0; i < $files; i++)); do
27443                 unlink $DIR/$tdir/$tfile.$i ||
27444                         error "unlink $DIR/$tdir/$tfile.$i failed"
27445         done
27446
27447         local count=0
27448         local loop
27449
27450         for (( loop = 0; loop < 30 && count < min; loop++)); do
27451                 sleep 1
27452                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27453                 echo "Count[$loop]: $count"
27454         done
27455         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27456 }
27457 run_test 360 "ldiskfs unlink in a separate thread"
27458
27459 test_398a() { # LU-4198
27460         local ost1_imp=$(get_osc_import_name client ost1)
27461         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27462                          cut -d'.' -f2)
27463
27464         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27465         stack_trap "rm -f $DIR/$tfile"
27466         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27467
27468         # request a new lock on client
27469         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27470
27471         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27472         local lock_count=$($LCTL get_param -n \
27473                            ldlm.namespaces.$imp_name.lru_size)
27474         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27475
27476         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27477
27478         # no lock cached, should use lockless DIO and not enqueue new lock
27479         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27480         lock_count=$($LCTL get_param -n \
27481                      ldlm.namespaces.$imp_name.lru_size)
27482         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27483
27484         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27485
27486         # no lock cached, should use locked DIO append
27487         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27488                 conv=notrunc || error "DIO append failed"
27489         lock_count=$($LCTL get_param -n \
27490                      ldlm.namespaces.$imp_name.lru_size)
27491         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27492 }
27493 run_test 398a "direct IO should cancel lock otherwise lockless"
27494
27495 test_398b() { # LU-4198
27496         local before=$(date +%s)
27497         local njobs=4
27498         local size=48
27499
27500         which fio || skip_env "no fio installed"
27501         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27502         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27503
27504         # Single page, multiple pages, stripe size, 4*stripe size
27505         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27506                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27507                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27508                         --numjobs=$njobs --fallocate=none \
27509                         --iodepth=16 --allow_file_create=0 \
27510                         --size=$((size/njobs))M \
27511                         --filename=$DIR/$tfile &
27512                 bg_pid=$!
27513
27514                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27515                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27516                         --numjobs=$njobs --fallocate=none \
27517                         --iodepth=16 --allow_file_create=0 \
27518                         --size=$((size/njobs))M \
27519                         --filename=$DIR/$tfile || true
27520                 wait $bg_pid
27521         done
27522
27523         evict=$(do_facet client $LCTL get_param \
27524                 osc.$FSNAME-OST*-osc-*/state |
27525             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27526
27527         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27528                 (do_facet client $LCTL get_param \
27529                         osc.$FSNAME-OST*-osc-*/state;
27530                     error "eviction happened: $evict before:$before")
27531
27532         rm -f $DIR/$tfile
27533 }
27534 run_test 398b "DIO and buffer IO race"
27535
27536 test_398c() { # LU-4198
27537         local ost1_imp=$(get_osc_import_name client ost1)
27538         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27539                          cut -d'.' -f2)
27540
27541         which fio || skip_env "no fio installed"
27542
27543         saved_debug=$($LCTL get_param -n debug)
27544         $LCTL set_param debug=0
27545
27546         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27547         ((size /= 1024)) # by megabytes
27548         ((size /= 2)) # write half of the OST at most
27549         [ $size -gt 40 ] && size=40 #reduce test time anyway
27550
27551         $LFS setstripe -c 1 $DIR/$tfile
27552
27553         # it seems like ldiskfs reserves more space than necessary if the
27554         # writing blocks are not mapped, so it extends the file firstly
27555         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27556         cancel_lru_locks osc
27557
27558         # clear and verify rpc_stats later
27559         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27560
27561         local njobs=4
27562         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27563         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27564                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27565                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27566                 --filename=$DIR/$tfile
27567         [ $? -eq 0 ] || error "fio write error"
27568
27569         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27570                 error "Locks were requested while doing AIO"
27571
27572         # get the percentage of 1-page I/O
27573         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27574                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27575                 awk '{print $7}')
27576         (( $pct <= 50 )) || {
27577                 $LCTL get_param osc.${imp_name}.rpc_stats
27578                 error "$pct% of I/O are 1-page"
27579         }
27580
27581         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27582         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27583                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27584                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27585                 --filename=$DIR/$tfile
27586         [ $? -eq 0 ] || error "fio mixed read write error"
27587
27588         echo "AIO with large block size ${size}M"
27589         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27590                 --numjobs=1 --fallocate=none --ioengine=libaio \
27591                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27592                 --filename=$DIR/$tfile
27593         [ $? -eq 0 ] || error "fio large block size failed"
27594
27595         rm -f $DIR/$tfile
27596         $LCTL set_param debug="$saved_debug"
27597 }
27598 run_test 398c "run fio to test AIO"
27599
27600 test_398d() { #  LU-13846
27601         which aiocp || skip_env "no aiocp installed"
27602         local aio_file=$DIR/$tfile.aio
27603
27604         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27605
27606         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27607         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27608         stack_trap "rm -f $DIR/$tfile $aio_file"
27609
27610         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27611
27612         # test memory unaligned aio
27613         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27614                 error "unaligned aio failed"
27615         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27616
27617         rm -f $DIR/$tfile $aio_file
27618 }
27619 run_test 398d "run aiocp to verify block size > stripe size"
27620
27621 test_398e() {
27622         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27623         touch $DIR/$tfile.new
27624         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27625 }
27626 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27627
27628 test_398f() { #  LU-14687
27629         which aiocp || skip_env "no aiocp installed"
27630         local aio_file=$DIR/$tfile.aio
27631
27632         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27633
27634         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27635         stack_trap "rm -f $DIR/$tfile $aio_file"
27636
27637         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27638         $LCTL set_param fail_loc=0x1418
27639         # make sure we don't crash and fail properly
27640         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27641                 error "aio with page allocation failure succeeded"
27642         $LCTL set_param fail_loc=0
27643         diff $DIR/$tfile $aio_file
27644         [[ $? != 0 ]] || error "no diff after failed aiocp"
27645 }
27646 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27647
27648 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27649 # stripe and i/o size must be > stripe size
27650 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27651 # single RPC in flight.  This test shows async DIO submission is working by
27652 # showing multiple RPCs in flight.
27653 test_398g() { #  LU-13798
27654         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27655
27656         # We need to do some i/o first to acquire enough grant to put our RPCs
27657         # in flight; otherwise a new connection may not have enough grant
27658         # available
27659         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27660                 error "parallel dio failed"
27661         stack_trap "rm -f $DIR/$tfile"
27662
27663         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27664         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27665         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27666         stack_trap "$LCTL set_param -n $pages_per_rpc"
27667
27668         # Recreate file so it's empty
27669         rm -f $DIR/$tfile
27670         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27671         #Pause rpc completion to guarantee we see multiple rpcs in flight
27672         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27673         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27674         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27675
27676         # Clear rpc stats
27677         $LCTL set_param osc.*.rpc_stats=c
27678
27679         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27680                 error "parallel dio failed"
27681         stack_trap "rm -f $DIR/$tfile"
27682
27683         $LCTL get_param osc.*-OST0000-*.rpc_stats
27684         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27685                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27686                 grep "8:" | awk '{print $8}')
27687         # We look at the "8 rpcs in flight" field, and verify A) it is present
27688         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27689         # as expected for an 8M DIO to a file with 1M stripes.
27690         # NB: There is occasionally a mystery extra write RPC to a different
27691         # file.  I can't identify why that's happening, so we set up a margin
27692         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27693         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27694
27695         # Verify turning off parallel dio works as expected
27696         # Clear rpc stats
27697         $LCTL set_param osc.*.rpc_stats=c
27698         $LCTL set_param llite.*.parallel_dio=0
27699         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27700
27701         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27702                 error "dio with parallel dio disabled failed"
27703
27704         # Ideally, we would see only one RPC in flight here, but there is an
27705         # unavoidable race between i/o completion and RPC in flight counting,
27706         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27707         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27708         # So instead we just verify it's always < 8.
27709         $LCTL get_param osc.*-OST0000-*.rpc_stats
27710         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27711                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27712                 grep '^$' -B1 | grep . | awk '{print $1}')
27713         [ $ret != "8:" ] ||
27714                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27715 }
27716 run_test 398g "verify parallel dio async RPC submission"
27717
27718 test_398h() { #  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         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27727                 error "parallel dio failed"
27728         diff $DIR/$tfile $dio_file
27729         [[ $? == 0 ]] || error "file diff after aiocp"
27730 }
27731 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27732
27733 test_398i() { #  LU-13798
27734         local dio_file=$DIR/$tfile.dio
27735
27736         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27737
27738         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27739         stack_trap "rm -f $DIR/$tfile $dio_file"
27740
27741         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27742         $LCTL set_param fail_loc=0x1418
27743         # make sure we don't crash and fail properly
27744         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27745                 error "parallel dio page allocation failure succeeded"
27746         diff $DIR/$tfile $dio_file
27747         [[ $? != 0 ]] || error "no diff after failed aiocp"
27748 }
27749 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27750
27751 test_398j() { #  LU-13798
27752         # Stripe size > RPC size but less than i/o size tests split across
27753         # stripes and RPCs for individual i/o op
27754         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27755
27756         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27757         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27758         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27759         stack_trap "$LCTL set_param -n $pages_per_rpc"
27760
27761         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27762                 error "parallel dio write failed"
27763         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27764
27765         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27766                 error "parallel dio read failed"
27767         diff $DIR/$tfile $DIR/$tfile.2
27768         [[ $? == 0 ]] || error "file diff after parallel dio read"
27769 }
27770 run_test 398j "test parallel dio where stripe size > rpc_size"
27771
27772 test_398k() { #  LU-13798
27773         wait_delete_completed
27774         wait_mds_ost_sync
27775
27776         # 4 stripe file; we will cause out of space on OST0
27777         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27778
27779         # Fill OST0 (if it's not too large)
27780         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27781                    head -n1)
27782         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27783                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27784         fi
27785         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27786         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27787                 error "dd should fill OST0"
27788         stack_trap "rm -f $DIR/$tfile.1"
27789
27790         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27791         err=$?
27792
27793         ls -la $DIR/$tfile
27794         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27795                 error "file is not 0 bytes in size"
27796
27797         # dd above should not succeed, but don't error until here so we can
27798         # get debug info above
27799         [[ $err != 0 ]] ||
27800                 error "parallel dio write with enospc succeeded"
27801         stack_trap "rm -f $DIR/$tfile"
27802 }
27803 run_test 398k "test enospc on first stripe"
27804
27805 test_398l() { #  LU-13798
27806         wait_delete_completed
27807         wait_mds_ost_sync
27808
27809         # 4 stripe file; we will cause out of space on OST0
27810         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27811         # happens on the second i/o chunk we issue
27812         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27813
27814         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27815         stack_trap "rm -f $DIR/$tfile"
27816
27817         # Fill OST0 (if it's not too large)
27818         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27819                    head -n1)
27820         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27821                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27822         fi
27823         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27824         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27825                 error "dd should fill OST0"
27826         stack_trap "rm -f $DIR/$tfile.1"
27827
27828         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27829         err=$?
27830         stack_trap "rm -f $DIR/$tfile.2"
27831
27832         # Check that short write completed as expected
27833         ls -la $DIR/$tfile.2
27834         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27835                 error "file is not 1M in size"
27836
27837         # dd above should not succeed, but don't error until here so we can
27838         # get debug info above
27839         [[ $err != 0 ]] ||
27840                 error "parallel dio write with enospc succeeded"
27841
27842         # Truncate source file to same length as output file and diff them
27843         $TRUNCATE $DIR/$tfile 1048576
27844         diff $DIR/$tfile $DIR/$tfile.2
27845         [[ $? == 0 ]] || error "data incorrect after short write"
27846 }
27847 run_test 398l "test enospc on intermediate stripe/RPC"
27848
27849 test_398m() { #  LU-13798
27850         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27851
27852         # Set up failure on OST0, the first stripe:
27853         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27854         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27855         # OST0 is on ost1, OST1 is on ost2.
27856         # So this fail_val specifies OST0
27857         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27858         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27859
27860         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27861                 error "parallel dio write with failure on first stripe succeeded"
27862         stack_trap "rm -f $DIR/$tfile"
27863         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27864
27865         # Place data in file for read
27866         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27867                 error "parallel dio write failed"
27868
27869         # Fail read on OST0, first stripe
27870         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27871         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27872         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27873                 error "parallel dio read with error on first stripe succeeded"
27874         rm -f $DIR/$tfile.2
27875         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27876
27877         # Switch to testing on OST1, second stripe
27878         # Clear file contents, maintain striping
27879         echo > $DIR/$tfile
27880         # Set up failure on OST1, second stripe:
27881         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27882         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27883
27884         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27885                 error "parallel dio write with failure on second stripe succeeded"
27886         stack_trap "rm -f $DIR/$tfile"
27887         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27888
27889         # Place data in file for read
27890         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27891                 error "parallel dio write failed"
27892
27893         # Fail read on OST1, second stripe
27894         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27895         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27896         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27897                 error "parallel dio read with error on second stripe succeeded"
27898         rm -f $DIR/$tfile.2
27899         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27900 }
27901 run_test 398m "test RPC failures with parallel dio"
27902
27903 # Parallel submission of DIO should not cause problems for append, but it's
27904 # important to verify.
27905 test_398n() { #  LU-13798
27906         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27907
27908         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27909                 error "dd to create source file failed"
27910         stack_trap "rm -f $DIR/$tfile"
27911
27912         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27913                 error "parallel dio write with failure on second stripe succeeded"
27914         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27915         diff $DIR/$tfile $DIR/$tfile.1
27916         [[ $? == 0 ]] || error "data incorrect after append"
27917
27918 }
27919 run_test 398n "test append with parallel DIO"
27920
27921 test_398o() {
27922         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27923 }
27924 run_test 398o "right kms with DIO"
27925
27926 test_398p()
27927 {
27928         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27929         which aiocp || skip_env "no aiocp installed"
27930
27931         local stripe_size=$((1024 * 1024)) #1 MiB
27932         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27933         local file_size=$((25 * stripe_size))
27934
27935         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27936         stack_trap "rm -f $DIR/$tfile*"
27937         # Just a bit bigger than the largest size in the test set below
27938         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27939                 error "buffered i/o to create file failed"
27940
27941         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27942                 $((stripe_size * 4)); do
27943
27944                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27945
27946                 echo "bs: $bs, file_size $file_size"
27947                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27948                         $DIR/$tfile.1 $DIR/$tfile.2 &
27949                 pid_dio1=$!
27950                 # Buffered I/O with similar but not the same block size
27951                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27952                         conv=notrunc &
27953                 pid_bio2=$!
27954                 wait $pid_dio1
27955                 rc1=$?
27956                 wait $pid_bio2
27957                 rc2=$?
27958                 if (( rc1 != 0 )); then
27959                         error "aio copy 1 w/bsize $bs failed: $rc1"
27960                 fi
27961                 if (( rc2 != 0 )); then
27962                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27963                 fi
27964
27965                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27966                         error "size incorrect"
27967                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27968                         error "files differ, bsize $bs"
27969                 rm -f $DIR/$tfile.2
27970         done
27971 }
27972 run_test 398p "race aio with buffered i/o"
27973
27974 test_398q()
27975 {
27976         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27977
27978         local stripe_size=$((1024 * 1024)) #1 MiB
27979         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27980         local file_size=$((25 * stripe_size))
27981
27982         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27983         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27984
27985         # Just a bit bigger than the largest size in the test set below
27986         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27987                 error "buffered i/o to create file failed"
27988
27989         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27990                 $((stripe_size * 4)); do
27991
27992                 echo "bs: $bs, file_size $file_size"
27993                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27994                         conv=notrunc oflag=direct iflag=direct &
27995                 pid_dio1=$!
27996                 # Buffered I/O with similar but not the same block size
27997                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27998                         conv=notrunc &
27999                 pid_bio2=$!
28000                 wait $pid_dio1
28001                 rc1=$?
28002                 wait $pid_bio2
28003                 rc2=$?
28004                 if (( rc1 != 0 )); then
28005                         error "dio copy 1 w/bsize $bs failed: $rc1"
28006                 fi
28007                 if (( rc2 != 0 )); then
28008                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28009                 fi
28010
28011                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28012                         error "size incorrect"
28013                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28014                         error "files differ, bsize $bs"
28015         done
28016
28017         rm -f $DIR/$tfile*
28018 }
28019 run_test 398q "race dio with buffered i/o"
28020
28021 test_398r() {
28022         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28023         echo "hello, world" > $DIR/$tfile
28024
28025         cancel_lru_locks osc
28026
28027 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28028         do_facet ost1 $LCTL set_param fail_loc=0x20f
28029         cat $DIR/$tfile > /dev/null && error "cat should fail"
28030         return 0
28031 }
28032 run_test 398r "i/o error on file read"
28033
28034 test_398s() {
28035         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28036                 skip "remote OST"
28037
28038         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28039                 error "mirror create failed"
28040
28041         echo "hello, world" > $DIR/$tfile
28042         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28043
28044         cancel_lru_locks osc
28045
28046 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28047         do_facet ost1 $LCTL set_param fail_loc=0x20f
28048         cat $DIR/$tfile > /dev/null && error "cat should fail"
28049         return 0
28050 }
28051 run_test 398s "i/o error on mirror file read"
28052
28053 test_fake_rw() {
28054         local read_write=$1
28055         if [ "$read_write" = "write" ]; then
28056                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28057         elif [ "$read_write" = "read" ]; then
28058                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28059         else
28060                 error "argument error"
28061         fi
28062
28063         # turn off debug for performance testing
28064         local saved_debug=$($LCTL get_param -n debug)
28065         $LCTL set_param debug=0
28066
28067         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28068
28069         # get ost1 size - $FSNAME-OST0000
28070         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28071         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28072         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28073
28074         if [ "$read_write" = "read" ]; then
28075                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28076         fi
28077
28078         local start_time=$(date +%s.%N)
28079         $dd_cmd bs=1M count=$blocks oflag=sync ||
28080                 error "real dd $read_write error"
28081         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28082
28083         if [ "$read_write" = "write" ]; then
28084                 rm -f $DIR/$tfile
28085         fi
28086
28087         # define OBD_FAIL_OST_FAKE_RW           0x238
28088         do_facet ost1 $LCTL set_param fail_loc=0x238
28089
28090         local start_time=$(date +%s.%N)
28091         $dd_cmd bs=1M count=$blocks oflag=sync ||
28092                 error "fake dd $read_write error"
28093         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28094
28095         if [ "$read_write" = "write" ]; then
28096                 # verify file size
28097                 cancel_lru_locks osc
28098                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28099                         error "$tfile size not $blocks MB"
28100         fi
28101         do_facet ost1 $LCTL set_param fail_loc=0
28102
28103         echo "fake $read_write $duration_fake vs. normal $read_write" \
28104                 "$duration in seconds"
28105         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28106                 error_not_in_vm "fake write is slower"
28107
28108         $LCTL set_param -n debug="$saved_debug"
28109         rm -f $DIR/$tfile
28110 }
28111 test_399a() { # LU-7655 for OST fake write
28112         remote_ost_nodsh && skip "remote OST with nodsh"
28113
28114         test_fake_rw write
28115 }
28116 run_test 399a "fake write should not be slower than normal write"
28117
28118 test_399b() { # LU-8726 for OST fake read
28119         remote_ost_nodsh && skip "remote OST with nodsh"
28120         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28121                 skip_env "ldiskfs only test"
28122         fi
28123
28124         test_fake_rw read
28125 }
28126 run_test 399b "fake read should not be slower than normal read"
28127
28128 test_400a() { # LU-1606, was conf-sanity test_74
28129         if ! which $CC > /dev/null 2>&1; then
28130                 skip_env "$CC is not installed"
28131         fi
28132
28133         local extra_flags=''
28134         local out=$TMP/$tfile
28135         local prefix=/usr/include/lustre
28136         local prog
28137
28138         # Oleg removes .c files in his test rig so test if any c files exist
28139         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28140                 skip_env "Needed .c test files are missing"
28141
28142         if ! [[ -d $prefix ]]; then
28143                 # Assume we're running in tree and fixup the include path.
28144                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28145                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28146                 extra_flags+=" -L$LUSTRE/utils/.libs"
28147         fi
28148
28149         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28150                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28151                         error "client api broken"
28152         done
28153         rm -f $out
28154 }
28155 run_test 400a "Lustre client api program can compile and link"
28156
28157 test_400b() { # LU-1606, LU-5011
28158         local header
28159         local out=$TMP/$tfile
28160         local prefix=/usr/include/linux/lustre
28161
28162         # We use a hard coded prefix so that this test will not fail
28163         # when run in tree. There are headers in lustre/include/lustre/
28164         # that are not packaged (like lustre_idl.h) and have more
28165         # complicated include dependencies (like config.h and lnet/types.h).
28166         # Since this test about correct packaging we just skip them when
28167         # they don't exist (see below) rather than try to fixup cppflags.
28168
28169         if ! which $CC > /dev/null 2>&1; then
28170                 skip_env "$CC is not installed"
28171         fi
28172
28173         for header in $prefix/*.h; do
28174                 if ! [[ -f "$header" ]]; then
28175                         continue
28176                 fi
28177
28178                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28179                         continue # lustre_ioctl.h is internal header
28180                 fi
28181
28182                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28183                         error "cannot compile '$header'"
28184         done
28185         rm -f $out
28186 }
28187 run_test 400b "packaged headers can be compiled"
28188
28189 test_401a() { #LU-7437
28190         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28191         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28192
28193         #count the number of parameters by "list_param -R"
28194         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28195         #count the number of parameters by listing proc files
28196         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28197         echo "proc_dirs='$proc_dirs'"
28198         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28199         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28200                       sort -u | wc -l)
28201
28202         [ $params -eq $procs ] ||
28203                 error "found $params parameters vs. $procs proc files"
28204
28205         # test the list_param -D option only returns directories
28206         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28207         #count the number of parameters by listing proc directories
28208         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28209                 sort -u | wc -l)
28210
28211         [ $params -eq $procs ] ||
28212                 error "found $params parameters vs. $procs proc files"
28213 }
28214 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28215
28216 test_401b() {
28217         # jobid_var may not allow arbitrary values, so use jobid_name
28218         # if available
28219         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28220                 local testname=jobid_name tmp='testing%p'
28221         else
28222                 local testname=jobid_var tmp=testing
28223         fi
28224
28225         local save=$($LCTL get_param -n $testname)
28226
28227         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28228                 error "no error returned when setting bad parameters"
28229
28230         local jobid_new=$($LCTL get_param -n foe $testname baz)
28231         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28232
28233         $LCTL set_param -n fog=bam $testname=$save bat=fog
28234         local jobid_old=$($LCTL get_param -n foe $testname bag)
28235         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28236 }
28237 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28238
28239 test_401c() {
28240         # jobid_var may not allow arbitrary values, so use jobid_name
28241         # if available
28242         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28243                 local testname=jobid_name
28244         else
28245                 local testname=jobid_var
28246         fi
28247
28248         local jobid_var_old=$($LCTL get_param -n $testname)
28249         local jobid_var_new
28250
28251         $LCTL set_param $testname= &&
28252                 error "no error returned for 'set_param a='"
28253
28254         jobid_var_new=$($LCTL get_param -n $testname)
28255         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28256                 error "$testname was changed by setting without value"
28257
28258         $LCTL set_param $testname &&
28259                 error "no error returned for 'set_param a'"
28260
28261         jobid_var_new=$($LCTL get_param -n $testname)
28262         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28263                 error "$testname was changed by setting without value"
28264 }
28265 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28266
28267 test_401d() {
28268         # jobid_var may not allow arbitrary values, so use jobid_name
28269         # if available
28270         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28271                 local testname=jobid_name new_value='foo=bar%p'
28272         else
28273                 local testname=jobid_var new_valuie=foo=bar
28274         fi
28275
28276         local jobid_var_old=$($LCTL get_param -n $testname)
28277         local jobid_var_new
28278
28279         $LCTL set_param $testname=$new_value ||
28280                 error "'set_param a=b' did not accept a value containing '='"
28281
28282         jobid_var_new=$($LCTL get_param -n $testname)
28283         [[ "$jobid_var_new" == "$new_value" ]] ||
28284                 error "'set_param a=b' failed on a value containing '='"
28285
28286         # Reset the $testname to test the other format
28287         $LCTL set_param $testname=$jobid_var_old
28288         jobid_var_new=$($LCTL get_param -n $testname)
28289         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28290                 error "failed to reset $testname"
28291
28292         $LCTL set_param $testname $new_value ||
28293                 error "'set_param a b' did not accept a value containing '='"
28294
28295         jobid_var_new=$($LCTL get_param -n $testname)
28296         [[ "$jobid_var_new" == "$new_value" ]] ||
28297                 error "'set_param a b' failed on a value containing '='"
28298
28299         $LCTL set_param $testname $jobid_var_old
28300         jobid_var_new=$($LCTL get_param -n $testname)
28301         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28302                 error "failed to reset $testname"
28303 }
28304 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28305
28306 test_401e() { # LU-14779
28307         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28308                 error "lctl list_param MGC* failed"
28309         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28310         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28311                 error "lctl get_param lru_size failed"
28312 }
28313 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28314
28315 test_402() {
28316         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28317         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28318                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28319         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28320                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28321                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28322         remote_mds_nodsh && skip "remote MDS with nodsh"
28323
28324         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28325 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28326         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28327         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28328                 echo "Touch failed - OK"
28329 }
28330 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28331
28332 test_403() {
28333         local file1=$DIR/$tfile.1
28334         local file2=$DIR/$tfile.2
28335         local tfile=$TMP/$tfile
28336
28337         rm -f $file1 $file2 $tfile
28338
28339         touch $file1
28340         ln $file1 $file2
28341
28342         # 30 sec OBD_TIMEOUT in ll_getattr()
28343         # right before populating st_nlink
28344         $LCTL set_param fail_loc=0x80001409
28345         stat -c %h $file1 > $tfile &
28346
28347         # create an alias, drop all locks and reclaim the dentry
28348         < $file2
28349         cancel_lru_locks mdc
28350         cancel_lru_locks osc
28351         sysctl -w vm.drop_caches=2
28352
28353         wait
28354
28355         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28356
28357         rm -f $tfile $file1 $file2
28358 }
28359 run_test 403 "i_nlink should not drop to zero due to aliasing"
28360
28361 test_404() { # LU-6601
28362         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28363                 skip "Need server version newer than 2.8.52"
28364         remote_mds_nodsh && skip "remote MDS with nodsh"
28365
28366         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28367                 awk '/osp .*-osc-MDT/ { print $4}')
28368
28369         local osp
28370         for osp in $mosps; do
28371                 echo "Deactivate: " $osp
28372                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28373                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28374                         awk -vp=$osp '$4 == p { print $2 }')
28375                 [ $stat = IN ] || {
28376                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28377                         error "deactivate error"
28378                 }
28379                 echo "Activate: " $osp
28380                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28381                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28382                         awk -vp=$osp '$4 == p { print $2 }')
28383                 [ $stat = UP ] || {
28384                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28385                         error "activate error"
28386                 }
28387         done
28388 }
28389 run_test 404 "validate manual {de}activated works properly for OSPs"
28390
28391 test_405() {
28392         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28393         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28394                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28395                         skip "Layout swap lock is not supported"
28396
28397         check_swap_layouts_support
28398         check_swap_layout_no_dom $DIR
28399
28400         test_mkdir $DIR/$tdir
28401         swap_lock_test -d $DIR/$tdir ||
28402                 error "One layout swap locked test failed"
28403 }
28404 run_test 405 "Various layout swap lock tests"
28405
28406 test_406() {
28407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28408         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28409         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28411         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28412                 skip "Need MDS version at least 2.8.50"
28413
28414         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28415         local test_pool=$TESTNAME
28416
28417         pool_add $test_pool || error "pool_add failed"
28418         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28419                 error "pool_add_targets failed"
28420
28421         save_layout_restore_at_exit $MOUNT
28422
28423         # parent set default stripe count only, child will stripe from both
28424         # parent and fs default
28425         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28426                 error "setstripe $MOUNT failed"
28427         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28428         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28429         for i in $(seq 10); do
28430                 local f=$DIR/$tdir/$tfile.$i
28431                 touch $f || error "touch failed"
28432                 local count=$($LFS getstripe -c $f)
28433                 [ $count -eq $OSTCOUNT ] ||
28434                         error "$f stripe count $count != $OSTCOUNT"
28435                 local offset=$($LFS getstripe -i $f)
28436                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28437                 local size=$($LFS getstripe -S $f)
28438                 [ $size -eq $((def_stripe_size * 2)) ] ||
28439                         error "$f stripe size $size != $((def_stripe_size * 2))"
28440                 local pool=$($LFS getstripe -p $f)
28441                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28442         done
28443
28444         # change fs default striping, delete parent default striping, now child
28445         # will stripe from new fs default striping only
28446         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28447                 error "change $MOUNT default stripe failed"
28448         $LFS setstripe -c 0 $DIR/$tdir ||
28449                 error "delete $tdir default stripe failed"
28450         for i in $(seq 11 20); do
28451                 local f=$DIR/$tdir/$tfile.$i
28452                 touch $f || error "touch $f failed"
28453                 local count=$($LFS getstripe -c $f)
28454                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28455                 local offset=$($LFS getstripe -i $f)
28456                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28457                 local size=$($LFS getstripe -S $f)
28458                 [ $size -eq $def_stripe_size ] ||
28459                         error "$f stripe size $size != $def_stripe_size"
28460                 local pool=$($LFS getstripe -p $f)
28461                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28462         done
28463
28464         unlinkmany $DIR/$tdir/$tfile. 1 20
28465
28466         local f=$DIR/$tdir/$tfile
28467         pool_remove_all_targets $test_pool $f
28468         pool_remove $test_pool $f
28469 }
28470 run_test 406 "DNE support fs default striping"
28471
28472 test_407() {
28473         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28474         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28475                 skip "Need MDS version at least 2.8.55"
28476         remote_mds_nodsh && skip "remote MDS with nodsh"
28477
28478         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28479                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28480         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28481                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28482         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28483
28484         #define OBD_FAIL_DT_TXN_STOP    0x2019
28485         for idx in $(seq $MDSCOUNT); do
28486                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28487         done
28488         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28489         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28490                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28491         true
28492 }
28493 run_test 407 "transaction fail should cause operation fail"
28494
28495 test_408() {
28496         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28497
28498         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28499         lctl set_param fail_loc=0x8000040a
28500         # let ll_prepare_partial_page() fail
28501         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28502
28503         rm -f $DIR/$tfile
28504
28505         # create at least 100 unused inodes so that
28506         # shrink_icache_memory(0) should not return 0
28507         touch $DIR/$tfile-{0..100}
28508         rm -f $DIR/$tfile-{0..100}
28509         sync
28510
28511         echo 2 > /proc/sys/vm/drop_caches
28512 }
28513 run_test 408 "drop_caches should not hang due to page leaks"
28514
28515 test_409()
28516 {
28517         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28518
28519         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28520         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28521         touch $DIR/$tdir/guard || error "(2) Fail to create"
28522
28523         local PREFIX=$(str_repeat 'A' 128)
28524         echo "Create 1K hard links start at $(date)"
28525         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28526                 error "(3) Fail to hard link"
28527
28528         echo "Links count should be right although linkEA overflow"
28529         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28530         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28531         [ $linkcount -eq 1001 ] ||
28532                 error "(5) Unexpected hard links count: $linkcount"
28533
28534         echo "List all links start at $(date)"
28535         ls -l $DIR/$tdir/foo > /dev/null ||
28536                 error "(6) Fail to list $DIR/$tdir/foo"
28537
28538         echo "Unlink hard links start at $(date)"
28539         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28540                 error "(7) Fail to unlink"
28541         echo "Unlink hard links finished at $(date)"
28542 }
28543 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28544
28545 test_410()
28546 {
28547         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28548                 skip "Need client version at least 2.9.59"
28549
28550         # Create a file, and stat it from the kernel
28551         local testfile=$DIR/$tfile
28552         touch $testfile
28553
28554         local run_id=$RANDOM
28555         local my_ino=$(stat --format "%i" $testfile)
28556
28557         # Try to insert the module.
28558         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28559                 error "load_module failed"
28560
28561         # Anything but success is a test failure
28562         dmesg | grep -q \
28563             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28564             error "no inode match"
28565
28566         # Remove the test module
28567         rmmod -v kinode ||
28568                 error "rmmod failed (may trigger a failure in a later test)"
28569 }
28570 run_test 410 "Test inode number returned from kernel thread"
28571
28572 cleanup_test411_cgroup() {
28573         trap 0
28574         cat $1/memory.stat
28575         rmdir "$1"
28576 }
28577
28578 test_411a() {
28579         local cg_basedir=/sys/fs/cgroup/memory
28580         # LU-9966
28581         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28582                 skip "no setup for cgroup"
28583
28584         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28585                 error "test file creation failed"
28586         cancel_lru_locks osc
28587
28588         # Create a very small memory cgroup to force a slab allocation error
28589         local cgdir=$cg_basedir/osc_slab_alloc
28590         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28591         trap "cleanup_test411_cgroup $cgdir" EXIT
28592         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28593         echo 1M > $cgdir/memory.limit_in_bytes
28594
28595         # Should not LBUG, just be killed by oom-killer
28596         # dd will return 0 even allocation failure in some environment.
28597         # So don't check return value
28598         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28599         cleanup_test411_cgroup $cgdir
28600
28601         return 0
28602 }
28603 run_test 411a "Slab allocation error with cgroup does not LBUG"
28604
28605 test_411b() {
28606         local cg_basedir=/sys/fs/cgroup/memory
28607         # LU-9966
28608         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28609                 skip "no setup for cgroup"
28610         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28611         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28612         # limit, so we have 384M in cgroup
28613         # (arm) this seems to hit OOM more often than x86, so 1024M
28614         if [[ $(uname -m) = aarch64 ]]; then
28615                 local memlimit_mb=1024
28616         else
28617                 local memlimit_mb=384
28618         fi
28619
28620         # Create a cgroup and set memory limit
28621         # (tfile is used as an easy way to get a recognizable cgroup name)
28622         local cgdir=$cg_basedir/$tfile
28623         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28624         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28625         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28626
28627         echo "writing first file"
28628         # Write a file 4x the memory limit in size
28629         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28630                 error "(1) failed to write successfully"
28631
28632         sync
28633         cancel_lru_locks osc
28634
28635         rm -f $DIR/$tfile
28636         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28637
28638         # Try writing at a larger block size
28639         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28640         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28641         # need *some* memory to do IO in)
28642         echo "writing at larger block size"
28643         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28644                 error "(3) failed to write successfully"
28645
28646         sync
28647         cancel_lru_locks osc
28648         rm -f $DIR/$tfile
28649         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28650
28651         # Try writing multiple files at once
28652         echo "writing multiple files"
28653         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28654         local pid1=$!
28655         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28656         local pid2=$!
28657         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28658         local pid3=$!
28659         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28660         local pid4=$!
28661
28662         wait $pid1
28663         local rc1=$?
28664         wait $pid2
28665         local rc2=$?
28666         wait $pid3
28667         local rc3=$?
28668         wait $pid4
28669         local rc4=$?
28670         if (( rc1 != 0)); then
28671                 error "error $rc1 writing to file from $pid1"
28672         fi
28673         if (( rc2 != 0)); then
28674                 error "error $rc2 writing to file from $pid2"
28675         fi
28676         if (( rc3 != 0)); then
28677                 error "error $rc3 writing to file from $pid3"
28678         fi
28679         if (( rc4 != 0)); then
28680                 error "error $rc4 writing to file from $pid4"
28681         fi
28682
28683         sync
28684         cancel_lru_locks osc
28685
28686         # These files can be large-ish (~1 GiB total), so delete them rather
28687         # than leave for later cleanup
28688         rm -f $DIR/$tfile.*
28689         return 0
28690 }
28691 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28692
28693 test_412() {
28694         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28695         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28696                 skip "Need server version at least 2.10.55"
28697
28698         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28699                 error "mkdir failed"
28700         $LFS getdirstripe $DIR/$tdir
28701         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28702         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28703                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28704         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28705         [ $stripe_count -eq 2 ] ||
28706                 error "expect 2 get $stripe_count"
28707
28708         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28709
28710         local index
28711         local index2
28712
28713         # subdirs should be on the same MDT as parent
28714         for i in $(seq 0 $((MDSCOUNT - 1))); do
28715                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28716                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28717                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28718                 (( index == i )) || error "mdt$i/sub on MDT$index"
28719         done
28720
28721         # stripe offset -1, ditto
28722         for i in {1..10}; do
28723                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28724                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28725                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28726                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28727                 (( index == index2 )) ||
28728                         error "qos$i on MDT$index, sub on MDT$index2"
28729         done
28730
28731         local testdir=$DIR/$tdir/inherit
28732
28733         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28734         # inherit 2 levels
28735         for i in 1 2; do
28736                 testdir=$testdir/s$i
28737                 mkdir $testdir || error "mkdir $testdir failed"
28738                 index=$($LFS getstripe -m $testdir)
28739                 (( index == 1 )) ||
28740                         error "$testdir on MDT$index"
28741         done
28742
28743         # not inherit any more
28744         testdir=$testdir/s3
28745         mkdir $testdir || error "mkdir $testdir failed"
28746         getfattr -d -m dmv $testdir | grep dmv &&
28747                 error "default LMV set on $testdir" || true
28748 }
28749 run_test 412 "mkdir on specific MDTs"
28750
28751 TEST413_COUNT=${TEST413_COUNT:-200}
28752
28753 #
28754 # set_maxage() is used by test_413 only.
28755 # This is a helper function to set maxage. Does not return any value.
28756 # Input: maxage to set
28757 #
28758 set_maxage() {
28759         local lmv_qos_maxage
28760         local lod_qos_maxage
28761         local new_maxage=$1
28762
28763         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28764         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28765         stack_trap "$LCTL set_param \
28766                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28767         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28768                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28769         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28770                 lod.*.mdt_qos_maxage=$new_maxage
28771         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28772                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28773 }
28774
28775 generate_uneven_mdts() {
28776         local threshold=$1
28777         local ffree
28778         local bavail
28779         local max
28780         local min
28781         local max_index
28782         local min_index
28783         local tmp
28784         local i
28785
28786         echo
28787         echo "Check for uneven MDTs: "
28788
28789         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28790         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28791         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28792
28793         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28794         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28795         max_index=0
28796         min_index=0
28797         for ((i = 1; i < ${#ffree[@]}; i++)); do
28798                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28799                 if [ $tmp -gt $max ]; then
28800                         max=$tmp
28801                         max_index=$i
28802                 fi
28803                 if [ $tmp -lt $min ]; then
28804                         min=$tmp
28805                         min_index=$i
28806                 fi
28807         done
28808
28809         (( min > 0 )) || skip "low space on MDT$min_index"
28810         (( ${ffree[min_index]} > 0 )) ||
28811                 skip "no free files on MDT$min_index"
28812         (( ${ffree[min_index]} < 10000000 )) ||
28813                 skip "too many free files on MDT$min_index"
28814
28815         # Check if we need to generate uneven MDTs
28816         local diff=$(((max - min) * 100 / min))
28817         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28818         local testdir # individual folder within $testdirp
28819         local start
28820         local cmd
28821
28822         # fallocate is faster to consume space on MDT, if available
28823         if check_fallocate_supported mds$((min_index + 1)); then
28824                 cmd="fallocate -l 128K "
28825         else
28826                 cmd="dd if=/dev/zero bs=128K count=1 of="
28827         fi
28828
28829         echo "using cmd $cmd"
28830         for (( i = 0; diff < threshold; i++ )); do
28831                 testdir=${testdirp}/$i
28832                 [ -d $testdir ] && continue
28833
28834                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28835
28836                 mkdir -p $testdirp
28837                 # generate uneven MDTs, create till $threshold% diff
28838                 echo -n "weight diff=$diff% must be > $threshold% ..."
28839                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28840                 $LFS mkdir -i $min_index $testdir ||
28841                         error "mkdir $testdir failed"
28842                 $LFS setstripe -E 1M -L mdt $testdir ||
28843                         error "setstripe $testdir failed"
28844                 start=$SECONDS
28845                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28846                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28847                 done
28848                 sync; sleep 1; sync
28849
28850                 # wait for QOS to update
28851                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28852
28853                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28854                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28855                 max=$(((${ffree[max_index]} >> 8) *
28856                         (${bavail[max_index]} * bsize >> 16)))
28857                 min=$(((${ffree[min_index]} >> 8) *
28858                         (${bavail[min_index]} * bsize >> 16)))
28859                 (( min > 0 )) || skip "low space on MDT$min_index"
28860                 diff=$(((max - min) * 100 / min))
28861         done
28862
28863         echo "MDT filesfree available: ${ffree[*]}"
28864         echo "MDT blocks available: ${bavail[*]}"
28865         echo "weight diff=$diff%"
28866 }
28867
28868 test_qos_mkdir() {
28869         local mkdir_cmd=$1
28870         local stripe_count=$2
28871         local mdts=$(comma_list $(mdts_nodes))
28872
28873         local testdir
28874         local lmv_qos_prio_free
28875         local lmv_qos_threshold_rr
28876         local lod_qos_prio_free
28877         local lod_qos_threshold_rr
28878         local total
28879         local count
28880         local i
28881
28882         # @total is total directories created if it's testing plain
28883         # directories, otherwise it's total stripe object count for
28884         # striped directories test.
28885         # remote/striped directory unlinking is slow on zfs and may
28886         # timeout, test with fewer directories
28887         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28888
28889         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28890         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28891         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28892                 head -n1)
28893         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28894         stack_trap "$LCTL set_param \
28895                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28896         stack_trap "$LCTL set_param \
28897                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28898
28899         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28900                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28901         lod_qos_prio_free=${lod_qos_prio_free%%%}
28902         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28903                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28904         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28905         stack_trap "do_nodes $mdts $LCTL set_param \
28906                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28907         stack_trap "do_nodes $mdts $LCTL set_param \
28908                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28909
28910         # decrease statfs age, so that it can be updated in time
28911         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28912         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28913
28914         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28915         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28916
28917         testdir=$DIR/$tdir-s$stripe_count/rr
28918
28919         local stripe_index=$($LFS getstripe -m $testdir)
28920         local test_mkdir_rr=true
28921
28922         getfattr -d -m dmv -e hex $testdir | grep dmv
28923         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28924                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28925                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28926                         test_mkdir_rr=false
28927         fi
28928
28929         echo
28930         $test_mkdir_rr &&
28931                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28932                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28933
28934         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28935         for (( i = 0; i < total / stripe_count; i++ )); do
28936                 eval $mkdir_cmd $testdir/subdir$i ||
28937                         error "$mkdir_cmd subdir$i failed"
28938         done
28939
28940         for (( i = 0; i < $MDSCOUNT; i++ )); do
28941                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28942                 echo "$count directories created on MDT$i"
28943                 if $test_mkdir_rr; then
28944                         (( count == total / stripe_count / MDSCOUNT )) ||
28945                                 error "subdirs are not evenly distributed"
28946                 elif (( i == stripe_index )); then
28947                         (( count == total / stripe_count )) ||
28948                                 error "$count subdirs created on MDT$i"
28949                 else
28950                         (( count == 0 )) ||
28951                                 error "$count subdirs created on MDT$i"
28952                 fi
28953
28954                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28955                         count=$($LFS getdirstripe $testdir/* |
28956                                 grep -c -P "^\s+$i\t")
28957                         echo "$count stripes created on MDT$i"
28958                         # deviation should < 5% of average
28959                         delta=$((count - total / MDSCOUNT))
28960                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28961                                 error "stripes are not evenly distributed"
28962                 fi
28963         done
28964
28965         echo
28966         echo "Check for uneven MDTs: "
28967
28968         local ffree
28969         local bavail
28970         local max
28971         local min
28972         local max_index
28973         local min_index
28974         local tmp
28975
28976         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28977         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28978         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28979
28980         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28981         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28982         max_index=0
28983         min_index=0
28984         for ((i = 1; i < ${#ffree[@]}; i++)); do
28985                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28986                 if [ $tmp -gt $max ]; then
28987                         max=$tmp
28988                         max_index=$i
28989                 fi
28990                 if [ $tmp -lt $min ]; then
28991                         min=$tmp
28992                         min_index=$i
28993                 fi
28994         done
28995         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28996
28997         (( min > 0 )) || skip "low space on MDT$min_index"
28998         (( ${ffree[min_index]} < 10000000 )) ||
28999                 skip "too many free files on MDT$min_index"
29000
29001         generate_uneven_mdts 120
29002
29003         echo "MDT filesfree available: ${ffree[*]}"
29004         echo "MDT blocks available: ${bavail[*]}"
29005         echo "weight diff=$(((max - min) * 100 / min))%"
29006         echo
29007         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29008
29009         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29010         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29011         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29012         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29013
29014         sleep 1
29015
29016         testdir=$DIR/$tdir-s$stripe_count/qos
29017
29018         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29019         for (( i = 0; i < total / stripe_count; i++ )); do
29020                 eval $mkdir_cmd $testdir/subdir$i ||
29021                         error "$mkdir_cmd subdir$i failed"
29022         done
29023
29024         max=0
29025         for (( i = 0; i < $MDSCOUNT; i++ )); do
29026                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29027                 (( count > max )) && max=$count
29028                 echo "$count directories created on MDT$i : curmax=$max"
29029         done
29030
29031         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29032
29033         # D-value should > 10% of average
29034         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29035                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29036
29037         # ditto for stripes
29038         if (( stripe_count > 1 )); then
29039                 max=0
29040                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29041                         count=$($LFS getdirstripe $testdir/* |
29042                                 grep -c -P "^\s+$i\t")
29043                         (( count > max )) && max=$count
29044                         echo "$count stripes created on MDT$i"
29045                 done
29046
29047                 min=$($LFS getdirstripe $testdir/* |
29048                         grep -c -P "^\s+$min_index\t")
29049                 (( max - min > total / MDSCOUNT / 10 )) ||
29050                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29051         fi
29052 }
29053
29054 most_full_mdt() {
29055         local ffree
29056         local bavail
29057         local bsize
29058         local min
29059         local min_index
29060         local tmp
29061
29062         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29063         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29064         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29065
29066         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29067         min_index=0
29068         for ((i = 1; i < ${#ffree[@]}; i++)); do
29069                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29070                 (( tmp < min )) && min=$tmp && min_index=$i
29071         done
29072
29073         echo -n $min_index
29074 }
29075
29076 test_413a() {
29077         [ $MDSCOUNT -lt 2 ] &&
29078                 skip "We need at least 2 MDTs for this test"
29079
29080         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29081                 skip "Need server version at least 2.12.52"
29082
29083         local stripe_max=$((MDSCOUNT - 1))
29084         local stripe_count
29085
29086         # let caller set maxage for latest result
29087         set_maxage 1
29088
29089         # fill MDT unevenly
29090         generate_uneven_mdts 120
29091
29092         # test 4-stripe directory at most, otherwise it's too slow
29093         # We are being very defensive. Although Autotest uses 4 MDTs.
29094         # We make sure stripe_max does not go over 4.
29095         (( stripe_max > 4 )) && stripe_max=4
29096         # unlinking striped directory is slow on zfs, and may timeout, only test
29097         # plain directory
29098         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29099         for stripe_count in $(seq 1 $stripe_max); do
29100                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29101                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29102                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29103                         error "mkdir failed"
29104                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29105         done
29106 }
29107 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29108
29109 test_413b() {
29110         [ $MDSCOUNT -lt 2 ] &&
29111                 skip "We need at least 2 MDTs for this test"
29112
29113         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29114                 skip "Need server version at least 2.12.52"
29115
29116         local stripe_max=$((MDSCOUNT - 1))
29117         local testdir
29118         local stripe_count
29119
29120         # let caller set maxage for latest result
29121         set_maxage 1
29122
29123         # fill MDT unevenly
29124         generate_uneven_mdts 120
29125
29126         # test 4-stripe directory at most, otherwise it's too slow
29127         # We are being very defensive. Although Autotest uses 4 MDTs.
29128         # We make sure stripe_max does not go over 4.
29129         (( stripe_max > 4 )) && stripe_max=4
29130         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29131         for stripe_count in $(seq 1 $stripe_max); do
29132                 testdir=$DIR/$tdir-s$stripe_count
29133                 mkdir $testdir || error "mkdir $testdir failed"
29134                 mkdir $testdir/rr || error "mkdir rr failed"
29135                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29136                         error "mkdir qos failed"
29137                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29138                         $testdir/rr || error "setdirstripe rr failed"
29139                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29140                         error "setdirstripe failed"
29141                 test_qos_mkdir "mkdir" $stripe_count
29142         done
29143 }
29144 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29145
29146 test_413c() {
29147         (( $MDSCOUNT >= 2 )) ||
29148                 skip "We need at least 2 MDTs for this test"
29149
29150         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29151                 skip "Need server version at least 2.14.51"
29152
29153         local testdir
29154         local inherit
29155         local inherit_rr
29156         local lmv_qos_maxage
29157         local lod_qos_maxage
29158
29159         # let caller set maxage for latest result
29160         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29161         $LCTL set_param lmv.*.qos_maxage=1
29162         stack_trap "$LCTL set_param \
29163                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29164         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29165                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29166         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29167                 lod.*.mdt_qos_maxage=1
29168         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29169                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29170
29171         # fill MDT unevenly
29172         generate_uneven_mdts 120
29173
29174         testdir=$DIR/${tdir}-s1
29175         mkdir $testdir || error "mkdir $testdir failed"
29176         mkdir $testdir/rr || error "mkdir rr failed"
29177         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29178         # default max_inherit is -1, default max_inherit_rr is 0
29179         $LFS setdirstripe -D -c 1 $testdir/rr ||
29180                 error "setdirstripe rr failed"
29181         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29182                 error "setdirstripe qos failed"
29183         test_qos_mkdir "mkdir" 1
29184
29185         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29186         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29187         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29188         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29189         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29190
29191         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29192         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29193         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29194         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29195         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29196         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29197         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29198                 error "level2 shouldn't have default LMV" || true
29199 }
29200 run_test 413c "mkdir with default LMV max inherit rr"
29201
29202 test_413d() {
29203         (( MDSCOUNT >= 2 )) ||
29204                 skip "We need at least 2 MDTs for this test"
29205
29206         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29207                 skip "Need server version at least 2.14.51"
29208
29209         local lmv_qos_threshold_rr
29210
29211         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29212                 head -n1)
29213         stack_trap "$LCTL set_param \
29214                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29215
29216         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29217         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29218         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29219                 error "$tdir shouldn't have default LMV"
29220         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29221                 error "mkdir sub failed"
29222
29223         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29224
29225         (( count == 100 )) || error "$count subdirs on MDT0"
29226 }
29227 run_test 413d "inherit ROOT default LMV"
29228
29229 test_413e() {
29230         (( MDSCOUNT >= 2 )) ||
29231                 skip "We need at least 2 MDTs for this test"
29232         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29233                 skip "Need server version at least 2.14.55"
29234
29235         local testdir=$DIR/$tdir
29236         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29237         local max_inherit
29238         local sub_max_inherit
29239
29240         mkdir -p $testdir || error "failed to create $testdir"
29241
29242         # set default max-inherit to -1 if stripe count is 0 or 1
29243         $LFS setdirstripe -D -c 1 $testdir ||
29244                 error "failed to set default LMV"
29245         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29246         (( max_inherit == -1 )) ||
29247                 error "wrong max_inherit value $max_inherit"
29248
29249         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29250         $LFS setdirstripe -D -c -1 $testdir ||
29251                 error "failed to set default LMV"
29252         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29253         (( max_inherit > 0 )) ||
29254                 error "wrong max_inherit value $max_inherit"
29255
29256         # and the subdir will decrease the max_inherit by 1
29257         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29258         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29259         (( sub_max_inherit == max_inherit - 1)) ||
29260                 error "wrong max-inherit of subdir $sub_max_inherit"
29261
29262         # check specified --max-inherit and warning message
29263         stack_trap "rm -f $tmpfile"
29264         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29265                 error "failed to set default LMV"
29266         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29267         (( max_inherit == -1 )) ||
29268                 error "wrong max_inherit value $max_inherit"
29269
29270         # check the warning messages
29271         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29272                 error "failed to detect warning string"
29273         fi
29274 }
29275 run_test 413e "check default max-inherit value"
29276
29277 test_fs_dmv_inherit()
29278 {
29279         local testdir=$DIR/$tdir
29280
29281         local count
29282         local inherit
29283         local inherit_rr
29284
29285         for i in 1 2; do
29286                 mkdir $testdir || error "mkdir $testdir failed"
29287                 count=$($LFS getdirstripe -D -c $testdir)
29288                 (( count == 1 )) ||
29289                         error "$testdir default LMV count mismatch $count != 1"
29290                 inherit=$($LFS getdirstripe -D -X $testdir)
29291                 (( inherit == 3 - i )) ||
29292                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29293                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29294                 (( inherit_rr == 3 - i )) ||
29295                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29296                 testdir=$testdir/sub
29297         done
29298
29299         mkdir $testdir || error "mkdir $testdir failed"
29300         count=$($LFS getdirstripe -D -c $testdir)
29301         (( count == 0 )) ||
29302                 error "$testdir default LMV count not zero: $count"
29303 }
29304
29305 test_413f() {
29306         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29307
29308         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29309                 skip "Need server version at least 2.14.55"
29310
29311         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29312                 error "dump $DIR default LMV failed"
29313         stack_trap "setfattr --restore=$TMP/dmv.ea"
29314
29315         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29316                 error "set $DIR default LMV failed"
29317
29318         test_fs_dmv_inherit
29319 }
29320 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29321
29322 test_413g() {
29323         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29324
29325         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29326         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29327                 error "dump $DIR default LMV failed"
29328         stack_trap "setfattr --restore=$TMP/dmv.ea"
29329
29330         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29331                 error "set $DIR default LMV failed"
29332
29333         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29334                 error "mount $MOUNT2 failed"
29335         stack_trap "umount_client $MOUNT2"
29336
29337         local saved_DIR=$DIR
29338
29339         export DIR=$MOUNT2
29340
29341         stack_trap "export DIR=$saved_DIR"
29342
29343         # first check filesystem-wide default LMV inheritance
29344         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29345
29346         # then check subdirs are spread to all MDTs
29347         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29348
29349         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29350
29351         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29352 }
29353 run_test 413g "enforce ROOT default LMV on subdir mount"
29354
29355 test_413h() {
29356         (( MDSCOUNT >= 2 )) ||
29357                 skip "We need at least 2 MDTs for this test"
29358
29359         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29360                 skip "Need server version at least 2.15.50.6"
29361
29362         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29363
29364         stack_trap "$LCTL set_param \
29365                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29366         $LCTL set_param lmv.*.qos_maxage=1
29367
29368         local depth=5
29369         local rr_depth=4
29370         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29371         local count=$((MDSCOUNT * 20))
29372
29373         generate_uneven_mdts 50
29374
29375         mkdir -p $dir || error "mkdir $dir failed"
29376         stack_trap "rm -rf $dir"
29377         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29378                 --max-inherit-rr=$rr_depth $dir
29379
29380         for ((d=0; d < depth + 2; d++)); do
29381                 log "dir=$dir:"
29382                 for ((sub=0; sub < count; sub++)); do
29383                         mkdir $dir/d$sub
29384                 done
29385                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29386                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29387                 # subdirs within $rr_depth should be created round-robin
29388                 if (( d < rr_depth )); then
29389                         (( ${num[0]} != count )) ||
29390                                 error "all objects created on MDT ${num[1]}"
29391                 fi
29392
29393                 dir=$dir/d0
29394         done
29395 }
29396 run_test 413h "don't stick to parent for round-robin dirs"
29397
29398 test_413i() {
29399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29400
29401         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29402                 skip "Need server version at least 2.14.55"
29403
29404         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29405                 error "dump $DIR default LMV failed"
29406         stack_trap "setfattr --restore=$TMP/dmv.ea"
29407
29408         local testdir=$DIR/$tdir
29409         local def_max_rr=1
29410         local def_max=3
29411         local count
29412
29413         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29414                 --max-inherit-rr=$def_max_rr $DIR ||
29415                 error "set $DIR default LMV failed"
29416
29417         for i in $(seq 2 3); do
29418                 def_max=$((def_max - 1))
29419                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29420
29421                 mkdir $testdir
29422                 # RR is decremented and keeps zeroed once exhausted
29423                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29424                 (( count == def_max_rr )) ||
29425                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29426
29427                 # max-inherit is decremented
29428                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29429                 (( count == def_max )) ||
29430                         error_noexit "$testdir: max-inherit $count != $def_max"
29431
29432                 testdir=$testdir/d$i
29433         done
29434
29435         # d3 is the last inherited from ROOT, no inheritance anymore
29436         # i.e. no the default layout anymore
29437         mkdir -p $testdir/d4/d5
29438         count=$($LFS getdirstripe -D --max-inherit $testdir)
29439         (( count == -1 )) ||
29440                 error_noexit "$testdir: max-inherit $count != -1"
29441
29442         local p_count=$($LFS getdirstripe -i $testdir)
29443
29444         for i in $(seq 4 5); do
29445                 testdir=$testdir/d$i
29446
29447                 # the root default layout is not applied once exhausted
29448                 count=$($LFS getdirstripe -i $testdir)
29449                 (( count == p_count )) ||
29450                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29451         done
29452
29453         $LFS setdirstripe -i 0 $DIR/d2
29454         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29455         (( count == -1 )) ||
29456                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29457 }
29458 run_test 413i "check default layout inheritance"
29459
29460 test_413j()
29461 {
29462         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29463
29464         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29465         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29466                 error "setdirstripe $tdir failed"
29467
29468         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29469                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29470
29471         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29472         # setfattr dmv calls setdirstripe -D
29473         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29474                 error "setfattr sub failed"
29475         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29476                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29477
29478         [ $value == $value2 ] || error "dmv mismatch"
29479
29480         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29481
29482         # do not allow remove dmv by setfattr -x
29483         do_nodes $(comma_list $(mdts_nodes)) \
29484                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29485         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29486         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29487
29488         # allow remove dmv by setfattr -x
29489         do_nodes $(comma_list $(mdts_nodes)) \
29490                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29491         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29492         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29493         do_nodes $(comma_list $(mdts_nodes)) \
29494                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29495 }
29496 run_test 413j "set default LMV by setxattr"
29497
29498 test_413k() {
29499         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29500                 skip "Need server version at least 2.15.60"
29501
29502         local index1
29503         local index2
29504         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29505         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29506         local prefixes="abc:123:foo bar"
29507
29508         # add prefixes
29509         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29510         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29511
29512         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29513         index1=$($LFS getstripe -m $DIR/$tdir)
29514         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29515                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29516                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29517                 ((index1 == index2)) ||
29518                         error "$tdir on MDT$index1, $dname on MDT$index2"
29519         done
29520
29521         # remove prefixes
29522         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29523
29524         # total prefixes length > PAGE_SIZE can be printed correctly
29525         for c in {a..z}; do
29526                 prefixes=$(str_repeat $c 255)
29527                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29528         done
29529         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29530         ((count2 == count + 26)) ||
29531                 error "prefixes count $count2 != $((count + 26))"
29532 }
29533 run_test 413k "QoS mkdir exclude prefixes"
29534
29535 test_413z() {
29536         local pids=""
29537         local subdir
29538         local pid
29539
29540         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29541                 unlinkmany $subdir/f. $TEST413_COUNT &
29542                 pids="$pids $!"
29543         done
29544
29545         for pid in $pids; do
29546                 wait $pid
29547         done
29548
29549         true
29550 }
29551 run_test 413z "413 test cleanup"
29552
29553 test_414() {
29554 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29555         $LCTL set_param fail_loc=0x80000521
29556         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29557         rm -f $DIR/$tfile
29558 }
29559 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29560
29561 test_415() {
29562         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29563         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29564                 skip "Need server version at least 2.11.52"
29565
29566         # LU-11102
29567         local total=500
29568         local max=120
29569
29570         # this test may be slow on ZFS
29571         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29572
29573         # though this test is designed for striped directory, let's test normal
29574         # directory too since lock is always saved as CoS lock.
29575         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29576         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29577         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29578         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29579         wait_delete_completed_mds
29580
29581         # run a loop without concurrent touch to measure rename duration.
29582         # only for test debug/robustness, NOT part of COS functional test.
29583         local start_time=$SECONDS
29584         for ((i = 0; i < total; i++)); do
29585                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29586                         > /dev/null
29587         done
29588         local baseline=$((SECONDS - start_time))
29589         echo "rename $total files without 'touch' took $baseline sec"
29590
29591         (
29592                 while true; do
29593                         touch $DIR/$tdir
29594                 done
29595         ) &
29596         local setattr_pid=$!
29597
29598         # rename files back to original name so unlinkmany works
29599         start_time=$SECONDS
29600         for ((i = 0; i < total; i++)); do
29601                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29602                         > /dev/null
29603         done
29604         local duration=$((SECONDS - start_time))
29605
29606         kill -9 $setattr_pid
29607
29608         echo "rename $total files with 'touch' took $duration sec"
29609         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29610         (( duration <= max )) ||
29611                 error_not_in_vm "rename took $duration > $max sec"
29612 }
29613 run_test 415 "lock revoke is not missing"
29614
29615 test_416() {
29616         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29617                 skip "Need server version at least 2.11.55"
29618
29619         # define OBD_FAIL_OSD_TXN_START    0x19a
29620         do_facet mds1 lctl set_param fail_loc=0x19a
29621
29622         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29623
29624         true
29625 }
29626 run_test 416 "transaction start failure won't cause system hung"
29627
29628 cleanup_417() {
29629         trap 0
29630         do_nodes $(comma_list $(mdts_nodes)) \
29631                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29632         do_nodes $(comma_list $(mdts_nodes)) \
29633                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29634         do_nodes $(comma_list $(mdts_nodes)) \
29635                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29636 }
29637
29638 test_417() {
29639         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29640         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29641                 skip "Need MDS version at least 2.11.56"
29642
29643         trap cleanup_417 RETURN EXIT
29644
29645         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29646         do_nodes $(comma_list $(mdts_nodes)) \
29647                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29648         $LFS migrate -m 0 $DIR/$tdir.1 &&
29649                 error "migrate dir $tdir.1 should fail"
29650
29651         do_nodes $(comma_list $(mdts_nodes)) \
29652                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29653         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29654                 error "create remote dir $tdir.2 should fail"
29655
29656         do_nodes $(comma_list $(mdts_nodes)) \
29657                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29658         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29659                 error "create striped dir $tdir.3 should fail"
29660         true
29661 }
29662 run_test 417 "disable remote dir, striped dir and dir migration"
29663
29664 # Checks that the outputs of df [-i] and lfs df [-i] match
29665 #
29666 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29667 check_lfs_df() {
29668         local dir=$2
29669         local inodes
29670         local df_out
29671         local lfs_df_out
29672         local count
29673         local passed=false
29674
29675         # blocks or inodes
29676         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29677
29678         for count in {1..100}; do
29679                 do_nodes "$CLIENTS" \
29680                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29681                 sync; sleep 0.2
29682
29683                 # read the lines of interest
29684                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29685                         error "df $inodes $dir | tail -n +2 failed"
29686                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29687                         error "lfs df $inodes $dir | grep summary: failed"
29688
29689                 # skip first substrings of each output as they are different
29690                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29691                 # compare the two outputs
29692                 passed=true
29693                 #  skip "available" on MDT until LU-13997 is fixed.
29694                 #for i in {1..5}; do
29695                 for i in 1 2 4 5; do
29696                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29697                 done
29698                 $passed && break
29699         done
29700
29701         if ! $passed; then
29702                 df -P $inodes $dir
29703                 echo
29704                 lfs df $inodes $dir
29705                 error "df and lfs df $1 output mismatch: "      \
29706                       "df ${inodes}: ${df_out[*]}, "            \
29707                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29708         fi
29709 }
29710
29711 test_418() {
29712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29713
29714         local dir=$DIR/$tdir
29715         local numfiles=$((RANDOM % 4096 + 2))
29716         local numblocks=$((RANDOM % 256 + 1))
29717
29718         wait_delete_completed
29719         test_mkdir $dir
29720
29721         # check block output
29722         check_lfs_df blocks $dir
29723         # check inode output
29724         check_lfs_df inodes $dir
29725
29726         # create a single file and retest
29727         echo "Creating a single file and testing"
29728         createmany -o $dir/$tfile- 1 &>/dev/null ||
29729                 error "creating 1 file in $dir failed"
29730         check_lfs_df blocks $dir
29731         check_lfs_df inodes $dir
29732
29733         # create a random number of files
29734         echo "Creating $((numfiles - 1)) files and testing"
29735         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29736                 error "creating $((numfiles - 1)) files in $dir failed"
29737
29738         # write a random number of blocks to the first test file
29739         echo "Writing $numblocks 4K blocks and testing"
29740         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29741                 count=$numblocks &>/dev/null ||
29742                 error "dd to $dir/${tfile}-0 failed"
29743
29744         # retest
29745         check_lfs_df blocks $dir
29746         check_lfs_df inodes $dir
29747
29748         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29749                 error "unlinking $numfiles files in $dir failed"
29750 }
29751 run_test 418 "df and lfs df outputs match"
29752
29753 test_419()
29754 {
29755         local dir=$DIR/$tdir
29756
29757         mkdir -p $dir
29758         touch $dir/file
29759
29760         cancel_lru_locks mdc
29761
29762         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29763         $LCTL set_param fail_loc=0x1410
29764         cat $dir/file
29765         $LCTL set_param fail_loc=0
29766         rm -rf $dir
29767 }
29768 run_test 419 "Verify open file by name doesn't crash kernel"
29769
29770 test_420()
29771 {
29772         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29773                 skip "Need MDS version at least 2.12.53"
29774
29775         local SAVE_UMASK=$(umask)
29776         local dir=$DIR/$tdir
29777         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29778
29779         mkdir -p $dir
29780         umask 0000
29781         mkdir -m03777 $dir/testdir
29782         ls -dn $dir/testdir
29783         # Need to remove trailing '.' when SELinux is enabled
29784         local dirperms=$(ls -dn $dir/testdir |
29785                          awk '{ sub(/\.$/, "", $1); print $1}')
29786         [ $dirperms == "drwxrwsrwt" ] ||
29787                 error "incorrect perms on $dir/testdir"
29788
29789         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29790                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29791         ls -n $dir/testdir/testfile
29792         local fileperms=$(ls -n $dir/testdir/testfile |
29793                           awk '{ sub(/\.$/, "", $1); print $1}')
29794         [ $fileperms == "-rwxr-xr-x" ] ||
29795                 error "incorrect perms on $dir/testdir/testfile"
29796
29797         umask $SAVE_UMASK
29798 }
29799 run_test 420 "clear SGID bit on non-directories for non-members"
29800
29801 test_421a() {
29802         local cnt
29803         local fid1
29804         local fid2
29805
29806         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29807                 skip "Need MDS version at least 2.12.54"
29808
29809         test_mkdir $DIR/$tdir
29810         createmany -o $DIR/$tdir/f 3
29811         cnt=$(ls -1 $DIR/$tdir | wc -l)
29812         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29813
29814         fid1=$(lfs path2fid $DIR/$tdir/f1)
29815         fid2=$(lfs path2fid $DIR/$tdir/f2)
29816         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29817
29818         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29819         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29820
29821         cnt=$(ls -1 $DIR/$tdir | wc -l)
29822         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29823
29824         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29825         createmany -o $DIR/$tdir/f 3
29826         cnt=$(ls -1 $DIR/$tdir | wc -l)
29827         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29828
29829         fid1=$(lfs path2fid $DIR/$tdir/f1)
29830         fid2=$(lfs path2fid $DIR/$tdir/f2)
29831         echo "remove using fsname $FSNAME"
29832         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29833
29834         cnt=$(ls -1 $DIR/$tdir | wc -l)
29835         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29836 }
29837 run_test 421a "simple rm by fid"
29838
29839 test_421b() {
29840         local cnt
29841         local FID1
29842         local FID2
29843
29844         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29845                 skip "Need MDS version at least 2.12.54"
29846
29847         test_mkdir $DIR/$tdir
29848         createmany -o $DIR/$tdir/f 3
29849         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29850         MULTIPID=$!
29851
29852         FID1=$(lfs path2fid $DIR/$tdir/f1)
29853         FID2=$(lfs path2fid $DIR/$tdir/f2)
29854         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29855
29856         kill -USR1 $MULTIPID
29857         wait
29858
29859         cnt=$(ls $DIR/$tdir | wc -l)
29860         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29861 }
29862 run_test 421b "rm by fid on open file"
29863
29864 test_421c() {
29865         local cnt
29866         local FIDS
29867
29868         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29869                 skip "Need MDS version at least 2.12.54"
29870
29871         test_mkdir $DIR/$tdir
29872         createmany -o $DIR/$tdir/f 3
29873         touch $DIR/$tdir/$tfile
29874         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29875         cnt=$(ls -1 $DIR/$tdir | wc -l)
29876         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29877
29878         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29879         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29880
29881         cnt=$(ls $DIR/$tdir | wc -l)
29882         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29883 }
29884 run_test 421c "rm by fid against hardlinked files"
29885
29886 test_421d() {
29887         local cnt
29888         local FIDS
29889
29890         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29891                 skip "Need MDS version at least 2.12.54"
29892
29893         test_mkdir $DIR/$tdir
29894         createmany -o $DIR/$tdir/f 4097
29895         cnt=$(ls -1 $DIR/$tdir | wc -l)
29896         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29897
29898         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29899         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29900
29901         cnt=$(ls $DIR/$tdir | wc -l)
29902         rm -rf $DIR/$tdir
29903         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29904 }
29905 run_test 421d "rmfid en masse"
29906
29907 test_421e() {
29908         local cnt
29909         local FID
29910
29911         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29912         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29913                 skip "Need MDS version at least 2.12.54"
29914
29915         mkdir -p $DIR/$tdir
29916         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29917         createmany -o $DIR/$tdir/striped_dir/f 512
29918         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29919         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29920
29921         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29922                 sed "s/[/][^:]*://g")
29923         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29924
29925         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29926         rm -rf $DIR/$tdir
29927         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29928 }
29929 run_test 421e "rmfid in DNE"
29930
29931 test_421f() {
29932         local cnt
29933         local FID
29934
29935         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29936                 skip "Need MDS version at least 2.12.54"
29937
29938         test_mkdir $DIR/$tdir
29939         touch $DIR/$tdir/f
29940         cnt=$(ls -1 $DIR/$tdir | wc -l)
29941         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29942
29943         FID=$(lfs path2fid $DIR/$tdir/f)
29944         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29945         # rmfid should fail
29946         cnt=$(ls -1 $DIR/$tdir | wc -l)
29947         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29948
29949         chmod a+rw $DIR/$tdir
29950         ls -la $DIR/$tdir
29951         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29952         # rmfid should fail
29953         cnt=$(ls -1 $DIR/$tdir | wc -l)
29954         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29955
29956         rm -f $DIR/$tdir/f
29957         $RUNAS touch $DIR/$tdir/f
29958         FID=$(lfs path2fid $DIR/$tdir/f)
29959         echo "rmfid as root"
29960         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29961         cnt=$(ls -1 $DIR/$tdir | wc -l)
29962         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29963
29964         rm -f $DIR/$tdir/f
29965         $RUNAS touch $DIR/$tdir/f
29966         cnt=$(ls -1 $DIR/$tdir | wc -l)
29967         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29968         FID=$(lfs path2fid $DIR/$tdir/f)
29969         # rmfid w/o user_fid2path mount option should fail
29970         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29971         cnt=$(ls -1 $DIR/$tdir | wc -l)
29972         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29973
29974         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29975         stack_trap "rmdir $tmpdir"
29976         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29977                 error "failed to mount client'"
29978         stack_trap "umount_client $tmpdir"
29979
29980         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29981         # rmfid should succeed
29982         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29983         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29984
29985         # rmfid shouldn't allow to remove files due to dir's permission
29986         chmod a+rwx $tmpdir/$tdir
29987         touch $tmpdir/$tdir/f
29988         ls -la $tmpdir/$tdir
29989         FID=$(lfs path2fid $tmpdir/$tdir/f)
29990         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29991         return 0
29992 }
29993 run_test 421f "rmfid checks permissions"
29994
29995 test_421g() {
29996         local cnt
29997         local FIDS
29998
29999         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30000         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30001                 skip "Need MDS version at least 2.12.54"
30002
30003         mkdir -p $DIR/$tdir
30004         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30005         createmany -o $DIR/$tdir/striped_dir/f 512
30006         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30007         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30008
30009         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30010                 sed "s/[/][^:]*://g")
30011
30012         rm -f $DIR/$tdir/striped_dir/f1*
30013         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30014         removed=$((512 - cnt))
30015
30016         # few files have been just removed, so we expect
30017         # rmfid to fail on their fids
30018         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30019         [ $removed != $errors ] && error "$errors != $removed"
30020
30021         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30022         rm -rf $DIR/$tdir
30023         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30024 }
30025 run_test 421g "rmfid to return errors properly"
30026
30027 test_421h() {
30028         local mount_other
30029         local mount_ret
30030         local rmfid_ret
30031         local old_fid
30032         local fidA
30033         local fidB
30034         local fidC
30035         local fidD
30036
30037         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30038                 skip "Need MDS version at least 2.15.53"
30039
30040         test_mkdir $DIR/$tdir
30041         test_mkdir $DIR/$tdir/subdir
30042         touch $DIR/$tdir/subdir/file0
30043         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30044         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30045         rm -f $DIR/$tdir/subdir/file0
30046         touch $DIR/$tdir/subdir/fileA
30047         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30048         echo File $DIR/$tdir/subdir/fileA FID $fidA
30049         touch $DIR/$tdir/subdir/fileB
30050         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30051         echo File $DIR/$tdir/subdir/fileB FID $fidB
30052         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30053         touch $DIR/$tdir/subdir/fileC
30054         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30055         echo File $DIR/$tdir/subdir/fileC FID $fidC
30056         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30057         touch $DIR/$tdir/fileD
30058         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30059         echo File $DIR/$tdir/fileD FID $fidD
30060
30061         # mount another client mount point with subdirectory mount
30062         export FILESET=/$tdir/subdir
30063         mount_other=${MOUNT}_other
30064         mount_client $mount_other ${MOUNT_OPTS}
30065         mount_ret=$?
30066         export FILESET=""
30067         (( mount_ret == 0 )) || error "mount $mount_other failed"
30068
30069         echo Removing FIDs:
30070         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30071         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30072         rmfid_ret=$?
30073
30074         umount_client $mount_other || error "umount $mount_other failed"
30075
30076         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30077
30078         # fileA should have been deleted
30079         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30080
30081         # fileB should have been deleted
30082         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30083
30084         # fileC should not have been deleted, fid also exists outside of fileset
30085         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30086
30087         # fileD should not have been deleted, it exists outside of fileset
30088         stat $DIR/$tdir/fileD || error "fileD deleted"
30089 }
30090 run_test 421h "rmfid with fileset mount"
30091
30092 test_422() {
30093         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30094         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30095         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30096         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30097         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30098
30099         local amc=$(at_max_get client)
30100         local amo=$(at_max_get mds1)
30101         local timeout=`lctl get_param -n timeout`
30102
30103         at_max_set 0 client
30104         at_max_set 0 mds1
30105
30106 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30107         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30108                         fail_val=$(((2*timeout + 10)*1000))
30109         touch $DIR/$tdir/d3/file &
30110         sleep 2
30111 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30112         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30113                         fail_val=$((2*timeout + 5))
30114         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30115         local pid=$!
30116         sleep 1
30117         kill -9 $pid
30118         sleep $((2 * timeout))
30119         echo kill $pid
30120         kill -9 $pid
30121         lctl mark touch
30122         touch $DIR/$tdir/d2/file3
30123         touch $DIR/$tdir/d2/file4
30124         touch $DIR/$tdir/d2/file5
30125
30126         wait
30127         at_max_set $amc client
30128         at_max_set $amo mds1
30129
30130         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30131         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30132                 error "Watchdog is always throttled"
30133 }
30134 run_test 422 "kill a process with RPC in progress"
30135
30136 stat_test() {
30137     df -h $MOUNT &
30138     df -h $MOUNT &
30139     df -h $MOUNT &
30140     df -h $MOUNT &
30141     df -h $MOUNT &
30142     df -h $MOUNT &
30143 }
30144
30145 test_423() {
30146     local _stats
30147     # ensure statfs cache is expired
30148     sleep 2;
30149
30150     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30151     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30152
30153     return 0
30154 }
30155 run_test 423 "statfs should return a right data"
30156
30157 test_424() {
30158 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30159         $LCTL set_param fail_loc=0x80000522
30160         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30161         rm -f $DIR/$tfile
30162 }
30163 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30164
30165 test_425() {
30166         test_mkdir -c -1 $DIR/$tdir
30167         $LFS setstripe -c -1 $DIR/$tdir
30168
30169         lru_resize_disable "" 100
30170         stack_trap "lru_resize_enable" EXIT
30171
30172         sleep 5
30173
30174         for i in $(seq $((MDSCOUNT * 125))); do
30175                 local t=$DIR/$tdir/$tfile_$i
30176
30177                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30178                         error_noexit "Create file $t"
30179         done
30180         stack_trap "rm -rf $DIR/$tdir" EXIT
30181
30182         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30183                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30184                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30185
30186                 [ $lock_count -le $lru_size ] ||
30187                         error "osc lock count $lock_count > lru size $lru_size"
30188         done
30189
30190         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30191                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30192                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30193
30194                 [ $lock_count -le $lru_size ] ||
30195                         error "mdc lock count $lock_count > lru size $lru_size"
30196         done
30197 }
30198 run_test 425 "lock count should not exceed lru size"
30199
30200 test_426() {
30201         splice-test -r $DIR/$tfile
30202         splice-test -rd $DIR/$tfile
30203         splice-test $DIR/$tfile
30204         splice-test -d $DIR/$tfile
30205 }
30206 run_test 426 "splice test on Lustre"
30207
30208 test_427() {
30209         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30210         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30211                 skip "Need MDS version at least 2.12.4"
30212         local log
30213
30214         mkdir $DIR/$tdir
30215         mkdir $DIR/$tdir/1
30216         mkdir $DIR/$tdir/2
30217         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30218         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30219
30220         $LFS getdirstripe $DIR/$tdir/1/dir
30221
30222         #first setfattr for creating updatelog
30223         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30224
30225 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30226         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30227         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30228         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30229
30230         sleep 2
30231         fail mds2
30232         wait_recovery_complete mds2 $((2*TIMEOUT))
30233
30234         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30235         echo $log | grep "get update log failed" &&
30236                 error "update log corruption is detected" || true
30237 }
30238 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30239
30240 test_428() {
30241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30242         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30243                               awk '/^max_cached_mb/ { print $2 }')
30244         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30245
30246         $LCTL set_param -n llite.*.max_cached_mb=64
30247
30248         mkdir $DIR/$tdir
30249         $LFS setstripe -c 1 $DIR/$tdir
30250         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30251         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30252         #test write
30253         for f in $(seq 4); do
30254                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30255         done
30256         wait
30257
30258         cancel_lru_locks osc
30259         # Test read
30260         for f in $(seq 4); do
30261                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30262         done
30263         wait
30264 }
30265 run_test 428 "large block size IO should not hang"
30266
30267 test_429() { # LU-7915 / LU-10948
30268         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30269         local testfile=$DIR/$tfile
30270         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30271         local new_flag=1
30272         local first_rpc
30273         local second_rpc
30274         local third_rpc
30275
30276         $LCTL get_param $ll_opencache_threshold_count ||
30277                 skip "client does not have opencache parameter"
30278
30279         set_opencache $new_flag
30280         stack_trap "restore_opencache"
30281         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30282                 error "enable opencache failed"
30283         touch $testfile
30284         # drop MDC DLM locks
30285         cancel_lru_locks mdc
30286         # clear MDC RPC stats counters
30287         $LCTL set_param $mdc_rpcstats=clear
30288
30289         # According to the current implementation, we need to run 3 times
30290         # open & close file to verify if opencache is enabled correctly.
30291         # 1st, RPCs are sent for lookup/open and open handle is released on
30292         #      close finally.
30293         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30294         #      so open handle won't be released thereafter.
30295         # 3rd, No RPC is sent out.
30296         $MULTIOP $testfile oc || error "multiop failed"
30297         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30298         echo "1st: $first_rpc RPCs in flight"
30299
30300         $MULTIOP $testfile oc || error "multiop failed"
30301         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30302         echo "2nd: $second_rpc RPCs in flight"
30303
30304         $MULTIOP $testfile oc || error "multiop failed"
30305         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30306         echo "3rd: $third_rpc RPCs in flight"
30307
30308         #verify no MDC RPC is sent
30309         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30310 }
30311 run_test 429 "verify if opencache flag on client side does work"
30312
30313 lseek_test_430() {
30314         local offset
30315         local file=$1
30316
30317         # data at [200K, 400K)
30318         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30319                 error "256K->512K dd fails"
30320         # data at [2M, 3M)
30321         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30322                 error "2M->3M dd fails"
30323         # data at [4M, 5M)
30324         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30325                 error "4M->5M dd fails"
30326         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30327         # start at first component hole #1
30328         printf "Seeking hole from 1000 ... "
30329         offset=$(lseek_test -l 1000 $file)
30330         echo $offset
30331         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30332         printf "Seeking data from 1000 ... "
30333         offset=$(lseek_test -d 1000 $file)
30334         echo $offset
30335         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30336
30337         # start at first component data block
30338         printf "Seeking hole from 300000 ... "
30339         offset=$(lseek_test -l 300000 $file)
30340         echo $offset
30341         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30342         printf "Seeking data from 300000 ... "
30343         offset=$(lseek_test -d 300000 $file)
30344         echo $offset
30345         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30346
30347         # start at the first component but beyond end of object size
30348         printf "Seeking hole from 1000000 ... "
30349         offset=$(lseek_test -l 1000000 $file)
30350         echo $offset
30351         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30352         printf "Seeking data from 1000000 ... "
30353         offset=$(lseek_test -d 1000000 $file)
30354         echo $offset
30355         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30356
30357         # start at second component stripe 2 (empty file)
30358         printf "Seeking hole from 1500000 ... "
30359         offset=$(lseek_test -l 1500000 $file)
30360         echo $offset
30361         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30362         printf "Seeking data from 1500000 ... "
30363         offset=$(lseek_test -d 1500000 $file)
30364         echo $offset
30365         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30366
30367         # start at second component stripe 1 (all data)
30368         printf "Seeking hole from 3000000 ... "
30369         offset=$(lseek_test -l 3000000 $file)
30370         echo $offset
30371         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30372         printf "Seeking data from 3000000 ... "
30373         offset=$(lseek_test -d 3000000 $file)
30374         echo $offset
30375         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30376
30377         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30378                 error "2nd dd fails"
30379         echo "Add data block at 640K...1280K"
30380
30381         # start at before new data block, in hole
30382         printf "Seeking hole from 600000 ... "
30383         offset=$(lseek_test -l 600000 $file)
30384         echo $offset
30385         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30386         printf "Seeking data from 600000 ... "
30387         offset=$(lseek_test -d 600000 $file)
30388         echo $offset
30389         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30390
30391         # start at the first component new data block
30392         printf "Seeking hole from 1000000 ... "
30393         offset=$(lseek_test -l 1000000 $file)
30394         echo $offset
30395         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30396         printf "Seeking data from 1000000 ... "
30397         offset=$(lseek_test -d 1000000 $file)
30398         echo $offset
30399         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30400
30401         # start at second component stripe 2, new data
30402         printf "Seeking hole from 1200000 ... "
30403         offset=$(lseek_test -l 1200000 $file)
30404         echo $offset
30405         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30406         printf "Seeking data from 1200000 ... "
30407         offset=$(lseek_test -d 1200000 $file)
30408         echo $offset
30409         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30410
30411         # start beyond file end
30412         printf "Using offset > filesize ... "
30413         lseek_test -l 4000000 $file && error "lseek should fail"
30414         printf "Using offset > filesize ... "
30415         lseek_test -d 4000000 $file && error "lseek should fail"
30416
30417         printf "Done\n\n"
30418 }
30419
30420 test_430a() {
30421         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30422                 skip "MDT does not support SEEK_HOLE"
30423
30424         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30425                 skip "OST does not support SEEK_HOLE"
30426
30427         local file=$DIR/$tdir/$tfile
30428
30429         mkdir -p $DIR/$tdir
30430
30431         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30432         # OST stripe #1 will have continuous data at [1M, 3M)
30433         # OST stripe #2 is empty
30434         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30435         lseek_test_430 $file
30436         rm $file
30437         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30438         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30439         lseek_test_430 $file
30440         rm $file
30441         $LFS setstripe -c2 -S 512K $file
30442         echo "Two stripes, stripe size 512K"
30443         lseek_test_430 $file
30444         rm $file
30445         # FLR with stale mirror
30446         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30447                        -N -c2 -S 1M $file
30448         echo "Mirrored file:"
30449         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30450         echo "Plain 2 stripes 1M"
30451         lseek_test_430 $file
30452         rm $file
30453 }
30454 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30455
30456 test_430b() {
30457         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30458                 skip "OST does not support SEEK_HOLE"
30459
30460         local offset
30461         local file=$DIR/$tdir/$tfile
30462
30463         mkdir -p $DIR/$tdir
30464         # Empty layout lseek should fail
30465         $MCREATE $file
30466         # seek from 0
30467         printf "Seeking hole from 0 ... "
30468         lseek_test -l 0 $file && error "lseek should fail"
30469         printf "Seeking data from 0 ... "
30470         lseek_test -d 0 $file && error "lseek should fail"
30471         rm $file
30472
30473         # 1M-hole file
30474         $LFS setstripe -E 1M -c2 -E eof $file
30475         $TRUNCATE $file 1048576
30476         printf "Seeking hole from 1000000 ... "
30477         offset=$(lseek_test -l 1000000 $file)
30478         echo $offset
30479         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30480         printf "Seeking data from 1000000 ... "
30481         lseek_test -d 1000000 $file && error "lseek should fail"
30482         rm $file
30483
30484         # full component followed by non-inited one
30485         $LFS setstripe -E 1M -c2 -E eof $file
30486         dd if=/dev/urandom of=$file bs=1M count=1
30487         printf "Seeking hole from 1000000 ... "
30488         offset=$(lseek_test -l 1000000 $file)
30489         echo $offset
30490         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30491         printf "Seeking hole from 1048576 ... "
30492         lseek_test -l 1048576 $file && error "lseek should fail"
30493         # init second component and truncate back
30494         echo "123" >> $file
30495         $TRUNCATE $file 1048576
30496         printf "Seeking hole from 1000000 ... "
30497         offset=$(lseek_test -l 1000000 $file)
30498         echo $offset
30499         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30500         printf "Seeking hole from 1048576 ... "
30501         lseek_test -l 1048576 $file && error "lseek should fail"
30502         # boundary checks for big values
30503         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30504         offset=$(lseek_test -d 0 $file.10g)
30505         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30506         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30507         offset=$(lseek_test -d 0 $file.100g)
30508         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30509         return 0
30510 }
30511 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30512
30513 test_430c() {
30514         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30515                 skip "OST does not support SEEK_HOLE"
30516
30517         local file=$DIR/$tdir/$tfile
30518         local start
30519
30520         mkdir -p $DIR/$tdir
30521         stack_trap "rm -f $file $file.tmp"
30522         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30523
30524         # cp version 8.33+ prefers lseek over fiemap
30525         local ver=$(cp --version | awk '{ print $4; exit; }')
30526
30527         echo "cp $ver installed"
30528         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30529                 start=$SECONDS
30530                 time cp -v $file $file.tmp || error "cp $file failed"
30531                 (( SECONDS - start < 5 )) || {
30532                         strace cp $file $file.tmp |&
30533                                 grep -E "open|read|seek|FIEMAP" |
30534                                 grep -A 100 $file
30535                         error "cp: too long runtime $((SECONDS - start))"
30536                 }
30537         else
30538                 echo "cp test skipped due to $ver < 8.33"
30539         fi
30540
30541         # tar version 1.29+ supports SEEK_HOLE/DATA
30542         ver=$(tar --version | awk '{ print $4; exit; }')
30543         echo "tar $ver installed"
30544         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30545                 start=$SECONDS
30546                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30547                 (( SECONDS - start < 5 )) || {
30548                         strace tar cf $file.tmp --sparse $file |&
30549                                 grep -E "open|read|seek|FIEMAP" |
30550                                 grep -A 100 $file
30551                         error "tar: too long runtime $((SECONDS - start))"
30552                 }
30553         else
30554                 echo "tar test skipped due to $ver < 1.29"
30555         fi
30556 }
30557 run_test 430c "lseek: external tools check"
30558
30559 test_431() { # LU-14187
30560         local file=$DIR/$tdir/$tfile
30561
30562         mkdir -p $DIR/$tdir
30563         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30564         dd if=/dev/urandom of=$file bs=4k count=1
30565         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30566         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30567         #define OBD_FAIL_OST_RESTART_IO 0x251
30568         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30569         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30570         cp $file $file.0
30571         cancel_lru_locks
30572         sync_all_data
30573         echo 3 > /proc/sys/vm/drop_caches
30574         diff  $file $file.0 || error "data diff"
30575 }
30576 run_test 431 "Restart transaction for IO"
30577
30578 cleanup_test_432() {
30579         do_facet mgs $LCTL nodemap_activate 0
30580         wait_nm_sync active
30581 }
30582
30583 test_432() {
30584         local tmpdir=$TMP/dir432
30585
30586         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30587                 skip "Need MDS version at least 2.14.52"
30588
30589         stack_trap cleanup_test_432 EXIT
30590         mkdir $DIR/$tdir
30591         mkdir $tmpdir
30592
30593         do_facet mgs $LCTL nodemap_activate 1
30594         wait_nm_sync active
30595         do_facet mgs $LCTL nodemap_modify --name default \
30596                 --property admin --value 1
30597         do_facet mgs $LCTL nodemap_modify --name default \
30598                 --property trusted --value 1
30599         cancel_lru_locks mdc
30600         wait_nm_sync default admin_nodemap
30601         wait_nm_sync default trusted_nodemap
30602
30603         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30604                grep -ci "Operation not permitted") -ne 0 ]; then
30605                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30606         fi
30607 }
30608 run_test 432 "mv dir from outside Lustre"
30609
30610 test_433() {
30611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30612
30613         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30614                 skip "inode cache not supported"
30615
30616         $LCTL set_param llite.*.inode_cache=0
30617         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30618
30619         local count=256
30620         local before
30621         local after
30622
30623         cancel_lru_locks mdc
30624         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30625         createmany -m $DIR/$tdir/f $count
30626         createmany -d $DIR/$tdir/d $count
30627         ls -l $DIR/$tdir > /dev/null
30628         stack_trap "rm -rf $DIR/$tdir"
30629
30630         before=$(num_objects)
30631         cancel_lru_locks mdc
30632         after=$(num_objects)
30633
30634         # sometimes even @before is less than 2 * count
30635         while (( before - after < count )); do
30636                 sleep 1
30637                 after=$(num_objects)
30638                 wait=$((wait + 1))
30639                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30640                 if (( wait > 60 )); then
30641                         error "inode slab grew from $before to $after"
30642                 fi
30643         done
30644
30645         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30646 }
30647 run_test 433 "ldlm lock cancel releases dentries and inodes"
30648
30649 test_434() {
30650         local file
30651         local getxattr_count
30652         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30653         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30654
30655         [[ $(getenforce) == "Disabled" ]] ||
30656                 skip "lsm selinux module have to be disabled for this test"
30657
30658         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30659                 error "fail to create $DIR/$tdir/ on MDT0000"
30660
30661         touch $DIR/$tdir/$tfile-{001..100}
30662
30663         # disable the xattr cache
30664         save_lustre_params client "llite.*.xattr_cache" > $p
30665         lctl set_param llite.*.xattr_cache=0
30666         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30667
30668         # clear clients mdc stats
30669         clear_stats $mdc_stat_param ||
30670                 error "fail to clear stats on mdc MDT0000"
30671
30672         for file in $DIR/$tdir/$tfile-{001..100}; do
30673                 getfattr -n security.selinux $file |&
30674                         grep -q "Operation not supported" ||
30675                         error "getxattr on security.selinux should return EOPNOTSUPP"
30676         done
30677
30678         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30679         (( getxattr_count < 100 )) ||
30680                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30681 }
30682 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30683
30684 test_440() {
30685         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30686                 source $LUSTRE/scripts/bash-completion/lustre
30687         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30688                 source /usr/share/bash-completion/completions/lustre
30689         else
30690                 skip "bash completion scripts not found"
30691         fi
30692
30693         local lctl_completions
30694         local lfs_completions
30695
30696         lctl_completions=$(_lustre_cmds lctl)
30697         if [[ ! $lctl_completions =~ "get_param" ]]; then
30698                 error "lctl bash completion failed"
30699         fi
30700
30701         lfs_completions=$(_lustre_cmds lfs)
30702         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30703                 error "lfs bash completion failed"
30704         fi
30705 }
30706 run_test 440 "bash completion for lfs, lctl"
30707
30708 test_442() {
30709         local pid1
30710         local pid2
30711         mkdir -p $DIR/$tdir
30712         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30713         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30714         sleep 1
30715         touch $DIR/$tdir/$tfile.2
30716         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30717         $LCTL set_param fail_loc=0x1430
30718         kill -USR1 $pid1
30719         sleep 1
30720         kill -USR1 $pid2
30721         wait
30722 }
30723 run_test 442 "truncate vs read/write should not panic"
30724
30725 test_460d() {
30726         verify_yaml_available || skip_env "YAML verification not installed"
30727         $LCTL get_param -n sptlrpc.page_pools
30728         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30729                 error "The output of encrypt_page_pools is not an valid YAML"
30730 }
30731 run_test 460d "Check encrypt pools output"
30732
30733 prep_801() {
30734         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30735         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30736                 skip "Need server version at least 2.9.55"
30737
30738         start_full_debug_logging
30739 }
30740
30741 post_801() {
30742         stop_full_debug_logging
30743 }
30744
30745 barrier_stat() {
30746         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30747                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30748                            awk '/The barrier for/ { print $7 }')
30749                 echo $st
30750         else
30751                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30752                 echo \'$st\'
30753         fi
30754 }
30755
30756 barrier_expired() {
30757         local expired
30758
30759         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30760                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30761                           awk '/will be expired/ { print $7 }')
30762         else
30763                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30764         fi
30765
30766         echo $expired
30767 }
30768
30769 test_801a() {
30770         prep_801
30771
30772         echo "Start barrier_freeze at: $(date)"
30773         #define OBD_FAIL_BARRIER_DELAY          0x2202
30774         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30775         # Do not reduce barrier time - See LU-11873
30776         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30777
30778         sleep 2
30779         local b_status=$(barrier_stat)
30780         echo "Got barrier status at: $(date)"
30781         [ "$b_status" = "'freezing_p1'" ] ||
30782                 error "(1) unexpected barrier status $b_status"
30783
30784         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30785         wait
30786         b_status=$(barrier_stat)
30787         [ "$b_status" = "'frozen'" ] ||
30788                 error "(2) unexpected barrier status $b_status"
30789
30790         local expired=$(barrier_expired)
30791         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30792         sleep $((expired + 3))
30793
30794         b_status=$(barrier_stat)
30795         [ "$b_status" = "'expired'" ] ||
30796                 error "(3) unexpected barrier status $b_status"
30797
30798         # Do not reduce barrier time - See LU-11873
30799         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30800                 error "(4) fail to freeze barrier"
30801
30802         b_status=$(barrier_stat)
30803         [ "$b_status" = "'frozen'" ] ||
30804                 error "(5) unexpected barrier status $b_status"
30805
30806         echo "Start barrier_thaw at: $(date)"
30807         #define OBD_FAIL_BARRIER_DELAY          0x2202
30808         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30809         do_facet mgs $LCTL barrier_thaw $FSNAME &
30810
30811         sleep 2
30812         b_status=$(barrier_stat)
30813         echo "Got barrier status at: $(date)"
30814         [ "$b_status" = "'thawing'" ] ||
30815                 error "(6) unexpected barrier status $b_status"
30816
30817         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30818         wait
30819         b_status=$(barrier_stat)
30820         [ "$b_status" = "'thawed'" ] ||
30821                 error "(7) unexpected barrier status $b_status"
30822
30823         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30824         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30825         do_facet mgs $LCTL barrier_freeze $FSNAME
30826
30827         b_status=$(barrier_stat)
30828         [ "$b_status" = "'failed'" ] ||
30829                 error "(8) unexpected barrier status $b_status"
30830
30831         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30832         do_facet mgs $LCTL barrier_thaw $FSNAME
30833
30834         post_801
30835 }
30836 run_test 801a "write barrier user interfaces and stat machine"
30837
30838 test_801b() {
30839         prep_801
30840
30841         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30842         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30843         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30844         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30845         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30846
30847         cancel_lru_locks mdc
30848
30849         # 180 seconds should be long enough
30850         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30851
30852         local b_status=$(barrier_stat)
30853         [ "$b_status" = "'frozen'" ] ||
30854                 error "(6) unexpected barrier status $b_status"
30855
30856         mkdir $DIR/$tdir/d0/d10 &
30857         mkdir_pid=$!
30858
30859         touch $DIR/$tdir/d1/f13 &
30860         touch_pid=$!
30861
30862         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30863         ln_pid=$!
30864
30865         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30866         mv_pid=$!
30867
30868         rm -f $DIR/$tdir/d4/f12 &
30869         rm_pid=$!
30870
30871         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30872
30873         # To guarantee taht the 'stat' is not blocked
30874         b_status=$(barrier_stat)
30875         [ "$b_status" = "'frozen'" ] ||
30876                 error "(8) unexpected barrier status $b_status"
30877
30878         # let above commands to run at background
30879         sleep 5
30880
30881         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30882         ps -p $touch_pid || error "(10) touch should be blocked"
30883         ps -p $ln_pid || error "(11) link should be blocked"
30884         ps -p $mv_pid || error "(12) rename should be blocked"
30885         ps -p $rm_pid || error "(13) unlink should be blocked"
30886
30887         b_status=$(barrier_stat)
30888         [ "$b_status" = "'frozen'" ] ||
30889                 error "(14) unexpected barrier status $b_status"
30890
30891         do_facet mgs $LCTL barrier_thaw $FSNAME
30892         b_status=$(barrier_stat)
30893         [ "$b_status" = "'thawed'" ] ||
30894                 error "(15) unexpected barrier status $b_status"
30895
30896         wait $mkdir_pid || error "(16) mkdir should succeed"
30897         wait $touch_pid || error "(17) touch should succeed"
30898         wait $ln_pid || error "(18) link should succeed"
30899         wait $mv_pid || error "(19) rename should succeed"
30900         wait $rm_pid || error "(20) unlink should succeed"
30901
30902         post_801
30903 }
30904 run_test 801b "modification will be blocked by write barrier"
30905
30906 test_801c() {
30907         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30908
30909         prep_801
30910
30911         stop mds2 || error "(1) Fail to stop mds2"
30912
30913         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30914
30915         local b_status=$(barrier_stat)
30916         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30917                 do_facet mgs $LCTL barrier_thaw $FSNAME
30918                 error "(2) unexpected barrier status $b_status"
30919         }
30920
30921         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30922                 error "(3) Fail to rescan barrier bitmap"
30923
30924         # Do not reduce barrier time - See LU-11873
30925         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30926
30927         b_status=$(barrier_stat)
30928         [ "$b_status" = "'frozen'" ] ||
30929                 error "(4) unexpected barrier status $b_status"
30930
30931         do_facet mgs $LCTL barrier_thaw $FSNAME
30932         b_status=$(barrier_stat)
30933         [ "$b_status" = "'thawed'" ] ||
30934                 error "(5) unexpected barrier status $b_status"
30935
30936         local devname=$(mdsdevname 2)
30937
30938         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30939
30940         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30941                 error "(7) Fail to rescan barrier bitmap"
30942
30943         post_801
30944 }
30945 run_test 801c "rescan barrier bitmap"
30946
30947 test_802b() {
30948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30949         remote_mds_nodsh && skip "remote MDS with nodsh"
30950
30951         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30952                 skip "readonly option not available"
30953
30954         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30955
30956         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30957                 error "(2) Fail to copy"
30958
30959         # write back all cached data before setting MDT to readonly
30960         cancel_lru_locks
30961         sync_all_data
30962
30963         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30964         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30965
30966         echo "Modify should be refused"
30967         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30968
30969         echo "Read should be allowed"
30970         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30971                 error "(7) Read should succeed under ro mode"
30972
30973         # disable readonly
30974         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30975 }
30976 run_test 802b "be able to set MDTs to readonly"
30977
30978 test_803a() {
30979         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30980         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30981                 skip "MDS needs to be newer than 2.10.54"
30982
30983         mkdir_on_mdt0 $DIR/$tdir
30984         # Create some objects on all MDTs to trigger related logs objects
30985         for idx in $(seq $MDSCOUNT); do
30986                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30987                         $DIR/$tdir/dir${idx} ||
30988                         error "Fail to create $DIR/$tdir/dir${idx}"
30989         done
30990
30991         wait_delete_completed # ensure old test cleanups are finished
30992         sleep 3
30993         echo "before create:"
30994         $LFS df -i $MOUNT
30995         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30996
30997         for i in {1..10}; do
30998                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30999                         error "Fail to create $DIR/$tdir/foo$i"
31000         done
31001
31002         # sync ZFS-on-MDS to refresh statfs data
31003         wait_zfs_commit mds1
31004         sleep 3
31005         echo "after create:"
31006         $LFS df -i $MOUNT
31007         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31008
31009         # allow for an llog to be cleaned up during the test
31010         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31011                 error "before ($before_used) + 10 > after ($after_used)"
31012
31013         for i in {1..10}; do
31014                 rm -rf $DIR/$tdir/foo$i ||
31015                         error "Fail to remove $DIR/$tdir/foo$i"
31016         done
31017
31018         # sync ZFS-on-MDS to refresh statfs data
31019         wait_zfs_commit mds1
31020         wait_delete_completed
31021         sleep 3 # avoid MDT return cached statfs
31022         echo "after unlink:"
31023         $LFS df -i $MOUNT
31024         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31025
31026         # allow for an llog to be created during the test
31027         [ $after_used -le $((before_used + 1)) ] ||
31028                 error "after ($after_used) > before ($before_used) + 1"
31029 }
31030 run_test 803a "verify agent object for remote object"
31031
31032 test_803b() {
31033         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31034         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31035                 skip "MDS needs to be newer than 2.13.56"
31036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31037
31038         for i in $(seq 0 $((MDSCOUNT - 1))); do
31039                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31040         done
31041
31042         local before=0
31043         local after=0
31044
31045         local tmp
31046
31047         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31048         for i in $(seq 0 $((MDSCOUNT - 1))); do
31049                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31050                         awk '/getattr/ { print $2 }')
31051                 before=$((before + tmp))
31052         done
31053         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31054         for i in $(seq 0 $((MDSCOUNT - 1))); do
31055                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31056                         awk '/getattr/ { print $2 }')
31057                 after=$((after + tmp))
31058         done
31059
31060         [ $before -eq $after ] || error "getattr count $before != $after"
31061 }
31062 run_test 803b "remote object can getattr from cache"
31063
31064 test_804() {
31065         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31066         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31067                 skip "MDS needs to be newer than 2.10.54"
31068         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31069
31070         mkdir -p $DIR/$tdir
31071         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31072                 error "Fail to create $DIR/$tdir/dir0"
31073
31074         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31075         local dev=$(mdsdevname 2)
31076
31077         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31078                 grep ${fid} || error "NOT found agent entry for dir0"
31079
31080         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31081                 error "Fail to create $DIR/$tdir/dir1"
31082
31083         touch $DIR/$tdir/dir1/foo0 ||
31084                 error "Fail to create $DIR/$tdir/dir1/foo0"
31085         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31086         local rc=0
31087
31088         for idx in $(seq $MDSCOUNT); do
31089                 dev=$(mdsdevname $idx)
31090                 do_facet mds${idx} \
31091                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31092                         grep ${fid} && rc=$idx
31093         done
31094
31095         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31096                 error "Fail to rename foo0 to foo1"
31097         if [ $rc -eq 0 ]; then
31098                 for idx in $(seq $MDSCOUNT); do
31099                         dev=$(mdsdevname $idx)
31100                         do_facet mds${idx} \
31101                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31102                         grep ${fid} && rc=$idx
31103                 done
31104         fi
31105
31106         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31107                 error "Fail to rename foo1 to foo2"
31108         if [ $rc -eq 0 ]; then
31109                 for idx in $(seq $MDSCOUNT); do
31110                         dev=$(mdsdevname $idx)
31111                         do_facet mds${idx} \
31112                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31113                         grep ${fid} && rc=$idx
31114                 done
31115         fi
31116
31117         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31118
31119         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31120                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31121         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31122                 error "Fail to rename foo2 to foo0"
31123         unlink $DIR/$tdir/dir1/foo0 ||
31124                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31125         rm -rf $DIR/$tdir/dir0 ||
31126                 error "Fail to rm $DIR/$tdir/dir0"
31127
31128         for idx in $(seq $MDSCOUNT); do
31129                 rc=0
31130
31131                 stop mds${idx}
31132                 dev=$(mdsdevname $idx)
31133                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31134                         rc=$?
31135                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31136                         error "mount mds$idx failed"
31137                 df $MOUNT > /dev/null 2>&1
31138
31139                 # e2fsck should not return error
31140                 [ $rc -eq 0 ] ||
31141                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31142         done
31143 }
31144 run_test 804 "verify agent entry for remote entry"
31145
31146 cleanup_805() {
31147         do_facet $SINGLEMDS zfs set quota=$old $fsset
31148         unlinkmany $DIR/$tdir/f- 1000000
31149         trap 0
31150 }
31151
31152 test_805() {
31153         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31154         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31155         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31156                 skip "netfree not implemented before 0.7"
31157         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31158                 skip "Need MDS version at least 2.10.57"
31159
31160         local fsset
31161         local freekb
31162         local usedkb
31163         local old
31164         local quota
31165         local pref="osd-zfs.$FSNAME-MDT0000."
31166
31167         # limit available space on MDS dataset to meet nospace issue
31168         # quickly. then ZFS 0.7.2 can use reserved space if asked
31169         # properly (using netfree flag in osd_declare_destroy()
31170         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31171         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31172                 gawk '{print $3}')
31173         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31174         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31175         let "usedkb=usedkb-freekb"
31176         let "freekb=freekb/2"
31177         if let "freekb > 5000"; then
31178                 let "freekb=5000"
31179         fi
31180         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31181         trap cleanup_805 EXIT
31182         mkdir_on_mdt0 $DIR/$tdir
31183         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31184                 error "Can't set PFL layout"
31185         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31186         rm -rf $DIR/$tdir || error "not able to remove"
31187         do_facet $SINGLEMDS zfs set quota=$old $fsset
31188         trap 0
31189 }
31190 run_test 805 "ZFS can remove from full fs"
31191
31192 # Size-on-MDS test
31193 check_lsom_data()
31194 {
31195         local file=$1
31196         local expect=$(stat -c %s $file)
31197
31198         check_lsom_size $1 $expect
31199
31200         local blocks=$($LFS getsom -b $file)
31201         expect=$(stat -c %b $file)
31202         [[ $blocks == $expect ]] ||
31203                 error "$file expected blocks: $expect, got: $blocks"
31204 }
31205
31206 check_lsom_size()
31207 {
31208         local size
31209         local expect=$2
31210
31211         cancel_lru_locks mdc
31212
31213         size=$($LFS getsom -s $1)
31214         [[ $size == $expect ]] ||
31215                 error "$file expected size: $expect, got: $size"
31216 }
31217
31218 test_806() {
31219         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31220                 skip "Need MDS version at least 2.11.52"
31221
31222         local bs=1048576
31223
31224         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31225
31226         disable_opencache
31227         stack_trap "restore_opencache"
31228
31229         # single-threaded write
31230         echo "Test SOM for single-threaded write"
31231         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31232                 error "write $tfile failed"
31233         check_lsom_size $DIR/$tfile $bs
31234
31235         local num=32
31236         local size=$(($num * $bs))
31237         local offset=0
31238         local i
31239
31240         echo "Test SOM for single client multi-threaded($num) write"
31241         $TRUNCATE $DIR/$tfile 0
31242         for ((i = 0; i < $num; i++)); do
31243                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31244                 local pids[$i]=$!
31245                 offset=$((offset + $bs))
31246         done
31247         for (( i=0; i < $num; i++ )); do
31248                 wait ${pids[$i]}
31249         done
31250         check_lsom_size $DIR/$tfile $size
31251
31252         $TRUNCATE $DIR/$tfile 0
31253         for ((i = 0; i < $num; i++)); do
31254                 offset=$((offset - $bs))
31255                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31256                 local pids[$i]=$!
31257         done
31258         for (( i=0; i < $num; i++ )); do
31259                 wait ${pids[$i]}
31260         done
31261         check_lsom_size $DIR/$tfile $size
31262
31263         # multi-client writes
31264         num=$(get_node_count ${CLIENTS//,/ })
31265         size=$(($num * $bs))
31266         offset=0
31267         i=0
31268
31269         echo "Test SOM for multi-client ($num) writes"
31270         $TRUNCATE $DIR/$tfile 0
31271         for client in ${CLIENTS//,/ }; do
31272                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31273                 local pids[$i]=$!
31274                 i=$((i + 1))
31275                 offset=$((offset + $bs))
31276         done
31277         for (( i=0; i < $num; i++ )); do
31278                 wait ${pids[$i]}
31279         done
31280         check_lsom_size $DIR/$tfile $offset
31281
31282         i=0
31283         $TRUNCATE $DIR/$tfile 0
31284         for client in ${CLIENTS//,/ }; do
31285                 offset=$((offset - $bs))
31286                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31287                 local pids[$i]=$!
31288                 i=$((i + 1))
31289         done
31290         for (( i=0; i < $num; i++ )); do
31291                 wait ${pids[$i]}
31292         done
31293         check_lsom_size $DIR/$tfile $size
31294
31295         # verify SOM blocks count
31296         echo "Verify SOM block count"
31297         $TRUNCATE $DIR/$tfile 0
31298         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31299                 error "failed to write file $tfile with fdatasync and fstat"
31300         check_lsom_data $DIR/$tfile
31301
31302         $TRUNCATE $DIR/$tfile 0
31303         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31304                 error "failed to write file $tfile with fdatasync"
31305         check_lsom_data $DIR/$tfile
31306
31307         $TRUNCATE $DIR/$tfile 0
31308         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31309                 error "failed to write file $tfile with sync IO"
31310         check_lsom_data $DIR/$tfile
31311
31312         # verify truncate
31313         echo "Test SOM for truncate"
31314         # use ftruncate to sync blocks on close request
31315         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31316         check_lsom_size $DIR/$tfile 16384
31317         check_lsom_data $DIR/$tfile
31318
31319         $TRUNCATE $DIR/$tfile 1234
31320         check_lsom_size $DIR/$tfile 1234
31321         # sync blocks on the MDT
31322         $MULTIOP $DIR/$tfile oc
31323         check_lsom_data $DIR/$tfile
31324 }
31325 run_test 806 "Verify Lazy Size on MDS"
31326
31327 test_807() {
31328         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31329         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31330                 skip "Need MDS version at least 2.11.52"
31331
31332         # Registration step
31333         changelog_register || error "changelog_register failed"
31334         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31335         changelog_users $SINGLEMDS | grep -q $cl_user ||
31336                 error "User $cl_user not found in changelog_users"
31337
31338         rm -rf $DIR/$tdir || error "rm $tdir failed"
31339         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31340         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31341         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31342         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31343                 error "truncate $tdir/trunc failed"
31344
31345         local bs=1048576
31346         echo "Test SOM for single-threaded write with fsync"
31347         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31348                 error "write $tfile failed"
31349         sync;sync;sync
31350
31351         # multi-client wirtes
31352         local num=$(get_node_count ${CLIENTS//,/ })
31353         local offset=0
31354         local i=0
31355
31356         echo "Test SOM for multi-client ($num) writes"
31357         touch $DIR/$tfile || error "touch $tfile failed"
31358         $TRUNCATE $DIR/$tfile 0
31359         for client in ${CLIENTS//,/ }; do
31360                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31361                 local pids[$i]=$!
31362                 i=$((i + 1))
31363                 offset=$((offset + $bs))
31364         done
31365         for (( i=0; i < $num; i++ )); do
31366                 wait ${pids[$i]}
31367         done
31368
31369         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31370         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31371         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31372         check_lsom_data $DIR/$tdir/trunc
31373         check_lsom_data $DIR/$tdir/single_dd
31374         check_lsom_data $DIR/$tfile
31375
31376         rm -rf $DIR/$tdir
31377         # Deregistration step
31378         changelog_deregister || error "changelog_deregister failed"
31379 }
31380 run_test 807 "verify LSOM syncing tool"
31381
31382 check_som_nologged()
31383 {
31384         local lines=$($LFS changelog $FSNAME-MDT0000 |
31385                 grep 'x=trusted.som' | wc -l)
31386         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31387 }
31388
31389 test_808() {
31390         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31391                 skip "Need MDS version at least 2.11.55"
31392
31393         # Registration step
31394         changelog_register || error "changelog_register failed"
31395
31396         touch $DIR/$tfile || error "touch $tfile failed"
31397         check_som_nologged
31398
31399         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31400                 error "write $tfile failed"
31401         check_som_nologged
31402
31403         $TRUNCATE $DIR/$tfile 1234
31404         check_som_nologged
31405
31406         $TRUNCATE $DIR/$tfile 1048576
31407         check_som_nologged
31408
31409         # Deregistration step
31410         changelog_deregister || error "changelog_deregister failed"
31411 }
31412 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31413
31414 check_som_nodata()
31415 {
31416         $LFS getsom $1
31417         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31418 }
31419
31420 test_809() {
31421         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31422                 skip "Need MDS version at least 2.11.56"
31423
31424         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31425                 error "failed to create DoM-only file $DIR/$tfile"
31426         touch $DIR/$tfile || error "touch $tfile failed"
31427         check_som_nodata $DIR/$tfile
31428
31429         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31430                 error "write $tfile failed"
31431         check_som_nodata $DIR/$tfile
31432
31433         $TRUNCATE $DIR/$tfile 1234
31434         check_som_nodata $DIR/$tfile
31435
31436         $TRUNCATE $DIR/$tfile 4097
31437         check_som_nodata $DIR/$file
31438 }
31439 run_test 809 "Verify no SOM xattr store for DoM-only files"
31440
31441 test_810() {
31442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31443         $GSS && skip_env "could not run with gss"
31444         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31445                 skip "OST < 2.12.58 doesn't align checksum"
31446
31447         set_checksums 1
31448         stack_trap "set_checksums $ORIG_CSUM" EXIT
31449         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31450
31451         local csum
31452         local before
31453         local after
31454         for csum in $CKSUM_TYPES; do
31455                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31456                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31457                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31458                         eval set -- $i
31459                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31460                         before=$(md5sum $DIR/$tfile)
31461                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31462                         after=$(md5sum $DIR/$tfile)
31463                         [ "$before" == "$after" ] ||
31464                                 error "$csum: $before != $after bs=$1 seek=$2"
31465                 done
31466         done
31467 }
31468 run_test 810 "partial page writes on ZFS (LU-11663)"
31469
31470 test_812a() {
31471         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31472                 skip "OST < 2.12.51 doesn't support this fail_loc"
31473         local old
31474
31475         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31476         $LCTL set_param osc.*.idle_timeout=10
31477         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31478
31479         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31480         # ensure ost1 is connected
31481         stat $DIR/$tfile >/dev/null || error "can't stat"
31482         wait_osc_import_state client ost1 FULL
31483         # no locks, no reqs to let the connection idle
31484         cancel_lru_locks osc
31485
31486         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31487 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31488         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31489         wait_osc_import_state client ost1 CONNECTING
31490         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31491
31492         stat $DIR/$tfile >/dev/null || error "can't stat file"
31493 }
31494 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31495
31496 test_812b() { # LU-12378
31497         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31498                 skip "OST < 2.12.51 doesn't support this fail_loc"
31499         local old
31500
31501         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31502         $LCTL set_param osc.*.idle_timeout=10
31503         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31504
31505         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31506         # ensure ost1 is connected
31507         stat $DIR/$tfile >/dev/null || error "can't stat"
31508         wait_osc_import_state client ost1 FULL
31509         # no locks, no reqs to let the connection idle
31510         cancel_lru_locks osc
31511
31512         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31513 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31514         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31515         wait_osc_import_state client ost1 CONNECTING
31516         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31517
31518         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31519         wait_osc_import_state client ost1 IDLE
31520 }
31521 run_test 812b "do not drop no resend request for idle connect"
31522
31523 test_812c() {
31524         local old
31525
31526         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31527
31528         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31529         $LFS getstripe $DIR/$tfile
31530         $LCTL set_param osc.*.idle_timeout=10
31531         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31532         # ensure ost1 is connected
31533         stat $DIR/$tfile >/dev/null || error "can't stat"
31534         wait_osc_import_state client ost1 FULL
31535         # no locks, no reqs to let the connection idle
31536         cancel_lru_locks osc
31537
31538 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31539         $LCTL set_param fail_loc=0x80000533
31540         sleep 15
31541         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31542 }
31543 run_test 812c "idle import vs lock enqueue race"
31544
31545 test_813() {
31546         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31547         [ -z "$file_heat_sav" ] && skip "no file heat support"
31548
31549         local readsample
31550         local writesample
31551         local readbyte
31552         local writebyte
31553         local readsample1
31554         local writesample1
31555         local readbyte1
31556         local writebyte1
31557
31558         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31559         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31560
31561         $LCTL set_param -n llite.*.file_heat=1
31562         echo "Turn on file heat"
31563         echo "Period second: $period_second, Decay percentage: $decay_pct"
31564
31565         echo "QQQQ" > $DIR/$tfile
31566         echo "QQQQ" > $DIR/$tfile
31567         echo "QQQQ" > $DIR/$tfile
31568         cat $DIR/$tfile > /dev/null
31569         cat $DIR/$tfile > /dev/null
31570         cat $DIR/$tfile > /dev/null
31571         cat $DIR/$tfile > /dev/null
31572
31573         local out=$($LFS heat_get $DIR/$tfile)
31574
31575         $LFS heat_get $DIR/$tfile
31576         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31577         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31578         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31579         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31580
31581         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31582         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31583         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31584         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31585
31586         sleep $((period_second + 3))
31587         echo "Sleep $((period_second + 3)) seconds..."
31588         # The recursion formula to calculate the heat of the file f is as
31589         # follow:
31590         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31591         # Where Hi is the heat value in the period between time points i*I and
31592         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31593         # to the weight of Ci.
31594         out=$($LFS heat_get $DIR/$tfile)
31595         $LFS heat_get $DIR/$tfile
31596         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31597         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31598         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31599         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31600
31601         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31602                 error "read sample ($readsample) is wrong"
31603         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31604                 error "write sample ($writesample) is wrong"
31605         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31606                 error "read bytes ($readbyte) is wrong"
31607         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31608                 error "write bytes ($writebyte) is wrong"
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         sleep $((period_second + 3))
31619         echo "Sleep $((period_second + 3)) seconds..."
31620
31621         out=$($LFS heat_get $DIR/$tfile)
31622         $LFS heat_get $DIR/$tfile
31623         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31624         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31625         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31626         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31627
31628         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31629                 4 * $decay_pct) / 100") -eq 1 ] ||
31630                 error "read sample ($readsample1) is wrong"
31631         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31632                 3 * $decay_pct) / 100") -eq 1 ] ||
31633                 error "write sample ($writesample1) is wrong"
31634         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31635                 20 * $decay_pct) / 100") -eq 1 ] ||
31636                 error "read bytes ($readbyte1) is wrong"
31637         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31638                 15 * $decay_pct) / 100") -eq 1 ] ||
31639                 error "write bytes ($writebyte1) is wrong"
31640
31641         echo "Turn off file heat for the file $DIR/$tfile"
31642         $LFS heat_set -o $DIR/$tfile
31643
31644         echo "QQQQ" > $DIR/$tfile
31645         echo "QQQQ" > $DIR/$tfile
31646         echo "QQQQ" > $DIR/$tfile
31647         cat $DIR/$tfile > /dev/null
31648         cat $DIR/$tfile > /dev/null
31649         cat $DIR/$tfile > /dev/null
31650         cat $DIR/$tfile > /dev/null
31651
31652         out=$($LFS heat_get $DIR/$tfile)
31653         $LFS heat_get $DIR/$tfile
31654         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31655         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31656         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31657         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31658
31659         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31660         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31661         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31662         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31663
31664         echo "Trun on file heat for the file $DIR/$tfile"
31665         $LFS heat_set -O $DIR/$tfile
31666
31667         echo "QQQQ" > $DIR/$tfile
31668         echo "QQQQ" > $DIR/$tfile
31669         echo "QQQQ" > $DIR/$tfile
31670         cat $DIR/$tfile > /dev/null
31671         cat $DIR/$tfile > /dev/null
31672         cat $DIR/$tfile > /dev/null
31673         cat $DIR/$tfile > /dev/null
31674
31675         out=$($LFS heat_get $DIR/$tfile)
31676         $LFS heat_get $DIR/$tfile
31677         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31678         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31679         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31680         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31681
31682         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31683         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31684         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31685         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31686
31687         $LFS heat_set -c $DIR/$tfile
31688         $LCTL set_param -n llite.*.file_heat=0
31689         echo "Turn off file heat support for the Lustre filesystem"
31690
31691         echo "QQQQ" > $DIR/$tfile
31692         echo "QQQQ" > $DIR/$tfile
31693         echo "QQQQ" > $DIR/$tfile
31694         cat $DIR/$tfile > /dev/null
31695         cat $DIR/$tfile > /dev/null
31696         cat $DIR/$tfile > /dev/null
31697         cat $DIR/$tfile > /dev/null
31698
31699         out=$($LFS heat_get $DIR/$tfile)
31700         $LFS heat_get $DIR/$tfile
31701         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31702         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31703         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31704         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31705
31706         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31707         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31708         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31709         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31710
31711         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31712         rm -f $DIR/$tfile
31713 }
31714 run_test 813 "File heat verfication"
31715
31716 test_814()
31717 {
31718         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31719         echo -n y >> $DIR/$tfile
31720         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31721         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31722 }
31723 run_test 814 "sparse cp works as expected (LU-12361)"
31724
31725 test_815()
31726 {
31727         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31728         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31729 }
31730 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31731
31732 test_816() {
31733         local ost1_imp=$(get_osc_import_name client ost1)
31734         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31735                          cut -d'.' -f2)
31736         local old
31737
31738         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31739         $LCTL set_param osc.*.idle_timeout=10
31740         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31741
31742         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31743         # ensure ost1 is connected
31744
31745         stat $DIR/$tfile >/dev/null || error "can't stat"
31746         wait_osc_import_state client ost1 FULL
31747         # no locks, no reqs to let the connection idle
31748         cancel_lru_locks osc
31749         lru_resize_disable osc
31750         local before
31751         local now
31752         before=$($LCTL get_param -n \
31753                  ldlm.namespaces.$imp_name.lru_size)
31754
31755         wait_osc_import_state client ost1 IDLE
31756         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31757         now=$($LCTL get_param -n \
31758               ldlm.namespaces.$imp_name.lru_size)
31759         [ $before == $now ] || error "lru_size changed $before != $now"
31760 }
31761 run_test 816 "do not reset lru_resize on idle reconnect"
31762
31763 cleanup_817() {
31764         umount $tmpdir
31765         exportfs -u localhost:$DIR/nfsexp
31766         rm -rf $DIR/nfsexp
31767 }
31768
31769 test_817() {
31770         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31771
31772         mkdir -p $DIR/nfsexp
31773         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31774                 error "failed to export nfs"
31775
31776         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31777         stack_trap cleanup_817 EXIT
31778
31779         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31780                 error "failed to mount nfs to $tmpdir"
31781
31782         cp /bin/true $tmpdir
31783         $DIR/nfsexp/true || error "failed to execute 'true' command"
31784 }
31785 run_test 817 "nfsd won't cache write lock for exec file"
31786
31787 test_818() {
31788         test_mkdir -i0 -c1 $DIR/$tdir
31789         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31790         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31791         stop $SINGLEMDS
31792
31793         # restore osp-syn threads
31794         stack_trap "fail $SINGLEMDS"
31795
31796         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31797         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31798         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31799                 error "start $SINGLEMDS failed"
31800         rm -rf $DIR/$tdir
31801
31802         local testid=$(echo $TESTNAME | tr '_' ' ')
31803
31804         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31805                 grep "run LFSCK" || error "run LFSCK is not suggested"
31806 }
31807 run_test 818 "unlink with failed llog"
31808
31809 test_819a() {
31810         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31811         cancel_lru_locks osc
31812         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31813         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31814         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31815         rm -f $TDIR/$tfile
31816 }
31817 run_test 819a "too big niobuf in read"
31818
31819 test_819b() {
31820         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31821         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31822         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31823         cancel_lru_locks osc
31824         sleep 1
31825         rm -f $TDIR/$tfile
31826 }
31827 run_test 819b "too big niobuf in write"
31828
31829
31830 function test_820_start_ost() {
31831         sleep 5
31832
31833         for num in $(seq $OSTCOUNT); do
31834                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31835         done
31836 }
31837
31838 test_820() {
31839         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31840
31841         mkdir $DIR/$tdir
31842         umount_client $MOUNT || error "umount failed"
31843         for num in $(seq $OSTCOUNT); do
31844                 stop ost$num
31845         done
31846
31847         # mount client with no active OSTs
31848         # so that the client can't initialize max LOV EA size
31849         # from OSC notifications
31850         mount_client $MOUNT || error "mount failed"
31851         # delay OST starting to keep this 0 max EA size for a while
31852         test_820_start_ost &
31853
31854         # create a directory on MDS2
31855         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31856                 error "Failed to create directory"
31857         # open intent should update default EA size
31858         # see mdc_update_max_ea_from_body()
31859         # notice this is the very first RPC to MDS2
31860         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31861         ret=$?
31862         echo $out
31863         # With SSK, this situation can lead to -EPERM being returned.
31864         # In that case, simply retry.
31865         if [ $ret -ne 0 ] && $SHARED_KEY; then
31866                 if echo "$out" | grep -q "not permitted"; then
31867                         cp /etc/services $DIR/$tdir/mds2
31868                         ret=$?
31869                 fi
31870         fi
31871         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31872 }
31873 run_test 820 "update max EA from open intent"
31874
31875 test_823() {
31876         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31877         local OST_MAX_PRECREATE=20000
31878
31879         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31880                 skip "Need MDS version at least 2.14.56"
31881
31882         save_lustre_params mds1 \
31883                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31884         do_facet $SINGLEMDS "$LCTL set_param -n \
31885                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31886         do_facet $SINGLEMDS "$LCTL set_param -n \
31887                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31888
31889         stack_trap "restore_lustre_params < $p; rm $p"
31890
31891         do_facet $SINGLEMDS "$LCTL set_param -n \
31892                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31893
31894         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31895                       osp.$FSNAME-OST0000*MDT0000.create_count")
31896         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31897                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31898         local expect_count=$(((($max/2)/256) * 256))
31899
31900         log "setting create_count to 100200:"
31901         log " -result- count: $count with max: $max, expecting: $expect_count"
31902
31903         [[ $count -eq expect_count ]] ||
31904                 error "Create count not set to max precreate."
31905 }
31906 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31907
31908 test_831() {
31909         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31910                 skip "Need MDS version 2.14.56"
31911
31912         local sync_changes=$(do_facet $SINGLEMDS \
31913                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31914
31915         [ "$sync_changes" -gt 100 ] &&
31916                 skip "Sync changes $sync_changes > 100 already"
31917
31918         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31919
31920         $LFS mkdir -i 0 $DIR/$tdir
31921         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31922
31923         save_lustre_params mds1 \
31924                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31925         save_lustre_params mds1 \
31926                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31927
31928         do_facet mds1 "$LCTL set_param -n \
31929                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31930                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31931         stack_trap "restore_lustre_params < $p" EXIT
31932
31933         createmany -o $DIR/$tdir/f- 1000
31934         unlinkmany $DIR/$tdir/f- 1000 &
31935         local UNLINK_PID=$!
31936
31937         while sleep 1; do
31938                 sync_changes=$(do_facet mds1 \
31939                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31940                 # the check in the code is racy, fail the test
31941                 # if the value above the limit by 10.
31942                 [ $sync_changes -gt 110 ] && {
31943                         kill -2 $UNLINK_PID
31944                         wait
31945                         error "osp changes throttling failed, $sync_changes>110"
31946                 }
31947                 kill -0 $UNLINK_PID 2> /dev/null || break
31948         done
31949         wait
31950 }
31951 run_test 831 "throttling unlink/setattr queuing on OSP"
31952
31953 test_832() {
31954         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31955         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31956                 skip "Need MDS version 2.15.52+"
31957         is_rmentry_supported || skip "rm_entry not supported"
31958
31959         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31960         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31961         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31962                 error "mkdir remote_dir failed"
31963         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31964                 error "mkdir striped_dir failed"
31965         touch $DIR/$tdir/file || error "touch file failed"
31966         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31967         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31968 }
31969 run_test 832 "lfs rm_entry"
31970
31971 test_833() {
31972         local file=$DIR/$tfile
31973
31974         stack_trap "rm -f $file" EXIT
31975         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31976
31977         local wpid
31978         local rpid
31979         local rpid2
31980
31981         # Buffered I/O write
31982         (
31983                 while [ ! -e $DIR/sanity.833.lck ]; do
31984                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31985                                 error "failed to write $file"
31986                         sleep 0.$((RANDOM % 4 + 1))
31987                 done
31988         )&
31989         wpid=$!
31990
31991         # Buffered I/O read
31992         (
31993                 while [ ! -e $DIR/sanity.833.lck ]; do
31994                         dd if=$file of=/dev/null bs=1M count=50 ||
31995                                 error "failed to read $file"
31996                         sleep 0.$((RANDOM % 4 + 1))
31997                 done
31998         )&
31999         rpid=$!
32000
32001         # Direct I/O read
32002         (
32003                 while [ ! -e $DIR/sanity.833.lck ]; do
32004                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32005                                 error "failed to read $file in direct I/O mode"
32006                         sleep 0.$((RANDOM % 4 + 1))
32007                 done
32008         )&
32009         rpid2=$!
32010
32011         sleep 30
32012         touch $DIR/sanity.833.lck
32013         wait $wpid || error "$?: buffered write failed"
32014         wait $rpid || error "$?: buffered read failed"
32015         wait $rpid2 || error "$?: direct read failed"
32016 }
32017 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32018
32019 test_842() {
32020         local oss1=$(facet_host ost1)
32021
32022         # Try to insert the module.  This will leave results in dmesg
32023         now=$(date +%s)
32024         log "STAMP $now" > /dev/kmsg
32025         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32026                 error "$oss1 load_module ldlm_extent failed"
32027
32028         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32029         do_node $oss1 rmmod -v ldlm_extent ||
32030                 error "rmmod failed (may trigger a failure in a later test)"
32031 }
32032 run_test 842 "Measure ldlm_extent performance"
32033
32034 test_850() {
32035         local dir=$DIR/$tdir
32036         local file=$dir/$tfile
32037         local statsfile=$dir/all_job_stats.txt
32038
32039         test_mkdir -p $dir || error "failed to create dir $dir"
32040         echo "abcdefg" > $file || error "failed to create file $file"
32041
32042         # read job_stats in the living system
32043         lljobstat -n 1 ||
32044                 error "failed to run lljobstat on living system"
32045
32046         $LCTL get_param *.*.job_stats > $statsfile
32047         lljobstat --statsfile=$statsfile ||
32048                 error "failed to run lljobstat on file $statsfile"
32049 }
32050 run_test 850 "lljobstat can parse living and aggregated job_stats"
32051
32052 test_851() {
32053         local dir=$DIR/$tdir
32054         local file=$dir/f_test_851_$$
32055         local report=/tmp/report_test_851_$$
32056         local fanotify_prog=monitor_lustrefs
32057         local pid
32058
32059         test_mkdir $dir || error "failed to create dir $dir"
32060
32061         $fanotify_prog $DIR > $report &
32062         pid=$!
32063
32064         sleep 1
32065         if ! kill -0 $pid; then
32066                 error "failed to start $fanoify_prog"
32067         fi
32068
32069         stack_trap "kill $pid"
32070         stack_trap "rm -f $report"
32071
32072         echo "1234567890" > $file
32073         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32074                 error "fanotify did not report anything after 30 seconds"
32075         grep -a -E "open.*:$file:" $report ||
32076                 error "no open event for writing $file"
32077         grep -a -E "write.*:$file:" $report ||
32078                 error "no write event for writing $file"
32079         grep -a -E "close.*:$file:" $report ||
32080                 error "no close event for writing $file"
32081
32082         > $report
32083         cat $file
32084         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32085                 error "fanotify did not report anything after 30 seconds"
32086         grep -a -E "open.*:$file:" $report ||
32087                 error "no open event for reading $file"
32088         grep -a -E "read.*:$file:" $report ||
32089                 error "no write event for reading $file"
32090         grep -a -E "close.*:$file:" $report ||
32091                 error "no close event for reading $file"
32092 }
32093 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32094
32095 #
32096 # tests that do cleanup/setup should be run at the end
32097 #
32098
32099 test_900() {
32100         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32101         local ls
32102
32103         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32104         $LCTL set_param fail_loc=0x903
32105
32106         cancel_lru_locks MGC
32107
32108         FAIL_ON_ERROR=true cleanup
32109         FAIL_ON_ERROR=true setup
32110 }
32111 run_test 900 "umount should not race with any mgc requeue thread"
32112
32113 # LUS-6253/LU-11185
32114 test_901() {
32115         local old
32116         local count
32117         local oldc
32118         local newc
32119         local olds
32120         local news
32121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32122
32123         # some get_param have a bug to handle dot in param name
32124         cancel_lru_locks MGC
32125         old=$(mount -t lustre | wc -l)
32126         # 1 config+sptlrpc
32127         # 2 params
32128         # 3 nodemap
32129         # 4 IR
32130         old=$((old * 4))
32131         oldc=0
32132         count=0
32133         while [ $old -ne $oldc ]; do
32134                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32135                 sleep 1
32136                 ((count++))
32137                 if [ $count -ge $TIMEOUT ]; then
32138                         error "too large timeout"
32139                 fi
32140         done
32141         umount_client $MOUNT || error "umount failed"
32142         mount_client $MOUNT || error "mount failed"
32143         cancel_lru_locks MGC
32144         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32145
32146         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32147
32148         return 0
32149 }
32150 run_test 901 "don't leak a mgc lock on client umount"
32151
32152 # LU-13377
32153 test_902() {
32154         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32155                 skip "client does not have LU-13377 fix"
32156         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32157         $LCTL set_param fail_loc=0x1415
32158         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32159         cancel_lru_locks osc
32160         rm -f $DIR/$tfile
32161 }
32162 run_test 902 "test short write doesn't hang lustre"
32163
32164 # LU-14711
32165 test_903() {
32166         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32167         echo "blah" > $DIR/${tfile}-2
32168         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32169         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32170         $LCTL set_param fail_loc=0x417 fail_val=20
32171
32172         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32173         sleep 1 # To start the destroy
32174         wait_destroy_complete 150 || error "Destroy taking too long"
32175         cat $DIR/$tfile > /dev/null || error "Evicted"
32176 }
32177 run_test 903 "Test long page discard does not cause evictions"
32178
32179 test_904() {
32180         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32181         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32182                 grep -q project || skip "skip project quota not supported"
32183
32184         local testfile="$DIR/$tdir/$tfile"
32185         local xattr="trusted.projid"
32186         local projid
32187         local mdts=$(comma_list $(mdts_nodes))
32188         local saved=$(do_facet mds1 $LCTL get_param -n \
32189                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32190
32191         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32192         stack_trap "do_nodes $mdts $LCTL set_param \
32193                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32194
32195         mkdir -p $DIR/$tdir
32196         touch $testfile
32197         #hide projid xattr on server
32198         $LFS project -p 1 $testfile ||
32199                 error "set $testfile project id failed"
32200         getfattr -m - $testfile | grep $xattr &&
32201                 error "do not show trusted.projid when disabled on server"
32202         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32203         #should be hidden when projid is 0
32204         $LFS project -p 0 $testfile ||
32205                 error "set $testfile project id failed"
32206         getfattr -m - $testfile | grep $xattr &&
32207                 error "do not show trusted.projid with project ID 0"
32208
32209         #still can getxattr explicitly
32210         projid=$(getfattr -n $xattr $testfile |
32211                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32212         [ $projid == "0" ] ||
32213                 error "projid expected 0 not $projid"
32214
32215         #set the projid via setxattr
32216         setfattr -n $xattr -v "1000" $testfile ||
32217                 error "setattr failed with $?"
32218         projid=($($LFS project $testfile))
32219         [ ${projid[0]} == "1000" ] ||
32220                 error "projid expected 1000 not $projid"
32221
32222         #check the new projid via getxattr
32223         $LFS project -p 1001 $testfile ||
32224                 error "set $testfile project id failed"
32225         getfattr -m - $testfile | grep $xattr ||
32226                 error "should show trusted.projid when project ID != 0"
32227         projid=$(getfattr -n $xattr $testfile |
32228                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32229         [ $projid == "1001" ] ||
32230                 error "projid expected 1001 not $projid"
32231
32232         #try to set invalid projid
32233         setfattr -n $xattr -v "4294967295" $testfile &&
32234                 error "set invalid projid should fail"
32235
32236         #remove the xattr means setting projid to 0
32237         setfattr -x $xattr $testfile ||
32238                 error "setfattr failed with $?"
32239         projid=($($LFS project $testfile))
32240         [ ${projid[0]} == "0" ] ||
32241                 error "projid expected 0 not $projid"
32242
32243         #should be hidden when parent has inherit flag and same projid
32244         $LFS project -srp 1002 $DIR/$tdir ||
32245                 error "set $tdir project id failed"
32246         getfattr -m - $testfile | grep $xattr &&
32247                 error "do not show trusted.projid with inherit flag"
32248
32249         #still can getxattr explicitly
32250         projid=$(getfattr -n $xattr $testfile |
32251                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32252         [ $projid == "1002" ] ||
32253                 error "projid expected 1002 not $projid"
32254 }
32255 run_test 904 "virtual project ID xattr"
32256
32257 # LU-8582
32258 test_905() {
32259         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32260                 skip "need OST version >= 2.15.50.220 for fail_loc"
32261
32262         remote_ost_nodsh && skip "remote OST with nodsh"
32263         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32264
32265         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32266
32267         #define OBD_FAIL_OST_OPCODE 0x253
32268         # OST_LADVISE = 21
32269         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32270         $LFS ladvise -a willread $DIR/$tfile &&
32271                 error "unexpected success of ladvise with fault injection"
32272         $LFS ladvise -a willread $DIR/$tfile |&
32273                 grep -q "Operation not supported"
32274         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32275 }
32276 run_test 905 "bad or new opcode should not stuck client"
32277
32278 test_906() {
32279         grep -q io_uring_setup /proc/kallsyms ||
32280                 skip "Client OS does not support io_uring I/O engine"
32281         io_uring_probe || skip "kernel does not support io_uring fully"
32282         which fio || skip_env "no fio installed"
32283         fio --enghelp | grep -q io_uring ||
32284                 skip_env "fio does not support io_uring I/O engine"
32285
32286         local file=$DIR/$tfile
32287         local ioengine="io_uring"
32288         local numjobs=2
32289         local size=50M
32290
32291         fio --name=seqwrite --ioengine=$ioengine        \
32292                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32293                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32294                 error "fio seqwrite $file failed"
32295
32296         fio --name=seqread --ioengine=$ioengine \
32297                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32298                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32299                 error "fio seqread $file failed"
32300
32301         rm -f $file || error "rm -f $file failed"
32302 }
32303 run_test 906 "Simple test for io_uring I/O engine via fio"
32304
32305 test_907() {
32306         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32307
32308         # set stripe size to max rpc size
32309         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32310         $LFS getstripe $DIR/$tfile
32311 #define OBD_FAIL_OST_EROFS               0x216
32312         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32313
32314         local bs=$((max_pages * PAGE_SIZE / 16))
32315
32316         # write full one stripe and one block
32317         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32318
32319         rm $DIR/$tfile || error "rm failed"
32320 }
32321 run_test 907 "write rpc error during unlink"
32322
32323 complete_test $SECONDS
32324 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32325 check_and_cleanup_lustre
32326 if [ "$I_MOUNTED" != "yes" ]; then
32327         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32328 fi
32329 exit_status