Whamcloud - gitweb
LU-17705 ptlrpc: replace synchronize_rcu() with rcu_barrier()
[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         # LU-16904 check if the root is set as PFL layout
10037         local numcomp=$($LFS getstripe --component-count $MOUNT)
10038         [ $numcomp -eq 0 ] || skip "Skip test_65a for PFL layout"
10039
10040         test_mkdir $DIR/$tdir
10041         touch $DIR/$tdir/f1
10042         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
10043 }
10044 run_test 65a "directory with no stripe info"
10045
10046 test_65b() {
10047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10048
10049         test_mkdir $DIR/$tdir
10050         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10051
10052         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10053                                                 error "setstripe"
10054         touch $DIR/$tdir/f2
10055         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
10056 }
10057 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
10058
10059 test_65c() {
10060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10061         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
10062
10063         test_mkdir $DIR/$tdir
10064         local stripesize=$($LFS getstripe -S $DIR/$tdir)
10065
10066         $LFS setstripe -S $((stripesize * 4)) -i 1 \
10067                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
10068         touch $DIR/$tdir/f3
10069         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
10070 }
10071 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10072
10073 test_65d() {
10074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10075
10076         test_mkdir $DIR/$tdir
10077         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10078         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10079
10080         if [[ $STRIPECOUNT -le 0 ]]; then
10081                 sc=1
10082         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10083                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10084                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10085         else
10086                 sc=$(($STRIPECOUNT - 1))
10087         fi
10088         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10089         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10090         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10091                 error "lverify failed"
10092 }
10093 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10094
10095 test_65e() {
10096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10097
10098         # LU-16904 delete layout when root is set as PFL layout
10099         save_layout_restore_at_exit $MOUNT
10100         $LFS setstripe -d $MOUNT || error "setstripe failed"
10101
10102         test_mkdir $DIR/$tdir
10103
10104         $LFS setstripe $DIR/$tdir || error "setstripe"
10105         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10106                                         error "no stripe info failed"
10107         touch $DIR/$tdir/f6
10108         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10109 }
10110 run_test 65e "directory setstripe defaults"
10111
10112 test_65f() {
10113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10114
10115         test_mkdir $DIR/${tdir}f
10116         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10117                 error "setstripe succeeded" || true
10118 }
10119 run_test 65f "dir setstripe permission (should return error) ==="
10120
10121 test_65g() {
10122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10123
10124         # LU-16904 delete layout when root is set as PFL layout
10125         save_layout_restore_at_exit $MOUNT
10126         $LFS setstripe -d $MOUNT || error "setstripe failed"
10127
10128         test_mkdir $DIR/$tdir
10129         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10130
10131         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10132                 error "setstripe -S failed"
10133         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10134         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10135                 error "delete default stripe failed"
10136 }
10137 run_test 65g "directory setstripe -d"
10138
10139 test_65h() {
10140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10141
10142         test_mkdir $DIR/$tdir
10143         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10144
10145         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10146                 error "setstripe -S failed"
10147         test_mkdir $DIR/$tdir/dd1
10148         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10149                 error "stripe info inherit failed"
10150 }
10151 run_test 65h "directory stripe info inherit ===================="
10152
10153 test_65i() {
10154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10155
10156         save_layout_restore_at_exit $MOUNT
10157
10158         # bug6367: set non-default striping on root directory
10159         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10160
10161         # bug12836: getstripe on -1 default directory striping
10162         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10163
10164         # bug12836: getstripe -v on -1 default directory striping
10165         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10166
10167         # bug12836: new find on -1 default directory striping
10168         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10169 }
10170 run_test 65i "various tests to set root directory striping"
10171
10172 test_65j() { # bug6367
10173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10174
10175         sync; sleep 1
10176
10177         # if we aren't already remounting for each test, do so for this test
10178         if [ "$I_MOUNTED" = "yes" ]; then
10179                 cleanup || error "failed to unmount"
10180                 setup
10181         fi
10182
10183         save_layout_restore_at_exit $MOUNT
10184
10185         $LFS setstripe -d $MOUNT || error "setstripe failed"
10186 }
10187 run_test 65j "set default striping on root directory (bug 6367)="
10188
10189 cleanup_65k() {
10190         rm -rf $DIR/$tdir
10191         wait_delete_completed
10192         do_facet $SINGLEMDS "lctl set_param -n \
10193                 osp.$ost*MDT0000.max_create_count=$max_count"
10194         do_facet $SINGLEMDS "lctl set_param -n \
10195                 osp.$ost*MDT0000.create_count=$count"
10196         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10197         echo $INACTIVE_OSC "is Activate"
10198
10199         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10200 }
10201
10202 test_65k() { # bug11679
10203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10204         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10205         remote_mds_nodsh && skip "remote MDS with nodsh"
10206
10207         local disable_precreate=true
10208         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10209                 disable_precreate=false
10210
10211         echo "Check OST status: "
10212         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10213                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10214
10215         for OSC in $MDS_OSCS; do
10216                 echo $OSC "is active"
10217                 do_facet $SINGLEMDS lctl --device %$OSC activate
10218         done
10219
10220         for INACTIVE_OSC in $MDS_OSCS; do
10221                 local ost=$(osc_to_ost $INACTIVE_OSC)
10222                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10223                                lov.*md*.target_obd |
10224                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10225
10226                 mkdir -p $DIR/$tdir
10227                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10228                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10229
10230                 echo "Deactivate: " $INACTIVE_OSC
10231                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10232
10233                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10234                               osp.$ost*MDT0000.create_count")
10235                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10236                                   osp.$ost*MDT0000.max_create_count")
10237                 $disable_precreate &&
10238                         do_facet $SINGLEMDS "lctl set_param -n \
10239                                 osp.$ost*MDT0000.max_create_count=0"
10240
10241                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10242                         [ -f $DIR/$tdir/$idx ] && continue
10243                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10244                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10245                                 { cleanup_65k;
10246                                   error "setstripe $idx should succeed"; }
10247                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10248                 done
10249                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10250                 rmdir $DIR/$tdir
10251
10252                 do_facet $SINGLEMDS "lctl set_param -n \
10253                         osp.$ost*MDT0000.max_create_count=$max_count"
10254                 do_facet $SINGLEMDS "lctl set_param -n \
10255                         osp.$ost*MDT0000.create_count=$count"
10256                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10257                 echo $INACTIVE_OSC "is Activate"
10258
10259                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10260         done
10261 }
10262 run_test 65k "validate manual striping works properly with deactivated OSCs"
10263
10264 test_65l() { # bug 12836
10265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10266
10267         test_mkdir -p $DIR/$tdir/test_dir
10268         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10269         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10270 }
10271 run_test 65l "lfs find on -1 stripe dir ========================"
10272
10273 test_65m() {
10274         local layout=$(save_layout $MOUNT)
10275         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10276                 restore_layout $MOUNT $layout
10277                 error "setstripe should fail by non-root users"
10278         }
10279         true
10280 }
10281 run_test 65m "normal user can't set filesystem default stripe"
10282
10283 test_65n() {
10284         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10285         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10286                 skip "Need MDS version at least 2.12.50"
10287         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10288
10289         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10290         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10291         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10292
10293         save_layout_restore_at_exit $MOUNT
10294
10295         # new subdirectory under root directory should not inherit
10296         # the default layout from root
10297         # LU-16904 check if the root is set as PFL layout
10298         local numcomp=$($LFS getstripe --component-count $MOUNT)
10299
10300         if [[ $numcomp -eq 0 ]]; then
10301                 local dir1=$MOUNT/$tdir-1
10302                 mkdir $dir1 || error "mkdir $dir1 failed"
10303                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10304                         error "$dir1 shouldn't have LOV EA"
10305         fi
10306
10307         # delete the default layout on root directory
10308         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10309
10310         local dir2=$MOUNT/$tdir-2
10311         mkdir $dir2 || error "mkdir $dir2 failed"
10312         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10313                 error "$dir2 shouldn't have LOV EA"
10314
10315         # set a new striping pattern on root directory
10316         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10317         local new_def_stripe_size=$((def_stripe_size * 2))
10318         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10319                 error "set stripe size on $MOUNT failed"
10320
10321         # new file created in $dir2 should inherit the new stripe size from
10322         # the filesystem default
10323         local file2=$dir2/$tfile-2
10324         touch $file2 || error "touch $file2 failed"
10325
10326         local file2_stripe_size=$($LFS getstripe -S $file2)
10327         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10328         {
10329                 echo "file2_stripe_size: '$file2_stripe_size'"
10330                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10331                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10332         }
10333
10334         local dir3=$MOUNT/$tdir-3
10335         mkdir $dir3 || error "mkdir $dir3 failed"
10336         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10337         # the root layout, which is the actual default layout that will be used
10338         # when new files are created in $dir3.
10339         local dir3_layout=$(get_layout_param $dir3)
10340         local root_dir_layout=$(get_layout_param $MOUNT)
10341         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10342         {
10343                 echo "dir3_layout: '$dir3_layout'"
10344                 echo "root_dir_layout: '$root_dir_layout'"
10345                 error "$dir3 should show the default layout from $MOUNT"
10346         }
10347
10348         # set OST pool on root directory
10349         local pool=$TESTNAME
10350         pool_add $pool || error "add $pool failed"
10351         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10352                 error "add targets to $pool failed"
10353
10354         $LFS setstripe -p $pool $MOUNT ||
10355                 error "set OST pool on $MOUNT failed"
10356
10357         # new file created in $dir3 should inherit the pool from
10358         # the filesystem default
10359         local file3=$dir3/$tfile-3
10360         touch $file3 || error "touch $file3 failed"
10361
10362         local file3_pool=$($LFS getstripe -p $file3)
10363         [[ "$file3_pool" = "$pool" ]] ||
10364                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10365
10366         local dir4=$MOUNT/$tdir-4
10367         mkdir $dir4 || error "mkdir $dir4 failed"
10368         local dir4_layout=$(get_layout_param $dir4)
10369         root_dir_layout=$(get_layout_param $MOUNT)
10370         echo "$LFS getstripe -d $dir4"
10371         $LFS getstripe -d $dir4
10372         echo "$LFS getstripe -d $MOUNT"
10373         $LFS getstripe -d $MOUNT
10374         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10375         {
10376                 echo "dir4_layout: '$dir4_layout'"
10377                 echo "root_dir_layout: '$root_dir_layout'"
10378                 error "$dir4 should show the default layout from $MOUNT"
10379         }
10380
10381         # new file created in $dir4 should inherit the pool from
10382         # the filesystem default
10383         local file4=$dir4/$tfile-4
10384         touch $file4 || error "touch $file4 failed"
10385
10386         local file4_pool=$($LFS getstripe -p $file4)
10387         [[ "$file4_pool" = "$pool" ]] ||
10388                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10389
10390         # new subdirectory under non-root directory should inherit
10391         # the default layout from its parent directory
10392         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10393                 error "set directory layout on $dir4 failed"
10394
10395         local dir5=$dir4/$tdir-5
10396         mkdir $dir5 || error "mkdir $dir5 failed"
10397
10398         dir4_layout=$(get_layout_param $dir4)
10399         local dir5_layout=$(get_layout_param $dir5)
10400         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10401         {
10402                 echo "dir4_layout: '$dir4_layout'"
10403                 echo "dir5_layout: '$dir5_layout'"
10404                 error "$dir5 should inherit the default layout from $dir4"
10405         }
10406
10407         # though subdir under ROOT doesn't inherit default layout, but
10408         # its sub dir/file should be created with default layout.
10409         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10410         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10411                 skip "Need MDS version at least 2.12.59"
10412
10413         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10414         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10415         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10416
10417         if [ $default_lmv_hash == "none" ]; then
10418                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10419         else
10420                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10421                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10422         fi
10423
10424         $LFS setdirstripe -D -c 2 $MOUNT ||
10425                 error "setdirstripe -D -c 2 failed"
10426         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10427         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10428         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10429
10430         # $dir4 layout includes pool
10431         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10432         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10433                 error "pool lost on setstripe"
10434         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10435         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10436                 error "pool lost on compound layout setstripe"
10437 }
10438 run_test 65n "don't inherit default layout from root for new subdirectories"
10439
10440 test_65o() {
10441         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10442                 skip "need MDS version at least 2.14.57"
10443
10444         # set OST pool on root directory
10445         local pool=$TESTNAME
10446
10447         pool_add $pool || error "add $pool failed"
10448         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10449                 error "add targets to $pool failed"
10450
10451         local dir1=$MOUNT/$tdir
10452
10453         mkdir $dir1 || error "mkdir $dir1 failed"
10454
10455         # set a new striping pattern on root directory
10456         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10457
10458         $LFS setstripe -p $pool $dir1 ||
10459                 error "set directory layout on $dir1 failed"
10460
10461         # $dir1 layout includes pool
10462         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10463         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10464                 error "pool lost on setstripe"
10465         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10466         $LFS getstripe $dir1
10467         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10468                 error "pool lost on compound layout setstripe"
10469
10470         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10471                 error "setdirstripe failed on sub-dir with inherited pool"
10472         $LFS getstripe $dir1/dir2
10473         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10474                 error "pool lost on compound layout setdirstripe"
10475
10476         $LFS setstripe -E -1 -c 1 $dir1
10477         $LFS getstripe -d $dir1
10478         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10479                 error "pool lost on setstripe"
10480 }
10481 run_test 65o "pool inheritance for mdt component"
10482
10483 test_65p () { # LU-16152
10484         local src_dir=$DIR/$tdir/src_dir
10485         local dst_dir=$DIR/$tdir/dst_dir
10486         local yaml_file=$DIR/$tdir/layout.yaml
10487         local border
10488
10489         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10490                 skip "Need at least version 2.15.51"
10491
10492         test_mkdir -p $src_dir
10493         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10494                 error "failed to setstripe"
10495         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10496                 error "failed to getstripe"
10497
10498         test_mkdir -p $dst_dir
10499         $LFS setstripe --yaml $yaml_file $dst_dir ||
10500                 error "failed to setstripe with yaml file"
10501         border=$($LFS getstripe -d $dst_dir |
10502                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10503                 error "failed to getstripe"
10504
10505         # 2048M is 0x80000000, or 2147483648
10506         (( $border == 2147483648 )) ||
10507                 error "failed to handle huge number in yaml layout"
10508 }
10509 run_test 65p "setstripe with yaml file and huge number"
10510
10511 test_65q () { # LU-16194
10512         local src_dir=$DIR/$tdir/src_dir
10513
10514         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) &&
10515         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
10516                 skip "Need at least version 2.15.51"
10517
10518         test_mkdir -p $src_dir
10519         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10520         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10521                 error "should fail if extent start/end >=8E"
10522
10523         # EOF should work as before
10524         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10525                 error "failed to setstripe normally"
10526 }
10527 run_test 65q "setstripe with >=8E offset should fail"
10528
10529 # bug 2543 - update blocks count on client
10530 test_66() {
10531         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10532
10533         local COUNT=${COUNT:-8}
10534         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10535         sync; sync_all_data; sync; sync_all_data
10536         cancel_lru_locks osc
10537         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10538         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10539 }
10540 run_test 66 "update inode blocks count on client ==============="
10541
10542 meminfo() {
10543         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10544 }
10545
10546 swap_used() {
10547         swapon -s | awk '($1 == "'$1'") { print $4 }'
10548 }
10549
10550 # bug5265, obdfilter oa2dentry return -ENOENT
10551 # #define OBD_FAIL_SRV_ENOENT 0x217
10552 test_69() {
10553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10554         remote_ost_nodsh && skip "remote OST with nodsh"
10555
10556         f="$DIR/$tfile"
10557         $LFS setstripe -c 1 -i 0 $f
10558         stack_trap "rm -f $f ${f}.2"
10559
10560         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10561
10562         do_facet ost1 lctl set_param fail_loc=0x217
10563         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10564         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10565
10566         do_facet ost1 lctl set_param fail_loc=0
10567         $DIRECTIO write $f 0 2 || error "write error"
10568
10569         cancel_lru_locks osc
10570         $DIRECTIO read $f 0 1 || error "read error"
10571
10572         do_facet ost1 lctl set_param fail_loc=0x217
10573         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10574
10575         do_facet ost1 lctl set_param fail_loc=0
10576 }
10577 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10578
10579 test_70a() {
10580         # Perform a really simple test of health write and health check
10581         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10582                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10583
10584         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10585
10586         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10587
10588         # Test with health write off
10589         do_facet ost1 $LCTL set_param enable_health_write off ||
10590                 error "can't set enable_health_write off"
10591         do_facet ost1 $LCTL get_param enable_health_write ||
10592                 error "can't get enable_health_write"
10593
10594         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10595                 error "not healthy (1)"
10596
10597         # Test with health write on
10598         do_facet ost1 $LCTL set_param enable_health_write on ||
10599                 error "can't set enable_health_write on"
10600         do_facet ost1 $LCTL get_param enable_health_write ||
10601                 error "can't get enable_health_write"
10602
10603         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10604                 error "not healthy (2)"
10605 }
10606 run_test 70a "verify health_check, health_write don't explode (on OST)"
10607
10608 test_71() {
10609         test_mkdir $DIR/$tdir
10610         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10611         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10612 }
10613 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10614
10615 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10617         [ "$RUNAS_ID" = "$UID" ] &&
10618                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10619         # Check that testing environment is properly set up. Skip if not
10620         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10621                 skip_env "User $RUNAS_ID does not exist - skipping"
10622
10623         touch $DIR/$tfile
10624         chmod 777 $DIR/$tfile
10625         chmod ug+s $DIR/$tfile
10626         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10627                 error "$RUNAS dd $DIR/$tfile failed"
10628         # See if we are still setuid/sgid
10629         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10630                 error "S/gid is not dropped on write"
10631         # Now test that MDS is updated too
10632         cancel_lru_locks mdc
10633         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10634                 error "S/gid is not dropped on MDS"
10635         rm -f $DIR/$tfile
10636 }
10637 run_test 72a "Test that remove suid works properly (bug5695) ===="
10638
10639 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10640         local perm
10641
10642         [ "$RUNAS_ID" = "$UID" ] &&
10643                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10644         [ "$RUNAS_ID" -eq 0 ] &&
10645                 skip_env "RUNAS_ID = 0 -- skipping"
10646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10647         # Check that testing environment is properly set up. Skip if not
10648         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10649                 skip_env "User $RUNAS_ID does not exist - skipping"
10650
10651         touch $DIR/${tfile}-f{g,u}
10652         test_mkdir $DIR/${tfile}-dg
10653         test_mkdir $DIR/${tfile}-du
10654         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10655         chmod g+s $DIR/${tfile}-{f,d}g
10656         chmod u+s $DIR/${tfile}-{f,d}u
10657         for perm in 777 2777 4777; do
10658                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10659                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10660                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10661                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10662         done
10663         true
10664 }
10665 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10666
10667 # bug 3462 - multiple simultaneous MDC requests
10668 test_73() {
10669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10670
10671         test_mkdir $DIR/d73-1
10672         test_mkdir $DIR/d73-2
10673         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10674         pid1=$!
10675
10676         lctl set_param fail_loc=0x80000129
10677         $MULTIOP $DIR/d73-1/f73-2 Oc &
10678         sleep 1
10679         lctl set_param fail_loc=0
10680
10681         $MULTIOP $DIR/d73-2/f73-3 Oc &
10682         pid3=$!
10683
10684         kill -USR1 $pid1
10685         wait $pid1 || return 1
10686
10687         sleep 25
10688
10689         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10690         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10691         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10692
10693         rm -rf $DIR/d73-*
10694 }
10695 run_test 73 "multiple MDC requests (should not deadlock)"
10696
10697 test_74a() { # bug 6149, 6184
10698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10699
10700         touch $DIR/f74a
10701         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10702         #
10703         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10704         # will spin in a tight reconnection loop
10705         $LCTL set_param fail_loc=0x8000030e
10706         # get any lock that won't be difficult - lookup works.
10707         ls $DIR/f74a
10708         $LCTL set_param fail_loc=0
10709         rm -f $DIR/f74a
10710         true
10711 }
10712 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10713
10714 test_74b() { # bug 13310
10715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10716
10717         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10718         #
10719         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10720         # will spin in a tight reconnection loop
10721         $LCTL set_param fail_loc=0x8000030e
10722         # get a "difficult" lock
10723         touch $DIR/f74b
10724         $LCTL set_param fail_loc=0
10725         rm -f $DIR/f74b
10726         true
10727 }
10728 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10729
10730 test_74c() {
10731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10732
10733         #define OBD_FAIL_LDLM_NEW_LOCK
10734         $LCTL set_param fail_loc=0x319
10735         touch $DIR/$tfile && error "touch successful"
10736         $LCTL set_param fail_loc=0
10737         true
10738 }
10739 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10740
10741 slab_lic=/sys/kernel/slab/lustre_inode_cache
10742 num_objects() {
10743         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10744         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10745                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10746 }
10747
10748 test_76a() { # Now for b=20433, added originally in b=1443
10749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10750
10751         cancel_lru_locks osc
10752         # there may be some slab objects cached per core
10753         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10754         local before=$(num_objects)
10755         local count=$((512 * cpus))
10756         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10757         local margin=$((count / 10))
10758         if [[ -f $slab_lic/aliases ]]; then
10759                 local aliases=$(cat $slab_lic/aliases)
10760                 (( aliases > 0 )) && margin=$((margin * aliases))
10761         fi
10762
10763         echo "before slab objects: $before"
10764         for i in $(seq $count); do
10765                 touch $DIR/$tfile
10766                 rm -f $DIR/$tfile
10767         done
10768         cancel_lru_locks osc
10769         local after=$(num_objects)
10770         echo "created: $count, after slab objects: $after"
10771         # shared slab counts are not very accurate, allow significant margin
10772         # the main goal is that the cache growth is not permanently > $count
10773         while (( after > before + margin )); do
10774                 sleep 1
10775                 after=$(num_objects)
10776                 wait=$((wait + 1))
10777                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10778                 if (( wait > 60 )); then
10779                         error "inode slab grew from $before+$margin to $after"
10780                 fi
10781         done
10782 }
10783 run_test 76a "confirm clients recycle inodes properly ===="
10784
10785 test_76b() {
10786         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10787         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10788
10789         local count=512
10790         local before=$(num_objects)
10791
10792         for i in $(seq $count); do
10793                 mkdir $DIR/$tdir
10794                 rmdir $DIR/$tdir
10795         done
10796
10797         local after=$(num_objects)
10798         local wait=0
10799
10800         while (( after > before )); do
10801                 sleep 1
10802                 after=$(num_objects)
10803                 wait=$((wait + 1))
10804                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10805                 if (( wait > 60 )); then
10806                         error "inode slab grew from $before to $after"
10807                 fi
10808         done
10809
10810         echo "slab objects before: $before, after: $after"
10811 }
10812 run_test 76b "confirm clients recycle directory inodes properly ===="
10813
10814 export ORIG_CSUM=""
10815 set_checksums()
10816 {
10817         # Note: in sptlrpc modes which enable its own bulk checksum, the
10818         # original crc32_le bulk checksum will be automatically disabled,
10819         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10820         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10821         # In this case set_checksums() will not be no-op, because sptlrpc
10822         # bulk checksum will be enabled all through the test.
10823
10824         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10825         lctl set_param -n osc.*.checksums $1
10826         return 0
10827 }
10828
10829 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10830                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10831 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10832                              tr -d [] | head -n1)}
10833 set_checksum_type()
10834 {
10835         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10836         rc=$?
10837         log "set checksum type to $1, rc = $rc"
10838         return $rc
10839 }
10840
10841 get_osc_checksum_type()
10842 {
10843         # arugment 1: OST name, like OST0000
10844         ost=$1
10845         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10846                         sed 's/.*\[\(.*\)\].*/\1/g')
10847         rc=$?
10848         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10849         echo $checksum_type
10850 }
10851
10852 F77_TMP=$TMP/f77-temp
10853 F77SZ=8
10854 setup_f77() {
10855         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10856                 error "error writing to $F77_TMP"
10857 }
10858
10859 test_77a() { # bug 10889
10860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10861         $GSS && skip_env "could not run with gss"
10862
10863         [ ! -f $F77_TMP ] && setup_f77
10864         set_checksums 1
10865         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10866         set_checksums 0
10867         rm -f $DIR/$tfile
10868 }
10869 run_test 77a "normal checksum read/write operation"
10870
10871 test_77b() { # bug 10889
10872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10873         $GSS && skip_env "could not run with gss"
10874
10875         [ ! -f $F77_TMP ] && setup_f77
10876         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10877         $LCTL set_param fail_loc=0x80000409
10878         set_checksums 1
10879
10880         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10881                 error "dd error: $?"
10882         $LCTL set_param fail_loc=0
10883
10884         for algo in $CKSUM_TYPES; do
10885                 cancel_lru_locks osc
10886                 set_checksum_type $algo
10887                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10888                 $LCTL set_param fail_loc=0x80000408
10889                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10890                 $LCTL set_param fail_loc=0
10891         done
10892         set_checksums 0
10893         set_checksum_type $ORIG_CSUM_TYPE
10894         rm -f $DIR/$tfile
10895 }
10896 run_test 77b "checksum error on client write, read"
10897
10898 cleanup_77c() {
10899         trap 0
10900         set_checksums 0
10901         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10902         $check_ost &&
10903                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10904         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10905         $check_ost && [ -n "$ost_file_prefix" ] &&
10906                 do_facet ost1 rm -f ${ost_file_prefix}\*
10907 }
10908
10909 test_77c() {
10910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10911         $GSS && skip_env "could not run with gss"
10912         remote_ost_nodsh && skip "remote OST with nodsh"
10913
10914         local bad1
10915         local osc_file_prefix
10916         local osc_file
10917         local check_ost=false
10918         local ost_file_prefix
10919         local ost_file
10920         local orig_cksum
10921         local dump_cksum
10922         local fid
10923
10924         # ensure corruption will occur on first OSS/OST
10925         $LFS setstripe -i 0 $DIR/$tfile
10926
10927         [ ! -f $F77_TMP ] && setup_f77
10928         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10929                 error "dd write error: $?"
10930         fid=$($LFS path2fid $DIR/$tfile)
10931
10932         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10933         then
10934                 check_ost=true
10935                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10936                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10937         else
10938                 echo "OSS do not support bulk pages dump upon error"
10939         fi
10940
10941         osc_file_prefix=$($LCTL get_param -n debug_path)
10942         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10943
10944         trap cleanup_77c EXIT
10945
10946         set_checksums 1
10947         # enable bulk pages dump upon error on Client
10948         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10949         # enable bulk pages dump upon error on OSS
10950         $check_ost &&
10951                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10952
10953         # flush Client cache to allow next read to reach OSS
10954         cancel_lru_locks osc
10955
10956         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10957         $LCTL set_param fail_loc=0x80000408
10958         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10959         $LCTL set_param fail_loc=0
10960
10961         rm -f $DIR/$tfile
10962
10963         # check cksum dump on Client
10964         osc_file=$(ls ${osc_file_prefix}*)
10965         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10966         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10967         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10968         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10969         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10970                      cksum)
10971         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10972         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10973                 error "dump content does not match on Client"
10974
10975         $check_ost || skip "No need to check cksum dump on OSS"
10976
10977         # check cksum dump on OSS
10978         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10979         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10980         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10981         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10982         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10983                 error "dump content does not match on OSS"
10984
10985         cleanup_77c
10986 }
10987 run_test 77c "checksum error on client read with debug"
10988
10989 test_77d() { # bug 10889
10990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10991         $GSS && skip_env "could not run with gss"
10992
10993         stack_trap "rm -f $DIR/$tfile"
10994         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10995         $LCTL set_param fail_loc=0x80000409
10996         set_checksums 1
10997         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10998                 error "direct write: rc=$?"
10999         $LCTL set_param fail_loc=0
11000         set_checksums 0
11001
11002         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
11003         $LCTL set_param fail_loc=0x80000408
11004         set_checksums 1
11005         cancel_lru_locks osc
11006         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
11007                 error "direct read: rc=$?"
11008         $LCTL set_param fail_loc=0
11009         set_checksums 0
11010 }
11011 run_test 77d "checksum error on OST direct write, read"
11012
11013 test_77f() { # bug 10889
11014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11015         $GSS && skip_env "could not run with gss"
11016
11017         set_checksums 1
11018         stack_trap "rm -f $DIR/$tfile"
11019         for algo in $CKSUM_TYPES; do
11020                 cancel_lru_locks osc
11021                 set_checksum_type $algo
11022                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11023                 $LCTL set_param fail_loc=0x409
11024                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11025                         error "direct write succeeded"
11026                 $LCTL set_param fail_loc=0
11027         done
11028         set_checksum_type $ORIG_CSUM_TYPE
11029         set_checksums 0
11030 }
11031 run_test 77f "repeat checksum error on write (expect error)"
11032
11033 test_77g() { # bug 10889
11034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11035         $GSS && skip_env "could not run with gss"
11036         remote_ost_nodsh && skip "remote OST with nodsh"
11037
11038         [ ! -f $F77_TMP ] && setup_f77
11039
11040         local file=$DIR/$tfile
11041         stack_trap "rm -f $file" EXIT
11042
11043         $LFS setstripe -c 1 -i 0 $file
11044         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11045         do_facet ost1 lctl set_param fail_loc=0x8000021a
11046         set_checksums 1
11047         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11048                 error "write error: rc=$?"
11049         do_facet ost1 lctl set_param fail_loc=0
11050         set_checksums 0
11051
11052         cancel_lru_locks osc
11053         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11054         do_facet ost1 lctl set_param fail_loc=0x8000021b
11055         set_checksums 1
11056         cmp $F77_TMP $file || error "file compare failed"
11057         do_facet ost1 lctl set_param fail_loc=0
11058         set_checksums 0
11059 }
11060 run_test 77g "checksum error on OST write, read"
11061
11062 test_77k() { # LU-10906
11063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11064         $GSS && skip_env "could not run with gss"
11065
11066         local cksum_param="osc.$FSNAME*.checksums"
11067         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11068         local checksum
11069         local i
11070
11071         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11072         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11073         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11074
11075         for i in 0 1; do
11076                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11077                         error "failed to set checksum=$i on MGS"
11078                 wait_update $HOSTNAME "$get_checksum" $i
11079                 #remount
11080                 echo "remount client, checksum should be $i"
11081                 remount_client $MOUNT || error "failed to remount client"
11082                 checksum=$(eval $get_checksum)
11083                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11084         done
11085         # remove persistent param to avoid races with checksum mountopt below
11086         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11087                 error "failed to delete checksum on MGS"
11088
11089         for opt in "checksum" "nochecksum"; do
11090                 #remount with mount option
11091                 echo "remount client with option $opt, checksum should be $i"
11092                 umount_client $MOUNT || error "failed to umount client"
11093                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11094                         error "failed to mount client with option '$opt'"
11095                 checksum=$(eval $get_checksum)
11096                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11097                 i=$((i - 1))
11098         done
11099
11100         remount_client $MOUNT || error "failed to remount client"
11101 }
11102 run_test 77k "enable/disable checksum correctly"
11103
11104 test_77l() {
11105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11106         $GSS && skip_env "could not run with gss"
11107
11108         set_checksums 1
11109         stack_trap "set_checksums $ORIG_CSUM" EXIT
11110         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11111         local old
11112
11113         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
11114         $LCTL set_param osc.*.idle_timeout=10
11115         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
11116
11117         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11118
11119         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11120         for algo in $CKSUM_TYPES; do
11121                 set_checksum_type $algo || error "fail to set checksum type $algo"
11122                 osc_algo=$(get_osc_checksum_type OST0000)
11123                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11124
11125                 # no locks, no reqs to let the connection idle
11126                 cancel_lru_locks osc
11127                 lru_resize_disable osc
11128                 wait_osc_import_state client ost1 IDLE
11129
11130                 # ensure ost1 is connected
11131                 stat $DIR/$tfile >/dev/null || error "can't stat"
11132                 wait_osc_import_state client ost1 FULL
11133
11134                 osc_algo=$(get_osc_checksum_type OST0000)
11135                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11136         done
11137         return 0
11138 }
11139 run_test 77l "preferred checksum type is remembered after reconnected"
11140
11141 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11142 rm -f $F77_TMP
11143 unset F77_TMP
11144
11145 test_77m() {
11146         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11147                 skip "Need at least version 2.14.52"
11148         local param=checksum_speed
11149
11150         $LCTL get_param $param || error "reading $param failed"
11151
11152         csum_speeds=$($LCTL get_param -n $param)
11153
11154         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11155                 error "known checksum types are missing"
11156 }
11157 run_test 77m "Verify checksum_speed is correctly read"
11158
11159 check_filefrag_77n() {
11160         local nr_ext=0
11161         local starts=()
11162         local ends=()
11163
11164         while read extidx a b start end rest; do
11165                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11166                         nr_ext=$(( $nr_ext + 1 ))
11167                         starts+=( ${start%..} )
11168                         ends+=( ${end%:} )
11169                 fi
11170         done < <( filefrag -sv $1 )
11171
11172         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11173         return 1
11174 }
11175
11176 test_77n() {
11177         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11178
11179         touch $DIR/$tfile
11180         $TRUNCATE $DIR/$tfile 0
11181         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11182         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11183         check_filefrag_77n $DIR/$tfile ||
11184                 skip "$tfile blocks not contiguous around hole"
11185
11186         set_checksums 1
11187         stack_trap "set_checksums $ORIG_CSUM" EXIT
11188         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11189         stack_trap "rm -f $DIR/$tfile"
11190
11191         for algo in $CKSUM_TYPES; do
11192                 if [[ "$algo" =~ ^t10 ]]; then
11193                         set_checksum_type $algo ||
11194                                 error "fail to set checksum type $algo"
11195                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11196                                 error "fail to read $tfile with $algo"
11197                 fi
11198         done
11199         rm -f $DIR/$tfile
11200         return 0
11201 }
11202 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11203
11204 test_77o() {
11205         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11206                 skip "Need MDS version at least 2.14.55"
11207         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11208                 skip "Need OST version at least 2.14.55"
11209         local ofd=obdfilter
11210         local mdt=mdt
11211
11212         # print OST checksum_type
11213         echo "$ofd.$FSNAME-*.checksum_type:"
11214         do_nodes $(comma_list $(osts_nodes)) \
11215                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11216
11217         # print MDT checksum_type
11218         echo "$mdt.$FSNAME-*.checksum_type:"
11219         do_nodes $(comma_list $(mdts_nodes)) \
11220                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11221
11222         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11223                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11224
11225         (( $o_count == $OSTCOUNT )) ||
11226                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11227
11228         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11229                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11230
11231         (( $m_count == $MDSCOUNT )) ||
11232                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11233 }
11234 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11235
11236 cleanup_test_78() {
11237         trap 0
11238         rm -f $DIR/$tfile
11239 }
11240
11241 test_78() { # bug 10901
11242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11243         remote_ost || skip_env "local OST"
11244
11245         NSEQ=5
11246         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11247         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11248         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11249         echo "MemTotal: $MEMTOTAL"
11250
11251         # reserve 256MB of memory for the kernel and other running processes,
11252         # and then take 1/2 of the remaining memory for the read/write buffers.
11253         if [ $MEMTOTAL -gt 512 ] ;then
11254                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11255         else
11256                 # for those poor memory-starved high-end clusters...
11257                 MEMTOTAL=$((MEMTOTAL / 2))
11258         fi
11259         echo "Mem to use for directio: $MEMTOTAL"
11260
11261         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11262         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11263         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11264         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11265                 head -n1)
11266         echo "Smallest OST: $SMALLESTOST"
11267         [[ $SMALLESTOST -lt 10240 ]] &&
11268                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11269
11270         trap cleanup_test_78 EXIT
11271
11272         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11273                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11274
11275         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11276         echo "File size: $F78SIZE"
11277         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11278         for i in $(seq 1 $NSEQ); do
11279                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11280                 echo directIO rdwr round $i of $NSEQ
11281                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11282         done
11283
11284         cleanup_test_78
11285 }
11286 run_test 78 "handle large O_DIRECT writes correctly ============"
11287
11288 test_79() { # bug 12743
11289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11290
11291         wait_delete_completed
11292
11293         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11294         BKFREE=$(calc_osc_kbytes kbytesfree)
11295         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11296
11297         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11298         DFTOTAL=`echo $STRING | cut -d, -f1`
11299         DFUSED=`echo $STRING  | cut -d, -f2`
11300         DFAVAIL=`echo $STRING | cut -d, -f3`
11301         DFFREE=$(($DFTOTAL - $DFUSED))
11302
11303         ALLOWANCE=$((64 * $OSTCOUNT))
11304
11305         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11306            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11307                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11308         fi
11309         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11310            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11311                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11312         fi
11313         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11314            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11315                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11316         fi
11317 }
11318 run_test 79 "df report consistency check ======================="
11319
11320 test_80() { # bug 10718
11321         remote_ost_nodsh && skip "remote OST with nodsh"
11322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11323
11324         # relax strong synchronous semantics for slow backends like ZFS
11325         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11326                 local soc="obdfilter.*.sync_lock_cancel"
11327                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11328
11329                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11330                 if [ -z "$save" ]; then
11331                         soc="obdfilter.*.sync_on_lock_cancel"
11332                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11333                 fi
11334
11335                 if [ "$save" != "never" ]; then
11336                         local hosts=$(comma_list $(osts_nodes))
11337
11338                         do_nodes $hosts $LCTL set_param $soc=never
11339                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11340                 fi
11341         fi
11342
11343         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11344         sync; sleep 1; sync
11345         local before=$(date +%s)
11346         cancel_lru_locks osc
11347         local after=$(date +%s)
11348         local diff=$((after - before))
11349         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11350
11351         rm -f $DIR/$tfile
11352 }
11353 run_test 80 "Page eviction is equally fast at high offsets too"
11354
11355 test_81a() { # LU-456
11356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11357         remote_ost_nodsh && skip "remote OST with nodsh"
11358
11359         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11360         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11361         do_facet ost1 lctl set_param fail_loc=0x80000228
11362
11363         # write should trigger a retry and success
11364         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11365         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11366         RC=$?
11367         if [ $RC -ne 0 ] ; then
11368                 error "write should success, but failed for $RC"
11369         fi
11370 }
11371 run_test 81a "OST should retry write when get -ENOSPC ==============="
11372
11373 test_81b() { # LU-456
11374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11375         remote_ost_nodsh && skip "remote OST with nodsh"
11376
11377         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11378         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11379         do_facet ost1 lctl set_param fail_loc=0x228
11380
11381         # write should retry several times and return -ENOSPC finally
11382         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11383         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11384         RC=$?
11385         ENOSPC=28
11386         if [ $RC -ne $ENOSPC ] ; then
11387                 error "dd should fail for -ENOSPC, but succeed."
11388         fi
11389 }
11390 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11391
11392 test_99() {
11393         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11394
11395         test_mkdir $DIR/$tdir.cvsroot
11396         chown $RUNAS_ID $DIR/$tdir.cvsroot
11397
11398         cd $TMP
11399         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11400
11401         cd /etc/init.d
11402         # some versions of cvs import exit(1) when asked to import links or
11403         # files they can't read.  ignore those files.
11404         local toignore=$(find . -type l -printf '-I %f\n' -o \
11405                          ! -perm /4 -printf '-I %f\n')
11406         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11407                 $tdir.reposname vtag rtag
11408
11409         cd $DIR
11410         test_mkdir $DIR/$tdir.reposname
11411         chown $RUNAS_ID $DIR/$tdir.reposname
11412         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11413
11414         cd $DIR/$tdir.reposname
11415         $RUNAS touch foo99
11416         $RUNAS cvs add -m 'addmsg' foo99
11417         $RUNAS cvs update
11418         $RUNAS cvs commit -m 'nomsg' foo99
11419         rm -fr $DIR/$tdir.cvsroot
11420 }
11421 run_test 99 "cvs strange file/directory operations"
11422
11423 test_100() {
11424         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11425         [[ "$NETTYPE" =~ tcp ]] ||
11426                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11427         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11428         remote_ost_nodsh && skip "remote OST with nodsh"
11429         remote_mds_nodsh && skip "remote MDS with nodsh"
11430         remote_servers || skip "useless for local single node setup"
11431
11432         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11433                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11434
11435                 rc=0
11436                 if (( ${LOCAL/*:/} >= 1024 )); then
11437                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11438                         ss -tna
11439                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11440                 fi
11441         done
11442         (( $rc == 0 )) || error "privileged port not found" )
11443 }
11444 run_test 100 "check local port using privileged port"
11445
11446 function get_named_value()
11447 {
11448     local tag=$1
11449
11450     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11451 }
11452
11453 test_101a() {
11454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11455
11456         local s
11457         local discard
11458         local nreads=10000
11459         local cache_limit=32
11460
11461         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11462         $LCTL set_param -n llite.*.read_ahead_stats=0
11463         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11464                               awk '/^max_cached_mb/ { print $2 }')
11465         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11466         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11467
11468         #
11469         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11470         #
11471         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11472         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11473
11474         discard=0
11475         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11476                    get_named_value 'read.but.discarded'); do
11477                         discard=$(($discard + $s))
11478         done
11479
11480         $LCTL get_param osc.*-osc*.rpc_stats
11481         $LCTL get_param llite.*.read_ahead_stats
11482
11483         # Discard is generally zero, but sometimes a few random reads line up
11484         # and trigger larger readahead, which is wasted & leads to discards.
11485         if [[ $(($discard)) -gt $nreads ]]; then
11486                 error "too many ($discard) discarded pages"
11487         fi
11488         rm -f $DIR/$tfile || true
11489 }
11490 run_test 101a "check read-ahead for random reads"
11491
11492 setup_test101bc() {
11493         test_mkdir $DIR/$tdir
11494         local ssize=$1
11495         local FILE_LENGTH=$2
11496         STRIPE_OFFSET=0
11497
11498         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11499
11500         local list=$(comma_list $(osts_nodes))
11501         set_osd_param $list '' read_cache_enable 0
11502         set_osd_param $list '' writethrough_cache_enable 0
11503
11504         trap cleanup_test101bc EXIT
11505         # prepare the read-ahead file
11506         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11507
11508         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11509                                 count=$FILE_SIZE_MB 2> /dev/null
11510
11511 }
11512
11513 cleanup_test101bc() {
11514         trap 0
11515         rm -rf $DIR/$tdir
11516         rm -f $DIR/$tfile
11517
11518         local list=$(comma_list $(osts_nodes))
11519         set_osd_param $list '' read_cache_enable 1
11520         set_osd_param $list '' writethrough_cache_enable 1
11521 }
11522
11523 ra_check_101() {
11524         local read_size=$1
11525         local stripe_size=$2
11526         local stride_length=$((stripe_size / read_size))
11527         local stride_width=$((stride_length * OSTCOUNT))
11528         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11529                                 (stride_width - stride_length) ))
11530         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11531                   get_named_value 'read.but.discarded' | calc_sum)
11532
11533         if [[ $discard -gt $discard_limit ]]; then
11534                 $LCTL get_param llite.*.read_ahead_stats
11535                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11536         else
11537                 echo "Read-ahead success for size ${read_size}"
11538         fi
11539 }
11540
11541 test_101b() {
11542         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11543         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11544
11545         local STRIPE_SIZE=1048576
11546         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11547
11548         if [ $SLOW == "yes" ]; then
11549                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11550         else
11551                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11552         fi
11553
11554         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11555
11556         # prepare the read-ahead file
11557         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11558         cancel_lru_locks osc
11559         for BIDX in 2 4 8 16 32 64 128 256
11560         do
11561                 local BSIZE=$((BIDX*4096))
11562                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11563                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11564                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11565                 $LCTL set_param -n llite.*.read_ahead_stats=0
11566                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11567                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11568                 cancel_lru_locks osc
11569                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11570         done
11571         cleanup_test101bc
11572         true
11573 }
11574 run_test 101b "check stride-io mode read-ahead ================="
11575
11576 test_101c() {
11577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11578
11579         local STRIPE_SIZE=1048576
11580         local FILE_LENGTH=$((STRIPE_SIZE*100))
11581         local nreads=10000
11582         local rsize=65536
11583         local osc_rpc_stats
11584
11585         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11586
11587         cancel_lru_locks osc
11588         $LCTL set_param osc.*.rpc_stats=0
11589         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11590         $LCTL get_param osc.*.rpc_stats
11591         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11592                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11593                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11594                 local size
11595
11596                 if [ $lines -le 20 ]; then
11597                         echo "continue debug"
11598                         continue
11599                 fi
11600                 for size in 1 2 4 8; do
11601                         local rpc=$(echo "$stats" |
11602                                     awk '($1 == "'$size':") {print $2; exit; }')
11603                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11604                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11605                 done
11606                 echo "$osc_rpc_stats check passed!"
11607         done
11608         cleanup_test101bc
11609         true
11610 }
11611 run_test 101c "check stripe_size aligned read-ahead"
11612
11613 test_101d() {
11614         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11615
11616         local file=$DIR/$tfile
11617         local sz_MB=${FILESIZE_101d:-80}
11618         local ra_MB=${READAHEAD_MB:-40}
11619
11620         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11621         [ $free_MB -lt $sz_MB ] &&
11622                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11623
11624         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11625         $LFS setstripe -c -1 $file || error "setstripe failed"
11626
11627         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11628         echo Cancel LRU locks on lustre client to flush the client cache
11629         cancel_lru_locks osc
11630
11631         echo Disable read-ahead
11632         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11633         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11634         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11635         $LCTL get_param -n llite.*.max_read_ahead_mb
11636
11637         echo "Reading the test file $file with read-ahead disabled"
11638         local sz_KB=$((sz_MB * 1024 / 4))
11639         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11640         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11641         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11642         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11643                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11644
11645         echo "Cancel LRU locks on lustre client to flush the client cache"
11646         cancel_lru_locks osc
11647         echo Enable read-ahead with ${ra_MB}MB
11648         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11649
11650         echo "Reading the test file $file with read-ahead enabled"
11651         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11652                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11653
11654         echo "read-ahead disabled time read '$raOFF'"
11655         echo "read-ahead enabled time read '$raON'"
11656
11657         rm -f $file
11658         wait_delete_completed
11659
11660         # use awk for this check instead of bash because it handles decimals
11661         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11662                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11663 }
11664 run_test 101d "file read with and without read-ahead enabled"
11665
11666 test_101e() {
11667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11668
11669         local file=$DIR/$tfile
11670         local size_KB=500  #KB
11671         local count=100
11672         local bsize=1024
11673
11674         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11675         local need_KB=$((count * size_KB))
11676         [[ $free_KB -le $need_KB ]] &&
11677                 skip_env "Need free space $need_KB, have $free_KB"
11678
11679         echo "Creating $count ${size_KB}K test files"
11680         for ((i = 0; i < $count; i++)); do
11681                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11682         done
11683
11684         echo "Cancel LRU locks on lustre client to flush the client cache"
11685         cancel_lru_locks $OSC
11686
11687         echo "Reset readahead stats"
11688         $LCTL set_param -n llite.*.read_ahead_stats=0
11689
11690         for ((i = 0; i < $count; i++)); do
11691                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11692         done
11693
11694         $LCTL get_param llite.*.max_cached_mb
11695         $LCTL get_param llite.*.read_ahead_stats
11696         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11697                      get_named_value 'misses' | calc_sum)
11698
11699         for ((i = 0; i < $count; i++)); do
11700                 rm -rf $file.$i 2>/dev/null
11701         done
11702
11703         #10000 means 20% reads are missing in readahead
11704         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11705 }
11706 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11707
11708 test_101f() {
11709         which iozone || skip_env "no iozone installed"
11710
11711         local old_debug=$($LCTL get_param debug)
11712         old_debug=${old_debug#*=}
11713         $LCTL set_param debug="reada mmap"
11714
11715         # create a test file
11716         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11717
11718         echo Cancel LRU locks on lustre client to flush the client cache
11719         cancel_lru_locks osc
11720
11721         echo Reset readahead stats
11722         $LCTL set_param -n llite.*.read_ahead_stats=0
11723
11724         echo mmap read the file with small block size
11725         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11726                 > /dev/null 2>&1
11727
11728         echo checking missing pages
11729         $LCTL get_param llite.*.read_ahead_stats
11730         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11731                         get_named_value 'misses' | calc_sum)
11732
11733         $LCTL set_param debug="$old_debug"
11734         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11735         rm -f $DIR/$tfile
11736 }
11737 run_test 101f "check mmap read performance"
11738
11739 test_101g_brw_size_test() {
11740         local mb=$1
11741         local pages=$((mb * 1048576 / PAGE_SIZE))
11742         local file=$DIR/$tfile
11743
11744         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11745                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11746         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11747                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11748                         return 2
11749         done
11750
11751         stack_trap "rm -f $file" EXIT
11752         $LCTL set_param -n osc.*.rpc_stats=0
11753
11754         # 10 RPCs should be enough for the test
11755         local count=10
11756         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11757                 { error "dd write ${mb} MB blocks failed"; return 3; }
11758         cancel_lru_locks osc
11759         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11760                 { error "dd write ${mb} MB blocks failed"; return 4; }
11761
11762         # calculate number of full-sized read and write RPCs
11763         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11764                 sed -n '/pages per rpc/,/^$/p' |
11765                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11766                 END { print reads,writes }'))
11767         # allow one extra full-sized read RPC for async readahead
11768         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11769                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11770         [[ ${rpcs[1]} == $count ]] ||
11771                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11772 }
11773
11774 test_101g() {
11775         remote_ost_nodsh && skip "remote OST with nodsh"
11776
11777         local rpcs
11778         local osts=$(get_facets OST)
11779         local list=$(comma_list $(osts_nodes))
11780         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11781         local brw_size="obdfilter.*.brw_size"
11782
11783         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11784
11785         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11786
11787         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11788                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11789                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11790            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11791                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11792                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11793
11794                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11795                         suffix="M"
11796
11797                 if [[ $orig_mb -lt 16 ]]; then
11798                         save_lustre_params $osts "$brw_size" > $p
11799                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11800                                 error "set 16MB RPC size failed"
11801
11802                         echo "remount client to enable new RPC size"
11803                         remount_client $MOUNT || error "remount_client failed"
11804                 fi
11805
11806                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11807                 # should be able to set brw_size=12, but no rpc_stats for that
11808                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11809         fi
11810
11811         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11812
11813         if [[ $orig_mb -lt 16 ]]; then
11814                 restore_lustre_params < $p
11815                 remount_client $MOUNT || error "remount_client restore failed"
11816         fi
11817
11818         rm -f $p $DIR/$tfile
11819 }
11820 run_test 101g "Big bulk(4/16 MiB) readahead"
11821
11822 test_101h() {
11823         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11824
11825         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11826                 error "dd 70M file failed"
11827         echo Cancel LRU locks on lustre client to flush the client cache
11828         cancel_lru_locks osc
11829
11830         echo "Reset readahead stats"
11831         $LCTL set_param -n llite.*.read_ahead_stats 0
11832
11833         echo "Read 10M of data but cross 64M bundary"
11834         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11835         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11836                      get_named_value 'misses' | calc_sum)
11837         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11838         rm -f $p $DIR/$tfile
11839 }
11840 run_test 101h "Readahead should cover current read window"
11841
11842 test_101i() {
11843         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11844                 error "dd 10M file failed"
11845
11846         local max_per_file_mb=$($LCTL get_param -n \
11847                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11848         cancel_lru_locks osc
11849         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11850         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11851                 error "set max_read_ahead_per_file_mb to 1 failed"
11852
11853         echo "Reset readahead stats"
11854         $LCTL set_param llite.*.read_ahead_stats=0
11855
11856         dd if=$DIR/$tfile of=/dev/null bs=2M
11857
11858         $LCTL get_param llite.*.read_ahead_stats
11859         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11860                      awk '/misses/ { print $2 }')
11861         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11862         rm -f $DIR/$tfile
11863 }
11864 run_test 101i "allow current readahead to exceed reservation"
11865
11866 test_101j() {
11867         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11868                 error "setstripe $DIR/$tfile failed"
11869         local file_size=$((1048576 * 16))
11870         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11871         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11872
11873         echo Disable read-ahead
11874         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11875
11876         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11877         for blk in $PAGE_SIZE 1048576 $file_size; do
11878                 cancel_lru_locks osc
11879                 echo "Reset readahead stats"
11880                 $LCTL set_param -n llite.*.read_ahead_stats=0
11881                 local count=$(($file_size / $blk))
11882                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11883                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11884                              get_named_value 'failed.to.fast.read' | calc_sum)
11885                 $LCTL get_param -n llite.*.read_ahead_stats
11886                 [ $miss -eq $count ] || error "expected $count got $miss"
11887         done
11888
11889         rm -f $p $DIR/$tfile
11890 }
11891 run_test 101j "A complete read block should be submitted when no RA"
11892
11893 test_readahead_base() {
11894         local file=$DIR/$tfile
11895         local size=$1
11896         local iosz
11897         local ramax
11898         local ranum
11899
11900         $LCTL set_param -n llite.*.read_ahead_stats=0
11901         # The first page is not accounted into readahead
11902         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11903         iosz=$(((size + 1048575) / 1048576 * 1048576))
11904         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11905
11906         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11907         fallocate -l $size $file || error "failed to fallocate $file"
11908         cancel_lru_locks osc
11909         $MULTIOP $file or${iosz}c || error "failed to read $file"
11910         $LCTL get_param -n llite.*.read_ahead_stats
11911         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11912                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11913         (( $ranum <= $ramax )) ||
11914                 error "read-ahead pages is $ranum more than $ramax"
11915         rm -rf $file || error "failed to remove $file"
11916 }
11917
11918 test_101m()
11919 {
11920         local file=$DIR/$tfile
11921         local ramax
11922         local ranum
11923         local size
11924         local iosz
11925
11926         check_set_fallocate_or_skip
11927         stack_trap "rm -f $file" EXIT
11928
11929         test_readahead_base 4096
11930
11931         # file size: 16K = 16384
11932         test_readahead_base 16384
11933         test_readahead_base 16385
11934         test_readahead_base 16383
11935
11936         # file size: 1M + 1 = 1048576 + 1
11937         test_readahead_base 1048577
11938         # file size: 1M + 16K
11939         test_readahead_base $((1048576 + 16384))
11940
11941         # file size: stripe_size * (stripe_count - 1) + 16K
11942         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11943         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11944         # file size: stripe_size * stripe_count + 16K
11945         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11946         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11947         # file size: 2 * stripe_size * stripe_count + 16K
11948         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11949         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11950 }
11951 run_test 101m "read ahead for small file and last stripe of the file"
11952
11953 setup_test102() {
11954         test_mkdir $DIR/$tdir
11955         chown $RUNAS_ID $DIR/$tdir
11956         STRIPE_SIZE=65536
11957         STRIPE_OFFSET=1
11958         STRIPE_COUNT=$OSTCOUNT
11959         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11960
11961         trap cleanup_test102 EXIT
11962         cd $DIR
11963         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11964         cd $DIR/$tdir
11965         for num in 1 2 3 4; do
11966                 for count in $(seq 1 $STRIPE_COUNT); do
11967                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11968                                 local size=`expr $STRIPE_SIZE \* $num`
11969                                 local file=file"$num-$idx-$count"
11970                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11971                         done
11972                 done
11973         done
11974
11975         cd $DIR
11976         $1 tar cf $TMP/f102.tar $tdir --xattrs
11977 }
11978
11979 cleanup_test102() {
11980         trap 0
11981         rm -f $TMP/f102.tar
11982         rm -rf $DIR/d0.sanity/d102
11983 }
11984
11985 test_102a() {
11986         [ "$UID" != 0 ] && skip "must run as root"
11987         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11988                 skip_env "must have user_xattr"
11989
11990         [ -z "$(which setfattr 2>/dev/null)" ] &&
11991                 skip_env "could not find setfattr"
11992
11993         local testfile=$DIR/$tfile
11994
11995         touch $testfile
11996         echo "set/get xattr..."
11997         setfattr -n trusted.name1 -v value1 $testfile ||
11998                 error "setfattr -n trusted.name1=value1 $testfile failed"
11999         getfattr -n trusted.name1 $testfile 2> /dev/null |
12000           grep "trusted.name1=.value1" ||
12001                 error "$testfile missing trusted.name1=value1"
12002
12003         setfattr -n user.author1 -v author1 $testfile ||
12004                 error "setfattr -n user.author1=author1 $testfile failed"
12005         getfattr -n user.author1 $testfile 2> /dev/null |
12006           grep "user.author1=.author1" ||
12007                 error "$testfile missing trusted.author1=author1"
12008
12009         echo "listxattr..."
12010         setfattr -n trusted.name2 -v value2 $testfile ||
12011                 error "$testfile unable to set trusted.name2"
12012         setfattr -n trusted.name3 -v value3 $testfile ||
12013                 error "$testfile unable to set trusted.name3"
12014         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
12015             grep "trusted.name" | wc -l) -eq 3 ] ||
12016                 error "$testfile missing 3 trusted.name xattrs"
12017
12018         setfattr -n user.author2 -v author2 $testfile ||
12019                 error "$testfile unable to set user.author2"
12020         setfattr -n user.author3 -v author3 $testfile ||
12021                 error "$testfile unable to set user.author3"
12022         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12023             grep "user.author" | wc -l) -eq 3 ] ||
12024                 error "$testfile missing 3 user.author xattrs"
12025
12026         echo "remove xattr..."
12027         setfattr -x trusted.name1 $testfile ||
12028                 error "$testfile error deleting trusted.name1"
12029         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12030                 error "$testfile did not delete trusted.name1 xattr"
12031
12032         setfattr -x user.author1 $testfile ||
12033                 error "$testfile error deleting user.author1"
12034         echo "set lustre special xattr ..."
12035         $LFS setstripe -c1 $testfile
12036         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12037                 awk -F "=" '/trusted.lov/ { print $2 }' )
12038         setfattr -n "trusted.lov" -v $lovea $testfile ||
12039                 error "$testfile doesn't ignore setting trusted.lov again"
12040         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12041                 error "$testfile allow setting invalid trusted.lov"
12042         rm -f $testfile
12043 }
12044 run_test 102a "user xattr test =================================="
12045
12046 check_102b_layout() {
12047         local layout="$*"
12048         local testfile=$DIR/$tfile
12049
12050         echo "test layout '$layout'"
12051         $LFS setstripe $layout $testfile || error "setstripe failed"
12052         $LFS getstripe -y $testfile
12053
12054         echo "get/set/list trusted.lov xattr ..." # b=10930
12055         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12056         [[ "$value" =~ "trusted.lov" ]] ||
12057                 error "can't get trusted.lov from $testfile"
12058         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12059                 error "getstripe failed"
12060
12061         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12062
12063         value=$(cut -d= -f2 <<<$value)
12064         # LU-13168: truncated xattr should fail if short lov_user_md header
12065         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12066                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12067         for len in $lens; do
12068                 echo "setfattr $len $testfile.2"
12069                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12070                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12071         done
12072         local stripe_size=$($LFS getstripe -S $testfile.2)
12073         local stripe_count=$($LFS getstripe -c $testfile.2)
12074         [[ $stripe_size -eq 65536 ]] ||
12075                 error "stripe size $stripe_size != 65536"
12076         [[ $stripe_count -eq $stripe_count_orig ]] ||
12077                 error "stripe count $stripe_count != $stripe_count_orig"
12078         rm $testfile $testfile.2
12079 }
12080
12081 test_102b() {
12082         [ -z "$(which setfattr 2>/dev/null)" ] &&
12083                 skip_env "could not find setfattr"
12084         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12085
12086         # check plain layout
12087         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12088
12089         # and also check composite layout
12090         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12091
12092 }
12093 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12094
12095 test_102c() {
12096         [ -z "$(which setfattr 2>/dev/null)" ] &&
12097                 skip_env "could not find setfattr"
12098         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12099
12100         # b10930: get/set/list lustre.lov xattr
12101         echo "get/set/list lustre.lov xattr ..."
12102         test_mkdir $DIR/$tdir
12103         chown $RUNAS_ID $DIR/$tdir
12104         local testfile=$DIR/$tdir/$tfile
12105         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12106                 error "setstripe failed"
12107         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12108                 error "getstripe failed"
12109         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12110         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12111
12112         local testfile2=${testfile}2
12113         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12114                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12115
12116         $RUNAS $MCREATE $testfile2
12117         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12118         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12119         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12120         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12121         [ $stripe_count -eq $STRIPECOUNT ] ||
12122                 error "stripe count $stripe_count != $STRIPECOUNT"
12123 }
12124 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12125
12126 compare_stripe_info1() {
12127         local stripe_index_all_zero=true
12128
12129         for num in 1 2 3 4; do
12130                 for count in $(seq 1 $STRIPE_COUNT); do
12131                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12132                                 local size=$((STRIPE_SIZE * num))
12133                                 local file=file"$num-$offset-$count"
12134                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12135                                 [[ $stripe_size -ne $size ]] &&
12136                                     error "$file: size $stripe_size != $size"
12137                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12138                                 # allow fewer stripes to be created, ORI-601
12139                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12140                                     error "$file: count $stripe_count != $count"
12141                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12142                                 [[ $stripe_index -ne 0 ]] &&
12143                                         stripe_index_all_zero=false
12144                         done
12145                 done
12146         done
12147         $stripe_index_all_zero &&
12148                 error "all files are being extracted starting from OST index 0"
12149         return 0
12150 }
12151
12152 have_xattrs_include() {
12153         tar --help | grep -q xattrs-include &&
12154                 echo --xattrs-include="lustre.*"
12155 }
12156
12157 test_102d() {
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12160
12161         XINC=$(have_xattrs_include)
12162         setup_test102
12163         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12164         cd $DIR/$tdir/$tdir
12165         compare_stripe_info1
12166 }
12167 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12168
12169 test_102f() {
12170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12171         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12172
12173         XINC=$(have_xattrs_include)
12174         setup_test102
12175         test_mkdir $DIR/$tdir.restore
12176         cd $DIR
12177         tar cf - --xattrs $tdir | tar xf - \
12178                 -C $DIR/$tdir.restore --xattrs $XINC
12179         cd $DIR/$tdir.restore/$tdir
12180         compare_stripe_info1
12181 }
12182 run_test 102f "tar copy files, not keep osts"
12183
12184 grow_xattr() {
12185         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12186                 skip "must have user_xattr"
12187         [ -z "$(which setfattr 2>/dev/null)" ] &&
12188                 skip_env "could not find setfattr"
12189         [ -z "$(which getfattr 2>/dev/null)" ] &&
12190                 skip_env "could not find getfattr"
12191
12192         local xsize=${1:-1024}  # in bytes
12193         local file=$DIR/$tfile
12194         local value="$(generate_string $xsize)"
12195         local xbig=trusted.big
12196         local toobig=$2
12197
12198         touch $file
12199         log "save $xbig on $file"
12200         if [ -z "$toobig" ]
12201         then
12202                 setfattr -n $xbig -v $value $file ||
12203                         error "saving $xbig on $file failed"
12204         else
12205                 setfattr -n $xbig -v $value $file &&
12206                         error "saving $xbig on $file succeeded"
12207                 return 0
12208         fi
12209
12210         local orig=$(get_xattr_value $xbig $file)
12211         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12212
12213         local xsml=trusted.sml
12214         log "save $xsml on $file"
12215         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12216
12217         local new=$(get_xattr_value $xbig $file)
12218         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12219
12220         log "grow $xsml on $file"
12221         setfattr -n $xsml -v "$value" $file ||
12222                 error "growing $xsml on $file failed"
12223
12224         new=$(get_xattr_value $xbig $file)
12225         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12226         log "$xbig still valid after growing $xsml"
12227
12228         rm -f $file
12229 }
12230
12231 test_102h() { # bug 15777
12232         grow_xattr 1024
12233 }
12234 run_test 102h "grow xattr from inside inode to external block"
12235
12236 test_102ha() {
12237         large_xattr_enabled || skip_env "ea_inode feature disabled"
12238
12239         echo "setting xattr of max xattr size: $(max_xattr_size)"
12240         grow_xattr $(max_xattr_size)
12241
12242         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12243         echo "This should fail:"
12244         grow_xattr $(($(max_xattr_size) + 10)) 1
12245 }
12246 run_test 102ha "grow xattr from inside inode to external inode"
12247
12248 test_102i() { # bug 17038
12249         [ -z "$(which getfattr 2>/dev/null)" ] &&
12250                 skip "could not find getfattr"
12251
12252         touch $DIR/$tfile
12253         ln -s $DIR/$tfile $DIR/${tfile}link
12254         getfattr -n trusted.lov $DIR/$tfile ||
12255                 error "lgetxattr on $DIR/$tfile failed"
12256         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12257                 grep -i "no such attr" ||
12258                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12259         rm -f $DIR/$tfile $DIR/${tfile}link
12260 }
12261 run_test 102i "lgetxattr test on symbolic link ============"
12262
12263 test_102j() {
12264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12265         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12266
12267         XINC=$(have_xattrs_include)
12268         setup_test102 "$RUNAS"
12269         chown $RUNAS_ID $DIR/$tdir
12270         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12271         cd $DIR/$tdir/$tdir
12272         compare_stripe_info1 "$RUNAS"
12273 }
12274 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12275
12276 test_102k() {
12277         [ -z "$(which setfattr 2>/dev/null)" ] &&
12278                 skip "could not find setfattr"
12279
12280         touch $DIR/$tfile
12281         # b22187 just check that does not crash for regular file.
12282         setfattr -n trusted.lov $DIR/$tfile
12283         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12284         local test_kdir=$DIR/$tdir
12285         test_mkdir $test_kdir
12286         local default_size=$($LFS getstripe -S $test_kdir)
12287         local default_count=$($LFS getstripe -c $test_kdir)
12288         local default_offset=$($LFS getstripe -i $test_kdir)
12289         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12290                 error 'dir setstripe failed'
12291         setfattr -n trusted.lov $test_kdir
12292         local stripe_size=$($LFS getstripe -S $test_kdir)
12293         local stripe_count=$($LFS getstripe -c $test_kdir)
12294         local stripe_offset=$($LFS getstripe -i $test_kdir)
12295         [ $stripe_size -eq $default_size ] ||
12296                 error "stripe size $stripe_size != $default_size"
12297         [ $stripe_count -eq $default_count ] ||
12298                 error "stripe count $stripe_count != $default_count"
12299         [ $stripe_offset -eq $default_offset ] ||
12300                 error "stripe offset $stripe_offset != $default_offset"
12301         rm -rf $DIR/$tfile $test_kdir
12302 }
12303 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12304
12305 test_102l() {
12306         [ -z "$(which getfattr 2>/dev/null)" ] &&
12307                 skip "could not find getfattr"
12308
12309         # LU-532 trusted. xattr is invisible to non-root
12310         local testfile=$DIR/$tfile
12311
12312         touch $testfile
12313
12314         echo "listxattr as user..."
12315         chown $RUNAS_ID $testfile
12316         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12317             grep -q "trusted" &&
12318                 error "$testfile trusted xattrs are user visible"
12319
12320         return 0;
12321 }
12322 run_test 102l "listxattr size test =================================="
12323
12324 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12325         local path=$DIR/$tfile
12326         touch $path
12327
12328         listxattr_size_check $path || error "listattr_size_check $path failed"
12329 }
12330 run_test 102m "Ensure listxattr fails on small bufffer ========"
12331
12332 cleanup_test102
12333
12334 getxattr() { # getxattr path name
12335         # Return the base64 encoding of the value of xattr name on path.
12336         local path=$1
12337         local name=$2
12338
12339         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12340         # file: $path
12341         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12342         #
12343         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12344
12345         getfattr --absolute-names --encoding=base64 --name=$name $path |
12346                 awk -F= -v name=$name '$1 == name {
12347                         print substr($0, index($0, "=") + 1);
12348         }'
12349 }
12350
12351 test_102n() { # LU-4101 mdt: protect internal xattrs
12352         [ -z "$(which setfattr 2>/dev/null)" ] &&
12353                 skip "could not find setfattr"
12354         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12355         then
12356                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12357         fi
12358
12359         local file0=$DIR/$tfile.0
12360         local file1=$DIR/$tfile.1
12361         local xattr0=$TMP/$tfile.0
12362         local xattr1=$TMP/$tfile.1
12363         local namelist="lov lma lmv link fid version som hsm"
12364         local name
12365         local value
12366
12367         rm -rf $file0 $file1 $xattr0 $xattr1
12368         touch $file0 $file1
12369
12370         # Get 'before' xattrs of $file1.
12371         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12372
12373         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12374                 namelist+=" lfsck_namespace"
12375         for name in $namelist; do
12376                 # Try to copy xattr from $file0 to $file1.
12377                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12378
12379                 setfattr --name=trusted.$name --value="$value" $file1 ||
12380                         error "setxattr 'trusted.$name' failed"
12381
12382                 # Try to set a garbage xattr.
12383                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12384
12385                 if [[ x$name == "xlov" ]]; then
12386                         setfattr --name=trusted.lov --value="$value" $file1 &&
12387                         error "setxattr invalid 'trusted.lov' success"
12388                 else
12389                         setfattr --name=trusted.$name --value="$value" $file1 ||
12390                                 error "setxattr invalid 'trusted.$name' failed"
12391                 fi
12392
12393                 # Try to remove the xattr from $file1. We don't care if this
12394                 # appears to succeed or fail, we just don't want there to be
12395                 # any changes or crashes.
12396                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12397         done
12398
12399         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12400         then
12401                 name="lfsck_ns"
12402                 # Try to copy xattr from $file0 to $file1.
12403                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12404
12405                 setfattr --name=trusted.$name --value="$value" $file1 ||
12406                         error "setxattr 'trusted.$name' failed"
12407
12408                 # Try to set a garbage xattr.
12409                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12410
12411                 setfattr --name=trusted.$name --value="$value" $file1 ||
12412                         error "setxattr 'trusted.$name' failed"
12413
12414                 # Try to remove the xattr from $file1. We don't care if this
12415                 # appears to succeed or fail, we just don't want there to be
12416                 # any changes or crashes.
12417                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12418         fi
12419
12420         # Get 'after' xattrs of file1.
12421         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12422
12423         if ! diff $xattr0 $xattr1; then
12424                 error "before and after xattrs of '$file1' differ"
12425         fi
12426
12427         rm -rf $file0 $file1 $xattr0 $xattr1
12428
12429         return 0
12430 }
12431 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12432
12433 test_102p() { # LU-4703 setxattr did not check ownership
12434         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12435                 skip "MDS needs to be at least 2.5.56"
12436
12437         local testfile=$DIR/$tfile
12438
12439         touch $testfile
12440
12441         echo "setfacl as user..."
12442         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12443         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12444
12445         echo "setfattr as user..."
12446         setfacl -m "u:$RUNAS_ID:---" $testfile
12447         $RUNAS setfattr -x system.posix_acl_access $testfile
12448         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12449 }
12450 run_test 102p "check setxattr(2) correctly fails without permission"
12451
12452 test_102q() {
12453         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12454                 skip "MDS needs to be at least 2.6.92"
12455
12456         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12457 }
12458 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12459
12460 test_102r() {
12461         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12462                 skip "MDS needs to be at least 2.6.93"
12463
12464         touch $DIR/$tfile || error "touch"
12465         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12466         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12467         rm $DIR/$tfile || error "rm"
12468
12469         #normal directory
12470         mkdir -p $DIR/$tdir || error "mkdir"
12471         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12472         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12473         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12474                 error "$testfile error deleting user.author1"
12475         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12476                 grep "user.$(basename $tdir)" &&
12477                 error "$tdir did not delete user.$(basename $tdir)"
12478         rmdir $DIR/$tdir || error "rmdir"
12479
12480         #striped directory
12481         test_mkdir $DIR/$tdir
12482         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12483         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12484         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12485                 error "$testfile error deleting user.author1"
12486         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12487                 grep "user.$(basename $tdir)" &&
12488                 error "$tdir did not delete user.$(basename $tdir)"
12489         rmdir $DIR/$tdir || error "rm striped dir"
12490 }
12491 run_test 102r "set EAs with empty values"
12492
12493 test_102s() {
12494         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12495                 skip "MDS needs to be at least 2.11.52"
12496
12497         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12498
12499         save_lustre_params client "llite.*.xattr_cache" > $save
12500
12501         for cache in 0 1; do
12502                 lctl set_param llite.*.xattr_cache=$cache
12503
12504                 rm -f $DIR/$tfile
12505                 touch $DIR/$tfile || error "touch"
12506                 for prefix in lustre security system trusted user; do
12507                         # Note getxattr() may fail with 'Operation not
12508                         # supported' or 'No such attribute' depending
12509                         # on prefix and cache.
12510                         getfattr -n $prefix.n102s $DIR/$tfile &&
12511                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12512                 done
12513         done
12514
12515         restore_lustre_params < $save
12516 }
12517 run_test 102s "getting nonexistent xattrs should fail"
12518
12519 test_102t() {
12520         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12521                 skip "MDS needs to be at least 2.11.52"
12522
12523         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12524
12525         save_lustre_params client "llite.*.xattr_cache" > $save
12526
12527         for cache in 0 1; do
12528                 lctl set_param llite.*.xattr_cache=$cache
12529
12530                 for buf_size in 0 256; do
12531                         rm -f $DIR/$tfile
12532                         touch $DIR/$tfile || error "touch"
12533                         setfattr -n user.multiop $DIR/$tfile
12534                         $MULTIOP $DIR/$tfile oa$buf_size ||
12535                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12536                 done
12537         done
12538
12539         restore_lustre_params < $save
12540 }
12541 run_test 102t "zero length xattr values handled correctly"
12542
12543 run_acl_subtest()
12544 {
12545         local test=$LUSTRE/tests/acl/$1.test
12546         local tmp=$(mktemp -t $1-XXXXXX).test
12547         local bin=$2
12548         local dmn=$3
12549         local grp=$4
12550         local nbd=$5
12551         export LANG=C
12552
12553
12554         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12555         local sedgroups="-e s/:users/:$grp/g"
12556         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12557
12558         sed $sedusers $sedgroups < $test > $tmp
12559         stack_trap "rm -f $tmp"
12560         [[ -s $tmp ]] || error "sed failed to create test script"
12561
12562         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12563         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12564 }
12565
12566 test_103a() {
12567         [ "$UID" != 0 ] && skip "must run as root"
12568         $GSS && skip_env "could not run under gss"
12569         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12570                 skip_env "must have acl enabled"
12571         which setfacl || skip_env "could not find setfacl"
12572         remote_mds_nodsh && skip "remote MDS with nodsh"
12573
12574         local mdts=$(comma_list $(mdts_nodes))
12575         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12576
12577         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12578         stack_trap "[[ -z \"$saved\" ]] || \
12579                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12580
12581         ACLBIN=${ACLBIN:-"bin"}
12582         ACLDMN=${ACLDMN:-"daemon"}
12583         ACLGRP=${ACLGRP:-"users"}
12584         ACLNBD=${ACLNBD:-"nobody"}
12585
12586         if ! id $ACLBIN ||
12587            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12588                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12589                 ACLBIN=$USER0
12590                 if ! id $ACLBIN ; then
12591                         cat /etc/passwd
12592                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12593                 fi
12594         fi
12595         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12596            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12597                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12598                 ACLDMN=$USER1
12599                 if ! id $ACLDMN ; then
12600                         cat /etc/passwd
12601                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12602                 fi
12603         fi
12604         if ! getent group $ACLGRP; then
12605                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12606                 ACLGRP="$TSTUSR"
12607                 if ! getent group $ACLGRP; then
12608                         echo "cannot find group '$ACLGRP', adding it"
12609                         cat /etc/group
12610                         add_group 60000 $ACLGRP
12611                 fi
12612         fi
12613
12614         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12615         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12616         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12617
12618         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12619                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12620                 ACLGRP="$TSTUSR"
12621                 if ! getent group $ACLGRP; then
12622                         echo "cannot find group '$ACLGRP', adding it"
12623                         cat /etc/group
12624                         add_group 60000 $ACLGRP
12625                 fi
12626                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12627                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12628                         cat /etc/group
12629                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12630                 fi
12631         fi
12632
12633         gpasswd -a $ACLDMN $ACLBIN ||
12634                 error "setting client group failed"             # LU-5641
12635         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12636                 error "setting MDS group failed"                # LU-5641
12637
12638         declare -a identity_old
12639
12640         for ((num = 1; num <= $MDSCOUNT; num++)); do
12641                 switch_identity $num true || identity_old[$num]=$?
12642         done
12643
12644         SAVE_UMASK=$(umask)
12645         umask 0022
12646         mkdir -p $DIR/$tdir
12647         cd $DIR/$tdir
12648
12649         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12650         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12651         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12652         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12653         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12654         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12655         if ! id -u $ACLNBD ||
12656            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12657                 ACLNBD="nfsnobody"
12658                 if ! id -u $ACLNBD; then
12659                         ACLNBD=""
12660                 fi
12661         fi
12662         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12663                 add_group $(id -u $ACLNBD) $ACLNBD
12664                 if ! getent group $ACLNBD; then
12665                         ACLNBD=""
12666                 fi
12667         fi
12668         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12669            [[ -n "$ACLNBD" ]] && which setfattr; then
12670                 run_acl_subtest permissions_xattr \
12671                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12672         elif [[ -z "$ACLNBD" ]]; then
12673                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12674         else
12675                 echo "skip 'permission_xattr' test - missing setfattr command"
12676         fi
12677         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12678
12679         # inheritance test got from HP
12680         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12681         chmod +x make-tree || error "chmod +x failed"
12682         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12683         rm -f make-tree
12684
12685         echo "LU-974 ignore umask when acl is enabled..."
12686         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12687         if [ $MDSCOUNT -ge 2 ]; then
12688                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12689         fi
12690
12691         echo "LU-2561 newly created file is same size as directory..."
12692         if [ "$mds1_FSTYPE" != "zfs" ]; then
12693                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12694         else
12695                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12696         fi
12697
12698         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12699
12700         cd $SAVE_PWD
12701         umask $SAVE_UMASK
12702
12703         for ((num = 1; num <= $MDSCOUNT; num++)); do
12704                 if [[ "${identity_old[$num]}" == 1 ]]; then
12705                         switch_identity $num false || identity_old[$num]=$?
12706                 fi
12707         done
12708 }
12709 run_test 103a "acl test"
12710
12711 test_103b() {
12712         declare -a pids
12713         local U
12714
12715         stack_trap "rm -f $DIR/$tfile.*"
12716         for U in {0..511}; do
12717                 {
12718                 local O=$(printf "%04o" $U)
12719
12720                 umask $(printf "%04o" $((511 ^ $O)))
12721                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12722                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12723
12724                 (( $S == ($O & 0666) )) ||
12725                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12726
12727                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12728                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12729                 (( $S == ($O & 0666) )) ||
12730                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12731
12732                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12733                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12734                 (( $S == ($O & 0666) )) ||
12735                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12736                 rm -f $DIR/$tfile.[smp]$0
12737                 } &
12738                 local pid=$!
12739
12740                 # limit the concurrently running threads to 64. LU-11878
12741                 local idx=$((U % 64))
12742                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12743                 pids[idx]=$pid
12744         done
12745         wait
12746 }
12747 run_test 103b "umask lfs setstripe"
12748
12749 test_103c() {
12750         mkdir -p $DIR/$tdir
12751         cp -rp $DIR/$tdir $DIR/$tdir.bak
12752
12753         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12754                 error "$DIR/$tdir shouldn't contain default ACL"
12755         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12756                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12757         true
12758 }
12759 run_test 103c "'cp -rp' won't set empty acl"
12760
12761 test_103e() {
12762         local numacl
12763         local fileacl
12764         local saved_debug=$($LCTL get_param -n debug)
12765
12766         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12767                 skip "MDS needs to be at least 2.14.52"
12768
12769         large_xattr_enabled || skip_env "ea_inode feature disabled"
12770
12771         mkdir -p $DIR/$tdir
12772         # add big LOV EA to cause reply buffer overflow earlier
12773         $LFS setstripe -C 1000 $DIR/$tdir
12774         lctl set_param mdc.*-mdc*.stats=clear
12775
12776         $LCTL set_param debug=0
12777         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12778         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12779
12780         # add a large number of default ACLs (expect 8000+ for 2.13+)
12781         for U in {2..7000}; do
12782                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12783                         error "Able to add just $U default ACLs"
12784         done
12785         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12786         echo "$numacl default ACLs created"
12787
12788         stat $DIR/$tdir || error "Cannot stat directory"
12789         # check file creation
12790         touch $DIR/$tdir/$tfile ||
12791                 error "failed to create $tfile with $numacl default ACLs"
12792         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12793         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12794         echo "$fileacl ACLs were inherited"
12795         (( $fileacl == $numacl )) ||
12796                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12797         # check that new ACLs creation adds new ACLs to inherited ACLs
12798         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12799                 error "Cannot set new ACL"
12800         numacl=$((numacl + 1))
12801         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12802         (( $fileacl == $numacl )) ||
12803                 error "failed to add new ACL: $fileacl != $numacl as expected"
12804         # adds more ACLs to a file to reach their maximum at 8000+
12805         numacl=0
12806         for U in {20000..25000}; do
12807                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12808                 numacl=$((numacl + 1))
12809         done
12810         echo "Added $numacl more ACLs to the file"
12811         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12812         echo "Total $fileacl ACLs in file"
12813         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12814         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12815         rmdir $DIR/$tdir || error "Cannot remove directory"
12816 }
12817 run_test 103e "inheritance of big amount of default ACLs"
12818
12819 test_103f() {
12820         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12821                 skip "MDS needs to be at least 2.14.51"
12822
12823         large_xattr_enabled || skip_env "ea_inode feature disabled"
12824
12825         # enable changelog to consume more internal MDD buffers
12826         changelog_register
12827
12828         mkdir -p $DIR/$tdir
12829         # add big LOV EA
12830         $LFS setstripe -C 1000 $DIR/$tdir
12831         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12832         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12833         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12834         rmdir $DIR/$tdir || error "Cannot remove directory"
12835 }
12836 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12837
12838 test_104a() {
12839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12840
12841         touch $DIR/$tfile
12842         lfs df || error "lfs df failed"
12843         lfs df -ih || error "lfs df -ih failed"
12844         lfs df -h $DIR || error "lfs df -h $DIR failed"
12845         lfs df -i $DIR || error "lfs df -i $DIR failed"
12846         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12847         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12848
12849         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12850         lctl --device %$OSC deactivate
12851         lfs df || error "lfs df with deactivated OSC failed"
12852         lctl --device %$OSC activate
12853         # wait the osc back to normal
12854         wait_osc_import_ready client ost
12855
12856         lfs df || error "lfs df with reactivated OSC failed"
12857         rm -f $DIR/$tfile
12858 }
12859 run_test 104a "lfs df [-ih] [path] test ========================="
12860
12861 test_104b() {
12862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12863         [ $RUNAS_ID -eq $UID ] &&
12864                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12865
12866         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12867                         grep "Permission denied" | wc -l)))
12868         if [ $denied_cnt -ne 0 ]; then
12869                 error "lfs check servers test failed"
12870         fi
12871 }
12872 run_test 104b "$RUNAS lfs check servers test ===================="
12873
12874 #
12875 # Verify $1 is within range of $2.
12876 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12877 # $1 is <= 2% of $2. Else Fail.
12878 #
12879 value_in_range() {
12880         # Strip all units (M, G, T)
12881         actual=$(echo $1 | tr -d A-Z)
12882         expect=$(echo $2 | tr -d A-Z)
12883
12884         expect_lo=$(($expect * 98 / 100)) # 2% below
12885         expect_hi=$(($expect * 102 / 100)) # 2% above
12886
12887         # permit 2% drift above and below
12888         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12889 }
12890
12891 test_104c() {
12892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12893         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12894
12895         local ost_param="osd-zfs.$FSNAME-OST0000."
12896         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12897         local ofacets=$(get_facets OST)
12898         local mfacets=$(get_facets MDS)
12899         local saved_ost_blocks=
12900         local saved_mdt_blocks=
12901
12902         echo "Before recordsize change"
12903         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12904         df=($(df -h | grep "$MOUNT"$))
12905
12906         # For checking.
12907         echo "lfs output : ${lfs_df[*]}"
12908         echo "df  output : ${df[*]}"
12909
12910         for facet in ${ofacets//,/ }; do
12911                 if [ -z $saved_ost_blocks ]; then
12912                         saved_ost_blocks=$(do_facet $facet \
12913                                 lctl get_param -n $ost_param.blocksize)
12914                         echo "OST Blocksize: $saved_ost_blocks"
12915                 fi
12916                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12917                 do_facet $facet zfs set recordsize=32768 $ost
12918         done
12919
12920         # BS too small. Sufficient for functional testing.
12921         for facet in ${mfacets//,/ }; do
12922                 if [ -z $saved_mdt_blocks ]; then
12923                         saved_mdt_blocks=$(do_facet $facet \
12924                                 lctl get_param -n $mdt_param.blocksize)
12925                         echo "MDT Blocksize: $saved_mdt_blocks"
12926                 fi
12927                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12928                 do_facet $facet zfs set recordsize=32768 $mdt
12929         done
12930
12931         # Give new values chance to reflect change
12932         sleep 2
12933
12934         echo "After recordsize change"
12935         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12936         df_after=($(df -h | grep "$MOUNT"$))
12937
12938         # For checking.
12939         echo "lfs output : ${lfs_df_after[*]}"
12940         echo "df  output : ${df_after[*]}"
12941
12942         # Verify lfs df
12943         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12944                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12945         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12946                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12947         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12948                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12949
12950         # Verify df
12951         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12952                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12953         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12954                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12955         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12956                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12957
12958         # Restore MDT recordize back to original
12959         for facet in ${mfacets//,/ }; do
12960                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12961                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12962         done
12963
12964         # Restore OST recordize back to original
12965         for facet in ${ofacets//,/ }; do
12966                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12967                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12968         done
12969
12970         return 0
12971 }
12972 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12973
12974 test_104d() {
12975         (( $RUNAS_ID != $UID )) ||
12976                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12977
12978         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12979                 skip "lustre version doesn't support lctl dl with non-root"
12980
12981         # debugfs only allows root users to access files, so the
12982         # previous move of the "devices" file to debugfs broke
12983         # "lctl dl" for non-root users. The LU-9680 Netlink
12984         # interface again allows non-root users to list devices.
12985         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12986                 error "lctl dl doesn't work for non root"
12987
12988         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12989         [ "$ost_count" -eq $OSTCOUNT ]  ||
12990                 error "lctl dl reports wrong number of OST devices"
12991
12992         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12993         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12994                 error "lctl dl reports wrong number of MDT devices"
12995 }
12996 run_test 104d "$RUNAS lctl dl test"
12997
12998 test_105a() {
12999         # doesn't work on 2.4 kernels
13000         touch $DIR/$tfile
13001         if $(flock_is_enabled); then
13002                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
13003         else
13004                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
13005         fi
13006         rm -f $DIR/$tfile
13007 }
13008 run_test 105a "flock when mounted without -o flock test ========"
13009
13010 test_105b() {
13011         touch $DIR/$tfile
13012         if $(flock_is_enabled); then
13013                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
13014         else
13015                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
13016         fi
13017         rm -f $DIR/$tfile
13018 }
13019 run_test 105b "fcntl when mounted without -o flock test ========"
13020
13021 test_105c() {
13022         touch $DIR/$tfile
13023         if $(flock_is_enabled); then
13024                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13025         else
13026                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13027         fi
13028         rm -f $DIR/$tfile
13029 }
13030 run_test 105c "lockf when mounted without -o flock test"
13031
13032 test_105d() { # bug 15924
13033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13034
13035         test_mkdir $DIR/$tdir
13036         flock_is_enabled || skip_env "mount w/o flock enabled"
13037         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13038         $LCTL set_param fail_loc=0x80000315
13039         flocks_test 2 $DIR/$tdir
13040 }
13041 run_test 105d "flock race (should not freeze) ========"
13042
13043 test_105e() { # bug 22660 && 22040
13044         flock_is_enabled || skip_env "mount w/o flock enabled"
13045
13046         touch $DIR/$tfile
13047         flocks_test 3 $DIR/$tfile
13048 }
13049 run_test 105e "Two conflicting flocks from same process"
13050
13051 wait_end() {
13052         echo $*
13053         while :; do
13054                 [ -f $TMP/${tfile}_sTOP ] && return
13055                 sleep 1
13056         done
13057 }
13058
13059 test_105f() {
13060         flock_is_enabled || skip_env "mount w/o flock enabled"
13061
13062         local pmax=$(ulimit -u)
13063         local i=0
13064         touch $DIR/$tfile
13065         [ $pmax -gt 20 ] && pmax=20
13066         for((i=0; i <= $pmax; i++)) {
13067                 wait_end "R4000, 5000" | flocks_test 6 $DIR/$tfile &
13068         }
13069         for((i=0; i <= 10; i++)) {
13070                 local locks=$(do_facet $SINGLEMDS $LCTL get_param -n \
13071                         ldlm.namespaces.mdt-${FSNAME}-MDT0000*.lock_count)
13072                 [ $locks -ge $pmax ] && break
13073                 [ $i -eq 10 ] && error "The locks cannot be added after 10 secs"
13074                 sleep 1
13075         }
13076         touch $TMP/${tfile}_sTOP
13077         wait
13078         rm -r $DIR/$tfile $TMP/${tfile}_sTOP
13079 }
13080 run_test 105f "Enqueue same range flocks"
13081
13082 test_106() { #bug 10921
13083         test_mkdir $DIR/$tdir
13084         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13085         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13086 }
13087 run_test 106 "attempt exec of dir followed by chown of that dir"
13088
13089 test_107() {
13090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13091
13092         CDIR=`pwd`
13093         local file=core
13094
13095         cd $DIR
13096         rm -f $file
13097
13098         local save_pattern=$(sysctl -n kernel.core_pattern)
13099         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13100         sysctl -w kernel.core_pattern=$file
13101         sysctl -w kernel.core_uses_pid=0
13102
13103         ulimit -c unlimited
13104         sleep 60 &
13105         SLEEPPID=$!
13106
13107         sleep 1
13108
13109         kill -s 11 $SLEEPPID
13110         wait $SLEEPPID
13111         if [ -e $file ]; then
13112                 size=`stat -c%s $file`
13113                 [ $size -eq 0 ] && error "Fail to create core file $file"
13114         else
13115                 error "Fail to create core file $file"
13116         fi
13117         rm -f $file
13118         sysctl -w kernel.core_pattern=$save_pattern
13119         sysctl -w kernel.core_uses_pid=$save_uses_pid
13120         cd $CDIR
13121 }
13122 run_test 107 "Coredump on SIG"
13123
13124 test_110() {
13125         test_mkdir $DIR/$tdir
13126         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13127         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13128                 error "mkdir with 256 char should fail, but did not"
13129         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13130                 error "create with 255 char failed"
13131         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13132                 error "create with 256 char should fail, but did not"
13133
13134         ls -l $DIR/$tdir
13135         rm -rf $DIR/$tdir
13136 }
13137 run_test 110 "filename length checking"
13138
13139 test_116a() { # was previously test_116()
13140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13141         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13142         remote_mds_nodsh && skip "remote MDS with nodsh"
13143
13144         echo -n "Free space priority "
13145         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13146                 head -n1
13147         declare -a AVAIL
13148         free_min_max
13149
13150         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13151         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13152         stack_trap simple_cleanup_common
13153
13154         # Check if we need to generate uneven OSTs
13155         test_mkdir -p $DIR/$tdir/OST${MINI}
13156         local FILL=$((MINV / 4))
13157         local DIFF=$((MAXV - MINV))
13158         local DIFF2=$((DIFF * 100 / MINV))
13159
13160         local threshold=$(do_facet $SINGLEMDS \
13161                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13162         threshold=${threshold%%%}
13163         echo -n "Check for uneven OSTs: "
13164         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13165
13166         if [[ $DIFF2 -gt $threshold ]]; then
13167                 echo "ok"
13168                 echo "Don't need to fill OST$MINI"
13169         else
13170                 # generate uneven OSTs. Write 2% over the QOS threshold value
13171                 echo "no"
13172                 DIFF=$((threshold - DIFF2 + 2))
13173                 DIFF2=$((MINV * DIFF / 100))
13174                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13175                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13176                         error "setstripe failed"
13177                 DIFF=$((DIFF2 / 2048))
13178                 i=0
13179                 while [ $i -lt $DIFF ]; do
13180                         i=$((i + 1))
13181                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13182                                 bs=2M count=1 2>/dev/null
13183                         echo -n .
13184                 done
13185                 echo .
13186                 sync
13187                 sleep_maxage
13188                 free_min_max
13189         fi
13190
13191         DIFF=$((MAXV - MINV))
13192         DIFF2=$((DIFF * 100 / MINV))
13193         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13194         if [ $DIFF2 -gt $threshold ]; then
13195                 echo "ok"
13196         else
13197                 skip "QOS imbalance criteria not met"
13198         fi
13199
13200         MINI1=$MINI
13201         MINV1=$MINV
13202         MAXI1=$MAXI
13203         MAXV1=$MAXV
13204
13205         # now fill using QOS
13206         $LFS setstripe -c 1 $DIR/$tdir
13207         FILL=$((FILL / 200))
13208         if [ $FILL -gt 600 ]; then
13209                 FILL=600
13210         fi
13211         echo "writing $FILL files to QOS-assigned OSTs"
13212         i=0
13213         while [ $i -lt $FILL ]; do
13214                 i=$((i + 1))
13215                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13216                         count=1 2>/dev/null
13217                 echo -n .
13218         done
13219         echo "wrote $i 200k files"
13220         sync
13221         sleep_maxage
13222
13223         echo "Note: free space may not be updated, so measurements might be off"
13224         free_min_max
13225         DIFF2=$((MAXV - MINV))
13226         echo "free space delta: orig $DIFF final $DIFF2"
13227         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13228         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13229         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13230         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13231         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13232         if [[ $DIFF -gt 0 ]]; then
13233                 FILL=$((DIFF2 * 100 / DIFF - 100))
13234                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13235         fi
13236
13237         # Figure out which files were written where
13238         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13239                awk '/'$MINI1': / {print $2; exit}')
13240         echo $UUID
13241         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13242         echo "$MINC files created on smaller OST $MINI1"
13243         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13244                awk '/'$MAXI1': / {print $2; exit}')
13245         echo $UUID
13246         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13247         echo "$MAXC files created on larger OST $MAXI1"
13248         if [[ $MINC -gt 0 ]]; then
13249                 FILL=$((MAXC * 100 / MINC - 100))
13250                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13251         fi
13252         [[ $MAXC -gt $MINC ]] ||
13253                 error_ignore LU-9 "stripe QOS didn't balance free space"
13254 }
13255 run_test 116a "stripe QOS: free space balance ==================="
13256
13257 test_116b() { # LU-2093
13258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13259         remote_mds_nodsh && skip "remote MDS with nodsh"
13260
13261 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13262         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13263                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13264         [ -z "$old_rr" ] && skip "no QOS"
13265         do_facet $SINGLEMDS lctl set_param \
13266                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13267         mkdir -p $DIR/$tdir
13268         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13269         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13270         do_facet $SINGLEMDS lctl set_param fail_loc=0
13271         rm -rf $DIR/$tdir
13272         do_facet $SINGLEMDS lctl set_param \
13273                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13274 }
13275 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13276
13277 test_117() # bug 10891
13278 {
13279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13280
13281         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13282         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13283         lctl set_param fail_loc=0x21e
13284         > $DIR/$tfile || error "truncate failed"
13285         lctl set_param fail_loc=0
13286         echo "Truncate succeeded."
13287         rm -f $DIR/$tfile
13288 }
13289 run_test 117 "verify osd extend =========="
13290
13291 NO_SLOW_RESENDCOUNT=4
13292 export OLD_RESENDCOUNT=""
13293 set_resend_count () {
13294         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13295         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13296         lctl set_param -n $PROC_RESENDCOUNT $1
13297         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13298 }
13299
13300 # for reduce test_118* time (b=14842)
13301 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13302
13303 # Reset async IO behavior after error case
13304 reset_async() {
13305         FILE=$DIR/reset_async
13306
13307         # Ensure all OSCs are cleared
13308         $LFS setstripe -c -1 $FILE
13309         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13310         sync
13311         rm $FILE
13312 }
13313
13314 test_118a() #bug 11710
13315 {
13316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13317
13318         reset_async
13319
13320         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13321         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13322         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13323
13324         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13325                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13326                 return 1;
13327         fi
13328         rm -f $DIR/$tfile
13329 }
13330 run_test 118a "verify O_SYNC works =========="
13331
13332 test_118b()
13333 {
13334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13335         remote_ost_nodsh && skip "remote OST with nodsh"
13336
13337         reset_async
13338
13339         #define OBD_FAIL_SRV_ENOENT 0x217
13340         set_nodes_failloc "$(osts_nodes)" 0x217
13341         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13342         RC=$?
13343         set_nodes_failloc "$(osts_nodes)" 0
13344         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13345         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13346                     grep -c writeback)
13347
13348         if [[ $RC -eq 0 ]]; then
13349                 error "Must return error due to dropped pages, rc=$RC"
13350                 return 1;
13351         fi
13352
13353         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13354                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13355                 return 1;
13356         fi
13357
13358         echo "Dirty pages not leaked on ENOENT"
13359
13360         # Due to the above error the OSC will issue all RPCs syncronously
13361         # until a subsequent RPC completes successfully without error.
13362         $MULTIOP $DIR/$tfile Ow4096yc
13363         rm -f $DIR/$tfile
13364
13365         return 0
13366 }
13367 run_test 118b "Reclaim dirty pages on fatal error =========="
13368
13369 test_118c()
13370 {
13371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13372
13373         # for 118c, restore the original resend count, LU-1940
13374         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13375                                 set_resend_count $OLD_RESENDCOUNT
13376         remote_ost_nodsh && skip "remote OST with nodsh"
13377
13378         reset_async
13379
13380         #define OBD_FAIL_OST_EROFS               0x216
13381         set_nodes_failloc "$(osts_nodes)" 0x216
13382
13383         # multiop should block due to fsync until pages are written
13384         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13385         MULTIPID=$!
13386         sleep 1
13387
13388         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13389                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13390         fi
13391
13392         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13393                     grep -c writeback)
13394         if [[ $WRITEBACK -eq 0 ]]; then
13395                 error "No page in writeback, writeback=$WRITEBACK"
13396         fi
13397
13398         set_nodes_failloc "$(osts_nodes)" 0
13399         wait $MULTIPID
13400         RC=$?
13401         if [[ $RC -ne 0 ]]; then
13402                 error "Multiop fsync failed, rc=$RC"
13403         fi
13404
13405         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13406         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13407                     grep -c writeback)
13408         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13409                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13410         fi
13411
13412         rm -f $DIR/$tfile
13413         echo "Dirty pages flushed via fsync on EROFS"
13414         return 0
13415 }
13416 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13417
13418 # continue to use small resend count to reduce test_118* time (b=14842)
13419 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13420
13421 test_118d()
13422 {
13423         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13424         remote_ost_nodsh && skip "remote OST with nodsh"
13425
13426         reset_async
13427
13428         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13429         set_nodes_failloc "$(osts_nodes)" 0x214
13430         # multiop should block due to fsync until pages are written
13431         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13432         MULTIPID=$!
13433         sleep 1
13434
13435         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13436                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13437         fi
13438
13439         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13440                     grep -c writeback)
13441         if [[ $WRITEBACK -eq 0 ]]; then
13442                 error "No page in writeback, writeback=$WRITEBACK"
13443         fi
13444
13445         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13446         set_nodes_failloc "$(osts_nodes)" 0
13447
13448         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13449         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13450                     grep -c writeback)
13451         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13452                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13453         fi
13454
13455         rm -f $DIR/$tfile
13456         echo "Dirty pages gaurenteed flushed via fsync"
13457         return 0
13458 }
13459 run_test 118d "Fsync validation inject a delay of the bulk =========="
13460
13461 test_118f() {
13462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13463
13464         reset_async
13465
13466         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13467         lctl set_param fail_loc=0x8000040a
13468
13469         # Should simulate EINVAL error which is fatal
13470         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13471         RC=$?
13472         if [[ $RC -eq 0 ]]; then
13473                 error "Must return error due to dropped pages, rc=$RC"
13474         fi
13475
13476         lctl set_param fail_loc=0x0
13477
13478         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13479         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13480         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13481                     grep -c writeback)
13482         if [[ $LOCKED -ne 0 ]]; then
13483                 error "Locked pages remain in cache, locked=$LOCKED"
13484         fi
13485
13486         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13487                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13488         fi
13489
13490         rm -f $DIR/$tfile
13491         echo "No pages locked after fsync"
13492
13493         reset_async
13494         return 0
13495 }
13496 run_test 118f "Simulate unrecoverable OSC side error =========="
13497
13498 test_118g() {
13499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13500
13501         reset_async
13502
13503         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13504         lctl set_param fail_loc=0x406
13505
13506         # simulate local -ENOMEM
13507         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13508         RC=$?
13509
13510         lctl set_param fail_loc=0
13511         if [[ $RC -eq 0 ]]; then
13512                 error "Must return error due to dropped pages, rc=$RC"
13513         fi
13514
13515         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13516         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13517         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13518                         grep -c writeback)
13519         if [[ $LOCKED -ne 0 ]]; then
13520                 error "Locked pages remain in cache, locked=$LOCKED"
13521         fi
13522
13523         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13524                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13525         fi
13526
13527         rm -f $DIR/$tfile
13528         echo "No pages locked after fsync"
13529
13530         reset_async
13531         return 0
13532 }
13533 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13534
13535 test_118h() {
13536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13537         remote_ost_nodsh && skip "remote OST with nodsh"
13538
13539         reset_async
13540
13541         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13542         set_nodes_failloc "$(osts_nodes)" 0x20e
13543         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13544         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13545         RC=$?
13546
13547         set_nodes_failloc "$(osts_nodes)" 0
13548         if [[ $RC -eq 0 ]]; then
13549                 error "Must return error due to dropped pages, rc=$RC"
13550         fi
13551
13552         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13553         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13554         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13555                     grep -c writeback)
13556         if [[ $LOCKED -ne 0 ]]; then
13557                 error "Locked pages remain in cache, locked=$LOCKED"
13558         fi
13559
13560         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13561                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13562         fi
13563
13564         rm -f $DIR/$tfile
13565         echo "No pages locked after fsync"
13566
13567         return 0
13568 }
13569 run_test 118h "Verify timeout in handling recoverables errors  =========="
13570
13571 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13572
13573 test_118i() {
13574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13575         remote_ost_nodsh && skip "remote OST with nodsh"
13576
13577         reset_async
13578
13579         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13580         set_nodes_failloc "$(osts_nodes)" 0x20e
13581
13582         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13583         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13584         PID=$!
13585         sleep 5
13586         set_nodes_failloc "$(osts_nodes)" 0
13587
13588         wait $PID
13589         RC=$?
13590         if [[ $RC -ne 0 ]]; then
13591                 error "got error, but should be not, rc=$RC"
13592         fi
13593
13594         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13595         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13596         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13597         if [[ $LOCKED -ne 0 ]]; then
13598                 error "Locked pages remain in cache, locked=$LOCKED"
13599         fi
13600
13601         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13602                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13603         fi
13604
13605         rm -f $DIR/$tfile
13606         echo "No pages locked after fsync"
13607
13608         return 0
13609 }
13610 run_test 118i "Fix error before timeout in recoverable error  =========="
13611
13612 [ "$SLOW" = "no" ] && set_resend_count 4
13613
13614 test_118j() {
13615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13616         remote_ost_nodsh && skip "remote OST with nodsh"
13617
13618         reset_async
13619
13620         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13621         set_nodes_failloc "$(osts_nodes)" 0x220
13622
13623         # return -EIO from OST
13624         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13625         RC=$?
13626         set_nodes_failloc "$(osts_nodes)" 0x0
13627         if [[ $RC -eq 0 ]]; then
13628                 error "Must return error due to dropped pages, rc=$RC"
13629         fi
13630
13631         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13632         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13633         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13634         if [[ $LOCKED -ne 0 ]]; then
13635                 error "Locked pages remain in cache, locked=$LOCKED"
13636         fi
13637
13638         # in recoverable error on OST we want resend and stay until it finished
13639         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13640                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13641         fi
13642
13643         rm -f $DIR/$tfile
13644         echo "No pages locked after fsync"
13645
13646         return 0
13647 }
13648 run_test 118j "Simulate unrecoverable OST side error =========="
13649
13650 test_118k()
13651 {
13652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13653         remote_ost_nodsh && skip "remote OSTs with nodsh"
13654
13655         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13656         set_nodes_failloc "$(osts_nodes)" 0x20e
13657         test_mkdir $DIR/$tdir
13658
13659         for ((i=0;i<10;i++)); do
13660                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13661                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13662                 SLEEPPID=$!
13663                 sleep 0.500s
13664                 kill $SLEEPPID
13665                 wait $SLEEPPID
13666         done
13667
13668         set_nodes_failloc "$(osts_nodes)" 0
13669         rm -rf $DIR/$tdir
13670 }
13671 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13672
13673 test_118l() # LU-646
13674 {
13675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13676
13677         test_mkdir $DIR/$tdir
13678         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13679         rm -rf $DIR/$tdir
13680 }
13681 run_test 118l "fsync dir"
13682
13683 test_118m() # LU-3066
13684 {
13685         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13686
13687         test_mkdir $DIR/$tdir
13688         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13689         rm -rf $DIR/$tdir
13690 }
13691 run_test 118m "fdatasync dir ========="
13692
13693 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13694
13695 test_118n()
13696 {
13697         local begin
13698         local end
13699
13700         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13701         remote_ost_nodsh && skip "remote OSTs with nodsh"
13702
13703         # Sleep to avoid a cached response.
13704         #define OBD_STATFS_CACHE_SECONDS 1
13705         sleep 2
13706
13707         # Inject a 10 second delay in the OST_STATFS handler.
13708         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13709         set_nodes_failloc "$(osts_nodes)" 0x242
13710
13711         begin=$SECONDS
13712         stat --file-system $MOUNT > /dev/null
13713         end=$SECONDS
13714
13715         set_nodes_failloc "$(osts_nodes)" 0
13716
13717         if ((end - begin > 20)); then
13718             error "statfs took $((end - begin)) seconds, expected 10"
13719         fi
13720 }
13721 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13722
13723 test_119a() # bug 11737
13724 {
13725         BSIZE=$((512 * 1024))
13726         directio write $DIR/$tfile 0 1 $BSIZE
13727         # We ask to read two blocks, which is more than a file size.
13728         # directio will indicate an error when requested and actual
13729         # sizes aren't equeal (a normal situation in this case) and
13730         # print actual read amount.
13731         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13732         if [ "$NOB" != "$BSIZE" ]; then
13733                 error "read $NOB bytes instead of $BSIZE"
13734         fi
13735         rm -f $DIR/$tfile
13736 }
13737 run_test 119a "Short directIO read must return actual read amount"
13738
13739 test_119b() # bug 11737
13740 {
13741         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13742
13743         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13744         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13745         sync
13746         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13747                 error "direct read failed"
13748         rm -f $DIR/$tfile
13749 }
13750 run_test 119b "Sparse directIO read must return actual read amount"
13751
13752 test_119c() # bug 13099
13753 {
13754         BSIZE=1048576
13755         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13756         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13757         rm -f $DIR/$tfile
13758 }
13759 run_test 119c "Testing for direct read hitting hole"
13760
13761 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13762 # Maloo test history
13763
13764 test_119e()
13765 {
13766         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13767                 skip "Need server version at least 2.15.58"
13768         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13769
13770         local stripe_size=$((1024 * 1024)) #1 MiB
13771         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13772         local file_size=$((25 * stripe_size))
13773         local bsizes
13774
13775         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13776         stack_trap "rm -f $DIR/$tfile*"
13777
13778         # Just a bit bigger than the largest size in the test set below
13779         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13780                 error "buffered i/o to create file failed"
13781
13782         # trivial test of unaligned DIO
13783         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13784                 iflag=direct oflag=direct ||
13785                 error "trivial unaligned dio failed"
13786
13787         # Test of disabling unaligned DIO support
13788         $LCTL set_param llite.*.unaligned_dio=0
13789         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13790         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13791         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13792                 iflag=direct oflag=direct &&
13793                 error "unaligned dio succeeded when disabled"
13794         $LCTL set_param llite.*.unaligned_dio=1
13795
13796         # Clean up before next part of test
13797         rm -f $DIR/$tfile.2
13798
13799         if zfs_or_rotational; then
13800                 # DIO on ZFS can take up to 2 seconds per IO
13801                 # rotational is better, but still slow.
13802                 # Limit testing on those media to larger sizes
13803                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13804                         $((stripe_size + 1024))"
13805         else
13806                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13807                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13808                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13809                         $((stripe_size - 1)) $stripe_size \
13810                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13811                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13812         fi
13813
13814         for bs in $bsizes; do
13815                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13816                 echo "Read/write with DIO at size $bs"
13817                 # Read and write with DIO from source to dest
13818                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13819                         iflag=direct oflag=direct ||
13820                         error "dio failed"
13821
13822                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13823                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13824                         error "size incorrect, file copy read/write bsize: $bs"
13825                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13826                         error "files differ, bsize $bs"
13827                 rm -f $DIR/$tfile.2
13828         done
13829 }
13830 run_test 119e "Basic tests of dio read and write at various sizes"
13831
13832 test_119f()
13833 {
13834         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13835
13836         local stripe_size=$((1024 * 1024)) #1 MiB
13837         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13838         local file_size=$((25 * stripe_size))
13839         local bsizes
13840
13841         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13842         stack_trap "rm -f $DIR/$tfile*"
13843
13844         # Just a bit bigger than the largest size in the test set below
13845         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13846                 error "buffered i/o to create file failed"
13847
13848         if zfs_or_rotational; then
13849                 # DIO on ZFS can take up to 2 seconds per IO
13850                 # rotational is better, but still slow.
13851                 # Limit testing on those media to larger sizes
13852                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13853                         $((stripe_size + 1024))"
13854         else
13855                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13856                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13857                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13858                         $((stripe_size - 1)) $stripe_size \
13859                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13860                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13861         fi
13862
13863         for bs in $bsizes; do
13864                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13865                 # Read and write with DIO from source to dest in two
13866                 # threads - should give correct copy of file
13867
13868                 echo "bs: $bs"
13869                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13870                         oflag=direct conv=notrunc &
13871                 pid_dio1=$!
13872                 # Note block size is different here for a more interesting race
13873                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13874                         iflag=direct oflag=direct conv=notrunc &
13875                 pid_dio2=$!
13876                 wait $pid_dio1
13877                 rc1=$?
13878                 wait $pid_dio2
13879                 rc2=$?
13880                 if (( rc1 != 0 )); then
13881                         error "dio copy 1 w/bsize $bs failed: $rc1"
13882                 fi
13883                 if (( rc2 != 0 )); then
13884                         error "dio copy 2 w/bsize $bs failed: $rc2"
13885                 fi
13886
13887
13888                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13889                         error "size incorrect, file copy read/write bsize: $bs"
13890                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13891                         error "files differ, bsize $bs"
13892                 rm -f $DIR/$tfile.2
13893         done
13894 }
13895 run_test 119f "dio vs dio race"
13896
13897 test_119g()
13898 {
13899         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13900
13901         local stripe_size=$((1024 * 1024)) #1 MiB
13902         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13903         local file_size=$((25 * stripe_size))
13904         local bsizes
13905
13906         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13907         stack_trap "rm -f $DIR/$tfile*"
13908
13909         # Just a bit bigger than the largest size in the test set below
13910         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13911                 error "buffered i/o to create file failed"
13912
13913         if zfs_or_rotational; then
13914                 # DIO on ZFS can take up to 2 seconds per IO
13915                 # rotational is better, but still slow.
13916                 # Limit testing on those media to larger sizes
13917                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13918                         $((stripe_size + 1024))"
13919         else
13920                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13921                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13922                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13923                         $((stripe_size - 1)) $stripe_size \
13924                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13925                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13926         fi
13927
13928         for bs in $bsizes; do
13929                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13930                 echo "bs: $bs"
13931                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13932                         oflag=direct conv=notrunc &
13933                 pid_dio1=$!
13934                 # Buffered I/O with similar but not the same block size
13935                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13936                 pid_bio2=$!
13937                 wait $pid_dio1
13938                 rc1=$?
13939                 wait $pid_bio2
13940                 rc2=$?
13941                 if (( rc1 != 0 )); then
13942                         error "dio copy 1 w/bsize $bs failed: $rc1"
13943                 fi
13944                 if (( rc2 != 0 )); then
13945                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13946                 fi
13947
13948                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13949                         error "size incorrect"
13950                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13951                         error "files differ, bsize $bs"
13952                 rm -f $DIR/$tfile.2
13953         done
13954 }
13955 run_test 119g "dio vs buffered I/O race"
13956
13957 test_119h()
13958 {
13959         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13960
13961         local stripe_size=$((1024 * 1024)) #1 MiB
13962         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13963         local file_size=$((25 * stripe_size))
13964         local bsizes
13965
13966         stack_trap "rm -f $DIR/$tfile.*"
13967
13968         if zfs_or_rotational; then
13969                 # DIO on ZFS can take up to 2 seconds per IO
13970                 # rotational is better, but still slow.
13971                 # Limit testing on those media to larger sizes
13972                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13973                         $((stripe_size + 1024))"
13974         else
13975                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13976                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13977                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13978                         $((stripe_size - 1)) $stripe_size \
13979                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13980                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13981         fi
13982
13983         for bs in $bsizes; do
13984                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13985                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13986                 echo "unaligned writes of blocksize: $bs"
13987                 # Write a file with unaligned DIO and regular DIO, and compare
13988                 # them
13989                 # with 'u', multiop randomly unaligns the io from the buffer
13990                 $MULTIOP $DIR/$tfile.1 \
13991                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13992                         error "multiop memory unaligned write failed, $bs"
13993                 $MULTIOP $DIR/$tfile.2 \
13994                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13995                         error "multiop memory aligned write failed, $bs"
13996
13997                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13998                         error "files differ, bsize $bs"
13999                 rm -f $DIR/$tfile.*
14000         done
14001
14002         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14003         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
14004                 error "dd to create source file for read failed"
14005
14006         # Just a few quick tests to make sure unaligned DIO reads don't crash
14007         for bs in $bsizes; do
14008
14009                 echo "unaligned reads of blocksize: $bs"
14010                 # with 'u', multiop randomly unaligns the io from the buffer
14011                 $MULTIOP $DIR/$tfile.1 \
14012                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
14013                         error "multiop memory unaligned read failed, $bs"
14014
14015         done
14016         rm -f $DIR/$tfile*
14017 }
14018 run_test 119h "basic tests of memory unaligned dio"
14019
14020 # aiocp with the '-a' option makes testing memory unaligned aio trivial
14021 test_119i()
14022 {
14023         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14024         which aiocp || skip_env "no aiocp installed"
14025
14026         local stripe_size=$((1024 * 1024)) #1 MiB
14027         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
14028         local file_size=$((25 * stripe_size))
14029         local bsizes
14030
14031         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
14032         stack_trap "rm -f $DIR/$tfile.*"
14033
14034         # Just a bit bigger than the largest size in the test set below
14035         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
14036                 error "buffered i/o to create file failed"
14037
14038         if zfs_or_rotational; then
14039                 # DIO on ZFS can take up to 2 seconds per IO
14040                 # rotational is better, but still slow.
14041                 # Limit testing on those media to larger sizes
14042                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14043                         $((stripe_size + 1024))"
14044         else
14045                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14046                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14047                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14048                         $((stripe_size - 1)) $stripe_size \
14049                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14050                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14051         fi
14052
14053         # Do page aligned and NOT page aligned AIO
14054         for align in 8 512 $((PAGE_SIZE)); do
14055         # Deliberately includes a few aligned sizes
14056         for bs in $bsizes; do
14057                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14058
14059                 echo "bs: $bs, align: $align, file_size $file_size"
14060                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14061                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14062                         error "unaligned aio failed, bs: $bs, align: $align"
14063
14064                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14065                         error "size incorrect"
14066                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14067                         error "files differ"
14068                 rm -f $DIR/$tfile.2
14069         done
14070         done
14071 }
14072 run_test 119i "test unaligned aio at varying sizes"
14073
14074 test_120a() {
14075         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14076         remote_mds_nodsh && skip "remote MDS with nodsh"
14077         test_mkdir -i0 -c1 $DIR/$tdir
14078         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14079                 skip_env "no early lock cancel on server"
14080
14081         lru_resize_disable mdc
14082         lru_resize_disable osc
14083         cancel_lru_locks mdc
14084         # asynchronous object destroy at MDT could cause bl ast to client
14085         cancel_lru_locks osc
14086
14087         stat $DIR/$tdir > /dev/null
14088         can1=$(do_facet mds1 \
14089                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14090                awk '/ldlm_cancel/ {print $2}')
14091         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14092                awk '/ldlm_bl_callback/ {print $2}')
14093         test_mkdir -i0 -c1 $DIR/$tdir/d1
14094         can2=$(do_facet mds1 \
14095                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14096                awk '/ldlm_cancel/ {print $2}')
14097         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14098                awk '/ldlm_bl_callback/ {print $2}')
14099         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14100         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14101         lru_resize_enable mdc
14102         lru_resize_enable osc
14103 }
14104 run_test 120a "Early Lock Cancel: mkdir test"
14105
14106 test_120b() {
14107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14108         remote_mds_nodsh && skip "remote MDS with nodsh"
14109         test_mkdir $DIR/$tdir
14110         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14111                 skip_env "no early lock cancel on server"
14112
14113         lru_resize_disable mdc
14114         lru_resize_disable osc
14115         cancel_lru_locks mdc
14116         stat $DIR/$tdir > /dev/null
14117         can1=$(do_facet $SINGLEMDS \
14118                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14119                awk '/ldlm_cancel/ {print $2}')
14120         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14121                awk '/ldlm_bl_callback/ {print $2}')
14122         touch $DIR/$tdir/f1
14123         can2=$(do_facet $SINGLEMDS \
14124                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14125                awk '/ldlm_cancel/ {print $2}')
14126         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14127                awk '/ldlm_bl_callback/ {print $2}')
14128         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14129         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14130         lru_resize_enable mdc
14131         lru_resize_enable osc
14132 }
14133 run_test 120b "Early Lock Cancel: create test"
14134
14135 test_120c() {
14136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14137         remote_mds_nodsh && skip "remote MDS with nodsh"
14138         test_mkdir -i0 -c1 $DIR/$tdir
14139         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14140                 skip "no early lock cancel on server"
14141
14142         lru_resize_disable mdc
14143         lru_resize_disable osc
14144         test_mkdir -i0 -c1 $DIR/$tdir/d1
14145         test_mkdir -i0 -c1 $DIR/$tdir/d2
14146         touch $DIR/$tdir/d1/f1
14147         cancel_lru_locks mdc
14148         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14149         can1=$(do_facet mds1 \
14150                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14151                awk '/ldlm_cancel/ {print $2}')
14152         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14153                awk '/ldlm_bl_callback/ {print $2}')
14154         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14155         can2=$(do_facet mds1 \
14156                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14157                awk '/ldlm_cancel/ {print $2}')
14158         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14159                awk '/ldlm_bl_callback/ {print $2}')
14160         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14161         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14162         lru_resize_enable mdc
14163         lru_resize_enable osc
14164 }
14165 run_test 120c "Early Lock Cancel: link test"
14166
14167 test_120d() {
14168         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14169         remote_mds_nodsh && skip "remote MDS with nodsh"
14170         test_mkdir -i0 -c1 $DIR/$tdir
14171         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14172                 skip_env "no early lock cancel on server"
14173
14174         lru_resize_disable mdc
14175         lru_resize_disable osc
14176         touch $DIR/$tdir
14177         cancel_lru_locks mdc
14178         stat $DIR/$tdir > /dev/null
14179         can1=$(do_facet mds1 \
14180                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14181                awk '/ldlm_cancel/ {print $2}')
14182         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14183                awk '/ldlm_bl_callback/ {print $2}')
14184         chmod a+x $DIR/$tdir
14185         can2=$(do_facet mds1 \
14186                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14187                awk '/ldlm_cancel/ {print $2}')
14188         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14189                awk '/ldlm_bl_callback/ {print $2}')
14190         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14191         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14192         lru_resize_enable mdc
14193         lru_resize_enable osc
14194 }
14195 run_test 120d "Early Lock Cancel: setattr test"
14196
14197 test_120e() {
14198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14199         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14200                 skip_env "no early lock cancel on server"
14201         remote_mds_nodsh && skip "remote MDS with nodsh"
14202
14203         local dlmtrace_set=false
14204
14205         test_mkdir -i0 -c1 $DIR/$tdir
14206         lru_resize_disable mdc
14207         lru_resize_disable osc
14208         ! $LCTL get_param debug | grep -q dlmtrace &&
14209                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14210         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14211         cancel_lru_locks mdc
14212         cancel_lru_locks osc
14213         dd if=$DIR/$tdir/f1 of=/dev/null
14214         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14215         # XXX client can not do early lock cancel of OST lock
14216         # during unlink (LU-4206), so cancel osc lock now.
14217         sleep 2
14218         cancel_lru_locks osc
14219         can1=$(do_facet mds1 \
14220                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14221                awk '/ldlm_cancel/ {print $2}')
14222         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14223                awk '/ldlm_bl_callback/ {print $2}')
14224         unlink $DIR/$tdir/f1
14225         sleep 5
14226         can2=$(do_facet mds1 \
14227                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14228                awk '/ldlm_cancel/ {print $2}')
14229         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14230                awk '/ldlm_bl_callback/ {print $2}')
14231         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14232                 $LCTL dk $TMP/cancel.debug.txt
14233         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14234                 $LCTL dk $TMP/blocking.debug.txt
14235         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14236         lru_resize_enable mdc
14237         lru_resize_enable osc
14238 }
14239 run_test 120e "Early Lock Cancel: unlink test"
14240
14241 test_120f() {
14242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14243         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14244                 skip_env "no early lock cancel on server"
14245         remote_mds_nodsh && skip "remote MDS with nodsh"
14246
14247         test_mkdir -i0 -c1 $DIR/$tdir
14248         lru_resize_disable mdc
14249         lru_resize_disable osc
14250         test_mkdir -i0 -c1 $DIR/$tdir/d1
14251         test_mkdir -i0 -c1 $DIR/$tdir/d2
14252         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14253         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14254         cancel_lru_locks mdc
14255         cancel_lru_locks osc
14256         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14257         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14258         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14259         # XXX client can not do early lock cancel of OST lock
14260         # during rename (LU-4206), so cancel osc lock now.
14261         sleep 2
14262         cancel_lru_locks osc
14263         can1=$(do_facet mds1 \
14264                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14265                awk '/ldlm_cancel/ {print $2}')
14266         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14267                awk '/ldlm_bl_callback/ {print $2}')
14268         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14269         sleep 5
14270         can2=$(do_facet mds1 \
14271                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14272                awk '/ldlm_cancel/ {print $2}')
14273         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14274                awk '/ldlm_bl_callback/ {print $2}')
14275         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14276         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14277         lru_resize_enable mdc
14278         lru_resize_enable osc
14279 }
14280 run_test 120f "Early Lock Cancel: rename test"
14281
14282 test_120g() {
14283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14284         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14285                 skip_env "no early lock cancel on server"
14286         remote_mds_nodsh && skip "remote MDS with nodsh"
14287
14288         lru_resize_disable mdc
14289         lru_resize_disable osc
14290         count=10000
14291         echo create $count files
14292         test_mkdir $DIR/$tdir
14293         cancel_lru_locks mdc
14294         cancel_lru_locks osc
14295         t0=$(date +%s)
14296
14297         can0=$(do_facet $SINGLEMDS \
14298                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14299                awk '/ldlm_cancel/ {print $2}')
14300         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14301                awk '/ldlm_bl_callback/ {print $2}')
14302         createmany -o $DIR/$tdir/f $count
14303         sync
14304         can1=$(do_facet $SINGLEMDS \
14305                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14306                awk '/ldlm_cancel/ {print $2}')
14307         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14308                awk '/ldlm_bl_callback/ {print $2}')
14309         t1=$(date +%s)
14310         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14311         echo rm $count files
14312         rm -r $DIR/$tdir
14313         sync
14314         can2=$(do_facet $SINGLEMDS \
14315                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14316                awk '/ldlm_cancel/ {print $2}')
14317         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14318                awk '/ldlm_bl_callback/ {print $2}')
14319         t2=$(date +%s)
14320         echo total: $count removes in $((t2-t1))
14321         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14322         sleep 2
14323         # wait for commitment of removal
14324         lru_resize_enable mdc
14325         lru_resize_enable osc
14326 }
14327 run_test 120g "Early Lock Cancel: performance test"
14328
14329 test_121() { #bug #10589
14330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14331
14332         rm -rf $DIR/$tfile
14333         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14334 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14335         lctl set_param fail_loc=0x310
14336         cancel_lru_locks osc > /dev/null
14337         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14338         lctl set_param fail_loc=0
14339         [[ $reads -eq $writes ]] ||
14340                 error "read $reads blocks, must be $writes blocks"
14341 }
14342 run_test 121 "read cancel race ========="
14343
14344 test_123a_base() { # was test 123, statahead(bug 11401)
14345         local lsx="$1"
14346
14347         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14348
14349         SLOWOK=0
14350         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14351                 log "testing UP system. Performance may be lower than expected."
14352                 SLOWOK=1
14353         fi
14354         running_in_vm && SLOWOK=1
14355
14356         $LCTL set_param mdc.*.batch_stats=0
14357
14358         rm -rf $DIR/$tdir
14359         test_mkdir $DIR/$tdir
14360         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14361         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14362         MULT=10
14363         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14364                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14365
14366                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14367                 lctl set_param -n llite.*.statahead_max 0
14368                 lctl get_param llite.*.statahead_max
14369                 cancel_lru_locks mdc
14370                 cancel_lru_locks osc
14371                 stime=$(date +%s)
14372                 time $lsx $DIR/$tdir | wc -l
14373                 etime=$(date +%s)
14374                 delta=$((etime - stime))
14375                 log "$lsx $i files without statahead: $delta sec"
14376                 lctl set_param llite.*.statahead_max=$max
14377
14378                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14379                          awk '/statahead.wrong:/ { print $NF }')
14380                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14381                 cancel_lru_locks mdc
14382                 cancel_lru_locks osc
14383                 stime=$(date +%s)
14384                 time $lsx $DIR/$tdir | wc -l
14385                 etime=$(date +%s)
14386                 delta_sa=$((etime - stime))
14387                 log "$lsx $i files with statahead: $delta_sa sec"
14388                 lctl get_param -n llite.*.statahead_stats
14389                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14390                          awk '/statahead.wrong:/ { print $NF }')
14391
14392                 [[ $swrong -lt $ewrong ]] &&
14393                         log "statahead was stopped, maybe too many locks held!"
14394                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14395
14396                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14397                         max=$(lctl get_param -n llite.*.statahead_max |
14398                                 head -n 1)
14399                         lctl set_param -n llite.*.statahead_max 0
14400                         lctl get_param llite.*.statahead_max
14401                         cancel_lru_locks mdc
14402                         cancel_lru_locks osc
14403                         stime=$(date +%s)
14404                         time $lsx $DIR/$tdir | wc -l
14405                         etime=$(date +%s)
14406                         delta=$((etime - stime))
14407                         log "$lsx $i files again without statahead: $delta sec"
14408                         lctl set_param llite.*.statahead_max=$max
14409                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14410                                 if [ $SLOWOK -eq 0 ]; then
14411                                         error "$lsx $i files is slower with statahead!"
14412                                 else
14413                                         log "$lsx $i files is slower with statahead!"
14414                                 fi
14415                                 break
14416                         fi
14417                 fi
14418
14419                 [ $delta -gt 20 ] && break
14420                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14421                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14422         done
14423         log "$lsx done"
14424
14425         stime=$(date +%s)
14426         rm -r $DIR/$tdir
14427         sync
14428         etime=$(date +%s)
14429         delta=$((etime - stime))
14430         log "rm -r $DIR/$tdir/: $delta seconds"
14431         log "rm done"
14432         lctl get_param -n llite.*.statahead_stats
14433         $LCTL get_param mdc.*.batch_stats
14434 }
14435
14436 test_123aa() {
14437         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14438
14439         test_123a_base "ls -l"
14440 }
14441 run_test 123aa "verify statahead work"
14442
14443 test_123ab() {
14444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14445
14446         statx_supported || skip_env "Test must be statx() syscall supported"
14447
14448         test_123a_base "$STATX -l"
14449 }
14450 run_test 123ab "verify statahead work by using statx"
14451
14452 test_123ac() {
14453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14454
14455         statx_supported || skip_env "Test must be statx() syscall supported"
14456
14457         local rpcs_before
14458         local rpcs_after
14459         local agl_before
14460         local agl_after
14461
14462         cancel_lru_locks $OSC
14463         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14464         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14465                      awk '/agl.total:/ { print $NF }')
14466         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14467         test_123a_base "$STATX --cached=always -D"
14468         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14469                     awk '/agl.total:/ { print $NF }')
14470         [ $agl_before -eq $agl_after ] ||
14471                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14472         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14473         [ $rpcs_after -eq $rpcs_before ] ||
14474                 error "$STATX should not send glimpse RPCs to $OSC"
14475 }
14476 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14477
14478 test_batch_statahead() {
14479         local max=$1
14480         local batch_max=$2
14481         local num=10000
14482         local batch_rpcs
14483         local unbatch_rpcs
14484         local hit_total
14485
14486         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14487         $LCTL set_param mdc.*.batch_stats=0
14488         $LCTL set_param llite.*.statahead_max=$max
14489         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14490         # Verify that batched statahead is faster than one without statahead
14491         test_123a_base "ls -l"
14492
14493         stack_trap "rm -rf $DIR/$tdir" EXIT
14494         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14495         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14496
14497         # unbatched statahead
14498         $LCTL set_param llite.*.statahead_batch_max=0
14499         $LCTL set_param llite.*.statahead_stats=clear
14500         $LCTL set_param mdc.*.stats=clear
14501         cancel_lru_locks mdc
14502         cancel_lru_locks osc
14503         time ls -l $DIR/$tdir | wc -l
14504         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14505         wait_update_facet client "pgrep ll_sa" "" 35 ||
14506                 error "ll_sa thread is still running"
14507         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14508                     awk '/hit.total:/ { print $NF }')
14509         # hit ratio should be larger than 75% (7500).
14510         (( $hit_total > 7500 )) ||
14511                 error "unbatched statahead hit count ($hit_total) is too low"
14512
14513         # batched statahead
14514         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14515         $LCTL set_param llite.*.statahead_stats=clear
14516         $LCTL set_param mdc.*.batch_stats=clear
14517         $LCTL set_param mdc.*.stats=clear
14518         cancel_lru_locks mdc
14519         cancel_lru_locks osc
14520         time ls -l $DIR/$tdir | wc -l
14521         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14522         # wait for statahead thread to quit and update statahead stats
14523         wait_update_facet client "pgrep ll_sa" "" 35 ||
14524                 error "ll_sa thread is still running"
14525         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14526                     awk '/hit.total:/ { print $NF }')
14527         # hit ratio should be larger than 75% (7500).
14528         (( $hit_total > 7500 )) ||
14529                 error "batched statahead hit count ($hit_total) is too low"
14530
14531         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14532         (( $unbatch_rpcs > $batch_rpcs )) ||
14533                 error "batched statahead does not reduce RPC count"
14534         $LCTL get_param mdc.*.batch_stats
14535 }
14536
14537 test_123ad() {
14538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14539
14540         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14541                 skip "Need server version at least 2.15.53"
14542
14543         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14544                 skip "Server does not support batch RPC"
14545
14546         local max
14547         local batch_max
14548
14549         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14550         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14551
14552         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14553         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14554
14555         test_batch_statahead 32 32
14556         test_batch_statahead 2048 256
14557 }
14558 run_test 123ad "Verify batching statahead works correctly"
14559
14560 test_123b () { # statahead(bug 15027)
14561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14562
14563         test_mkdir $DIR/$tdir
14564         createmany -o $DIR/$tdir/$tfile-%d 1000
14565
14566         cancel_lru_locks mdc
14567         cancel_lru_locks osc
14568
14569 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14570         lctl set_param fail_loc=0x80000803
14571         ls -lR $DIR/$tdir > /dev/null
14572         log "ls done"
14573         lctl set_param fail_loc=0x0
14574         lctl get_param -n llite.*.statahead_stats
14575         rm -r $DIR/$tdir
14576         sync
14577
14578 }
14579 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14580
14581 test_123c() {
14582         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14583
14584         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14585         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14586         touch $DIR/$tdir.1/{1..3}
14587         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14588
14589         remount_client $MOUNT
14590
14591         $MULTIOP $DIR/$tdir.0 Q
14592
14593         # let statahead to complete
14594         ls -l $DIR/$tdir.0 > /dev/null
14595
14596         testid=$(echo $TESTNAME | tr '_' ' ')
14597         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14598                 error "statahead warning" || true
14599 }
14600 run_test 123c "Can not initialize inode warning on DNE statahead"
14601
14602 test_123d() {
14603         local num=100
14604         local swrong
14605         local ewrong
14606
14607         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14608         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14609                 error "setdirstripe $DIR/$tdir failed"
14610         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14611         remount_client $MOUNT
14612         $LCTL get_param llite.*.statahead_max
14613         $LCTL set_param llite.*.statahead_stats=0 ||
14614                 error "clear statahead_stats failed"
14615         swrong=$(lctl get_param -n llite.*.statahead_stats |
14616                  awk '/statahead.wrong:/ { print $NF }')
14617         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14618         # wait for statahead thread finished to update hit/miss stats.
14619         sleep 1
14620         $LCTL get_param -n llite.*.statahead_stats
14621         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14622                  awk '/statahead.wrong:/ { print $NF }')
14623         (( $swrong == $ewrong )) ||
14624                 log "statahead was stopped, maybe too many locks held!"
14625 }
14626 run_test 123d "Statahead on striped directories works correctly"
14627
14628 test_123e() {
14629         local max
14630         local batch_max
14631         local dir=$DIR/$tdir
14632
14633         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14634                 skip "Server does not support batch RPC"
14635
14636         mkdir $dir || error "mkdir $dir failed"
14637         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14638         stack_trap "rm -rf $dir"
14639
14640         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14641
14642         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14643         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14644         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14645         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14646
14647         $LCTL set_param llite.*.statahead_max=2048
14648         $LCTL set_param llite.*.statahead_batch_max=1024
14649
14650         ls -l $dir
14651         $LCTL get_param mdc.*.batch_stats
14652         $LCTL get_param llite.*.statahead_*
14653 }
14654 run_test 123e "statahead with large wide striping"
14655
14656 test_123f() {
14657         local max
14658         local batch_max
14659         local dir=$DIR/$tdir
14660
14661         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14662                 skip "Server does not support batch RPC"
14663
14664         mkdir $dir || error "mkdir $dir failed"
14665         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14666         stack_trap "rm -rf $dir"
14667
14668         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14669
14670         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14671         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14672
14673         $LCTL set_param llite.*.statahead_max=64
14674         $LCTL set_param llite.*.statahead_batch_max=64
14675
14676         ls -l $dir
14677         lctl get_param mdc.*.batch_stats
14678         lctl get_param llite.*.statahead_*
14679
14680         $LCTL set_param llite.*.statahead_max=$max
14681         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14682 }
14683 run_test 123f "Retry mechanism with large wide striping files"
14684
14685 test_123g() {
14686         local dir=$DIR/$tdir
14687         local num=1000
14688
14689         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14690                 skip "Server does not support batch RPC"
14691
14692         mkdir $dir || error "failed to mkdir $dir"
14693         createmany -o $dir/$tfile $num || error "failed creatmany files"
14694         cancel_lru_locks mdc
14695         cancel_lru_locks osc
14696
14697         $LCTL set_param llite.*.statahead_stats=clear
14698         $LCTL set_param mdc.*.batch_stats=clear
14699         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14700                 error "aheadmany $dir with $tfile failed"
14701         wait_update_facet client "pgrep ll_sa" "" 35 ||
14702                 error "ll_sa thread is still running"
14703         $LCTL get_param -n llite.*.statahead_stats
14704         $LCTL get_param -n mdc.*.batch_stats
14705
14706         local count
14707
14708         count=$($LCTL get_param -n llite.*.statahead_stats |
14709                 awk '/hit.total:/ {print $2}')
14710         echo "Hit total: $count"
14711         # Hit ratio should be >= 75%
14712         (( $count > num * 75 / 100 )) ||
14713                 error "hit total $count is be > 75% of $num"
14714 }
14715 run_test 123g "Test for stat-ahead advise"
14716
14717 test_123h_base() {
14718         local dir=$DIR/$tdir
14719         local cmd="touch $dir/$tfile.{$1}"
14720         local fcnt=$2
14721
14722         stack_trap "rm -rf $dir"
14723         mkdir -p $dir || error "failed to mkdir $dir"
14724         eval $cmd
14725
14726         cancel_lru_locks mdc
14727         $LCTL set_param llite.*.statahead_stats=clear
14728         $LCTL set_param mdc.*.batch_stats=0
14729         $LCTL set_param llite.*.statahead_max=1024
14730         $LCTL set_param llite.*.statahead_batch_max=1024
14731         lctl get_param -n llite.*.statahead_stats
14732         du -a $dir > /dev/null
14733         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14734         wait_update_facet client "pgrep ll_sa" "" 35 ||
14735                 error "ll_sa statahead thread does not quit in 35s"
14736         $LCTL get_param -n llite.*.statahead_stats
14737         $LCTL get_param -n mdc.*.batch_stats
14738
14739         local count=$($LCTL get_param -n llite.*.statahead_stats |
14740                         awk '/fname.total:/ {print $2}')
14741
14742         [ $count == 1 ] || error "File name pattern statahead not trigger"
14743         count=$($LCTL get_param -n llite.*.statahead_stats |
14744                 awk '/hit.total:/ {print $2}')
14745         # Hit ratio should be >= 75%
14746         (( $count > fcnt * 75 / 100 )) ||
14747                 error "hit total is too low: $count"
14748         rm -rf $dir || error "rm -rf $dir failed"
14749 }
14750
14751 test_123h() {
14752         local max
14753         local batch_max
14754         local enabled
14755
14756         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14757                 skip "Server does not support batch RPC"
14758
14759         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14760         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14761         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14762         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14763         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14764         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14765
14766         $LCTL set_param llite.*.enable_statahead_fname=1
14767
14768         echo "Scan a directory with number regularized fname"
14769         test_123h_base "0..10000" 10000
14770
14771         echo "Scan a directory with zeroed padding number regularized fname"
14772         test_123h_base "000000..010000" 10000
14773 }
14774 run_test 123h "Verify statahead work with the fname pattern via du"
14775
14776 test_123i_base() {
14777         local fmt=$1
14778         local iocmd=$2
14779         local dir=$DIR/$tdir
14780         local cmd="createmany -m $fmt"
14781
14782         echo "Command:"
14783         echo "- $cmd"
14784         echo "- $iocmd"
14785         stack_trap "unlinkmany $fmt"
14786         mkdir -p $dir || error "failed to mkdir $dir"
14787         eval $cmd
14788
14789         cancel_lru_locks mdc
14790         $LCTL set_param llite.*.statahead_stats=clear
14791         $LCTL set_param mdc.*.batch_stats=0
14792
14793         echo "statahead_stats (Pre):"
14794         lctl get_param -n llite.*.statahead_stats
14795         eval $iocmd || error "$iocmd failed"
14796         echo "statahead_stats (Post):"
14797         $LCTL get_param -n llite.*.statahead_stats
14798         $LCTL get_param -n mdc.*.batch_stats
14799
14800         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14801         wait_update_facet client "pgrep ll_sa" "" 35 ||
14802                 error "ll_sa statahead thread does not quit in 35s"
14803         $LCTL get_param -n llite.*.statahead_stats
14804         $LCTL get_param -n mdc.*.batch_stats
14805
14806         local count=$($LCTL get_param -n llite.*.statahead_stats |
14807                         awk '/fname.total:/ {print $2}')
14808
14809         [ $count == 1 ] || error "File name pattern statahead not trigger"
14810         count=$($LCTL get_param -n llite.*.statahead_stats |
14811                 awk '/hit.total:/ {print $2}')
14812         # Hit ratio should be >= 75%
14813         (( $count > 750 )) || error "hit total is too low: $count"
14814 }
14815
14816 test_123i() {
14817         local dir=$DIR/$tdir
14818         local cnt=1000
14819         local max
14820         local batch_max
14821         local enabled
14822         local min
14823
14824         $LCTL get_param -n mdc.*.connect_flags | grep -q batch_rpc ||
14825                 skip "Server does not support batch RPC"
14826
14827         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14828         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14829         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14830         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14831         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14832         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14833         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14834         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14835         $LCTL set_param llite.*.statahead_max=1024
14836         $LCTL set_param llite.*.statahead_batch_max=32
14837         $LCTL set_param llite.*.statahead_min=64
14838         $LCTL set_param llite.*.enable_statahead_fname=1
14839
14840         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14841         test_123i_base "$dir/$tfile $cnt" \
14842                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14843 }
14844 run_test 123i "Verify statahead work with the fname indexing pattern"
14845
14846 test_124a() {
14847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14848         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14849                 skip_env "no lru resize on server"
14850
14851         local NR=2000
14852
14853         test_mkdir $DIR/$tdir
14854
14855         log "create $NR files at $DIR/$tdir"
14856         createmany -o $DIR/$tdir/f $NR ||
14857                 error "failed to create $NR files in $DIR/$tdir"
14858
14859         cancel_lru_locks mdc
14860         ls -l $DIR/$tdir > /dev/null
14861
14862         local NSDIR=""
14863         local LRU_SIZE=0
14864         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14865                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14866                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14867                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14868                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14869                         log "NSDIR=$NSDIR"
14870                         log "NS=$(basename $NSDIR)"
14871                         break
14872                 fi
14873         done
14874
14875         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14876                 skip "Not enough cached locks created!"
14877         fi
14878         log "LRU=$LRU_SIZE"
14879
14880         local SLEEP=30
14881
14882         # We know that lru resize allows one client to hold $LIMIT locks
14883         # for 10h. After that locks begin to be killed by client.
14884         local MAX_HRS=10
14885         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14886         log "LIMIT=$LIMIT"
14887         if [ $LIMIT -lt $LRU_SIZE ]; then
14888                 skip "Limit is too small $LIMIT"
14889         fi
14890
14891         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14892         # killing locks. Some time was spent for creating locks. This means
14893         # that up to the moment of sleep finish we must have killed some of
14894         # them (10-100 locks). This depends on how fast ther were created.
14895         # Many of them were touched in almost the same moment and thus will
14896         # be killed in groups.
14897         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14898
14899         # Use $LRU_SIZE_B here to take into account real number of locks
14900         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14901         local LRU_SIZE_B=$LRU_SIZE
14902         log "LVF=$LVF"
14903         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14904         log "OLD_LVF=$OLD_LVF"
14905         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14906
14907         # Let's make sure that we really have some margin. Client checks
14908         # cached locks every 10 sec.
14909         SLEEP=$((SLEEP+20))
14910         log "Sleep ${SLEEP} sec"
14911         local SEC=0
14912         while ((SEC<$SLEEP)); do
14913                 echo -n "..."
14914                 sleep 5
14915                 SEC=$((SEC+5))
14916                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14917                 echo -n "$LRU_SIZE"
14918         done
14919         echo ""
14920         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14921         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14922
14923         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14924                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14925                 unlinkmany $DIR/$tdir/f $NR
14926                 return
14927         }
14928
14929         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14930         log "unlink $NR files at $DIR/$tdir"
14931         unlinkmany $DIR/$tdir/f $NR
14932 }
14933 run_test 124a "lru resize ======================================="
14934
14935 get_max_pool_limit()
14936 {
14937         local limit=$($LCTL get_param \
14938                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14939         local max=0
14940         for l in $limit; do
14941                 if [[ $l -gt $max ]]; then
14942                         max=$l
14943                 fi
14944         done
14945         echo $max
14946 }
14947
14948 test_124b() {
14949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14950         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14951                 skip_env "no lru resize on server"
14952
14953         LIMIT=$(get_max_pool_limit)
14954
14955         NR=$(($(default_lru_size)*20))
14956         if [[ $NR -gt $LIMIT ]]; then
14957                 log "Limit lock number by $LIMIT locks"
14958                 NR=$LIMIT
14959         fi
14960
14961         IFree=$(mdsrate_inodes_available)
14962         if [ $IFree -lt $NR ]; then
14963                 log "Limit lock number by $IFree inodes"
14964                 NR=$IFree
14965         fi
14966
14967         lru_resize_disable mdc
14968         test_mkdir -p $DIR/$tdir/disable_lru_resize
14969
14970         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14971         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14972         cancel_lru_locks mdc
14973         stime=`date +%s`
14974         PID=""
14975         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14976         PID="$PID $!"
14977         sleep 2
14978         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14979         PID="$PID $!"
14980         sleep 2
14981         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14982         PID="$PID $!"
14983         wait $PID
14984         etime=`date +%s`
14985         nolruresize_delta=$((etime-stime))
14986         log "ls -la time: $nolruresize_delta seconds"
14987         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14988         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14989
14990         lru_resize_enable mdc
14991         test_mkdir -p $DIR/$tdir/enable_lru_resize
14992
14993         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14994         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14995         cancel_lru_locks mdc
14996         stime=`date +%s`
14997         PID=""
14998         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14999         PID="$PID $!"
15000         sleep 2
15001         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15002         PID="$PID $!"
15003         sleep 2
15004         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
15005         PID="$PID $!"
15006         wait $PID
15007         etime=`date +%s`
15008         lruresize_delta=$((etime-stime))
15009         log "ls -la time: $lruresize_delta seconds"
15010         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
15011
15012         if [ $lruresize_delta -gt $nolruresize_delta ]; then
15013                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
15014         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
15015                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
15016         else
15017                 log "lru resize performs the same with no lru resize"
15018         fi
15019         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
15020 }
15021 run_test 124b "lru resize (performance test) ======================="
15022
15023 test_124c() {
15024         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15025         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15026                 skip_env "no lru resize on server"
15027
15028         # cache ununsed locks on client
15029         local nr=100
15030         cancel_lru_locks mdc
15031         test_mkdir $DIR/$tdir
15032         createmany -o $DIR/$tdir/f $nr ||
15033                 error "failed to create $nr files in $DIR/$tdir"
15034         ls -l $DIR/$tdir > /dev/null
15035
15036         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15037         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15038         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15039         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15040         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15041
15042         # set lru_max_age to 1 sec
15043         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15044         echo "sleep $((recalc_p * 2)) seconds..."
15045         sleep $((recalc_p * 2))
15046
15047         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15048         # restore lru_max_age
15049         $LCTL set_param -n $nsdir.lru_max_age $max_age
15050         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15051         unlinkmany $DIR/$tdir/f $nr
15052 }
15053 run_test 124c "LRUR cancel very aged locks"
15054
15055 test_124d() {
15056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15057         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15058                 skip_env "no lru resize on server"
15059
15060         # cache ununsed locks on client
15061         local nr=100
15062
15063         lru_resize_disable mdc
15064         stack_trap "lru_resize_enable mdc" EXIT
15065
15066         cancel_lru_locks mdc
15067
15068         # asynchronous object destroy at MDT could cause bl ast to client
15069         test_mkdir $DIR/$tdir
15070         createmany -o $DIR/$tdir/f $nr ||
15071                 error "failed to create $nr files in $DIR/$tdir"
15072         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15073
15074         ls -l $DIR/$tdir > /dev/null
15075
15076         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15077         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15078         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15079         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15080
15081         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15082
15083         # set lru_max_age to 1 sec
15084         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15085         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15086
15087         echo "sleep $((recalc_p * 2)) seconds..."
15088         sleep $((recalc_p * 2))
15089
15090         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15091
15092         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15093 }
15094 run_test 124d "cancel very aged locks if lru-resize disabled"
15095
15096 test_125() { # 13358
15097         $LCTL get_param -n llite.*.client_type | grep -q local ||
15098                 skip "must run as local client"
15099         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15100                 skip_env "must have acl enabled"
15101         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15102         id $USER0 || skip_env "missing user $USER0"
15103
15104         test_mkdir $DIR/$tdir
15105         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15106         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15107                 error "setfacl $DIR/$tdir failed"
15108         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15109 }
15110 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15111
15112 test_126() { # bug 12829/13455
15113         $GSS && skip_env "must run as gss disabled"
15114         $LCTL get_param -n llite.*.client_type | grep -q local ||
15115                 skip "must run as local client"
15116         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15117
15118         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15119         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15120         rm -f $DIR/$tfile
15121         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15122 }
15123 run_test 126 "check that the fsgid provided by the client is taken into account"
15124
15125 test_127a() { # bug 15521
15126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15127         local name count samp unit min max sum sumsq
15128         local tmpfile=$TMP/$tfile.tmp
15129
15130         # enable stats header if it is disabled
15131         $LCTL set_param enable_stats_header=1
15132
15133         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15134         echo "stats before reset"
15135         stack_trap "rm -f $tmpfile"
15136         local now=$(date +%s)
15137
15138         $LCTL get_param osc.*.stats | tee $tmpfile
15139
15140         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15141         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15142         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15143         local uptime=$(awk '{ print $1 }' /proc/uptime)
15144
15145         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15146         (( ${snapshot_time%\.*} >= $now - 5 &&
15147            ${snapshot_time%\.*} <= $now + 5 )) ||
15148                 error "snapshot_time=$snapshot_time != now=$now"
15149         # elapsed _should_ be from mount, but at least less than uptime
15150         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15151                 error "elapsed=$elapsed > uptime=$uptime"
15152         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15153            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15154                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15155
15156         $LCTL set_param osc.*.stats=0
15157         local reset=$(date +%s)
15158         local fsize=$((2048 * 1024))
15159
15160         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15161         cancel_lru_locks osc
15162         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15163
15164         now=$(date +%s)
15165         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15166         while read name count samp unit min max sum sumsq; do
15167                 [[ "$samp" == "samples" ]] || continue
15168
15169                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15170                 [ ! $min ] && error "Missing min value for $name proc entry"
15171                 eval $name=$count || error "Wrong proc format"
15172
15173                 case $name in
15174                 read_bytes|write_bytes)
15175                         [[ "$unit" =~ "bytes" ]] ||
15176                                 error "unit is not 'bytes': $unit"
15177                         (( $min >= 4096 )) || error "min is too small: $min"
15178                         (( $min <= $fsize )) || error "min is too big: $min"
15179                         (( $max >= 4096 )) || error "max is too small: $max"
15180                         (( $max <= $fsize )) || error "max is too big: $max"
15181                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15182                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15183                                 error "sumsquare is too small: $sumsq"
15184                         (( $sumsq <= $fsize * $fsize )) ||
15185                                 error "sumsquare is too big: $sumsq"
15186                         ;;
15187                 ost_read|ost_write)
15188                         [[ "$unit" =~ "usec" ]] ||
15189                                 error "unit is not 'usec': $unit"
15190                         ;;
15191                 *)      ;;
15192                 esac
15193         done < $tmpfile
15194
15195         #check that we actually got some stats
15196         [ "$read_bytes" ] || error "Missing read_bytes stats"
15197         [ "$write_bytes" ] || error "Missing write_bytes stats"
15198         [ "$read_bytes" != 0 ] || error "no read done"
15199         [ "$write_bytes" != 0 ] || error "no write done"
15200
15201         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15202         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15203         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15204
15205         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15206         (( ${snapshot_time%\.*} >= $now - 5 &&
15207            ${snapshot_time%\.*} <= $now + 5 )) ||
15208                 error "reset snapshot_time=$snapshot_time != now=$now"
15209         # elapsed should be from time of stats reset
15210         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15211            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15212                 error "reset elapsed=$elapsed > $now - $reset"
15213         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15214            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15215                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15216 }
15217 run_test 127a "verify the client stats are sane"
15218
15219 test_127b() { # bug LU-333
15220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15221         local name count samp unit min max sum sumsq
15222
15223         echo "stats before reset"
15224         $LCTL get_param llite.*.stats
15225         $LCTL set_param llite.*.stats=0
15226
15227         # perform 2 reads and writes so MAX is different from SUM.
15228         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15229         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15230         cancel_lru_locks osc
15231         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15232         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15233
15234         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15235         stack_trap "rm -f $TMP/$tfile.tmp"
15236         while read name count samp unit min max sum sumsq; do
15237                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15238                 eval $name=$count || error "Wrong proc format"
15239
15240                 case $name in
15241                 read_bytes|write_bytes)
15242                         [[ "$unit" =~ "bytes" ]] ||
15243                                 error "unit is not 'bytes': $unit"
15244                         (( $count == 2 )) || error "count is not 2: $count"
15245                         (( $min == $PAGE_SIZE )) ||
15246                                 error "min is not $PAGE_SIZE: $min"
15247                         (( $max == $PAGE_SIZE )) ||
15248                                 error "max is not $PAGE_SIZE: $max"
15249                         (( $sum == $PAGE_SIZE * 2 )) ||
15250                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15251                         ;;
15252                 read|write)
15253                         [[ "$unit" =~ "usec" ]] ||
15254                                 error "unit is not 'usec': $unit"
15255                         ;;
15256                 *)      ;;
15257                 esac
15258         done < $TMP/$tfile.tmp
15259
15260         #check that we actually got some stats
15261         [ "$read_bytes" ] || error "Missing read_bytes stats"
15262         [ "$write_bytes" ] || error "Missing write_bytes stats"
15263         [ "$read_bytes" != 0 ] || error "no read done"
15264         [ "$write_bytes" != 0 ] || error "no write done"
15265 }
15266 run_test 127b "verify the llite client stats are sane"
15267
15268 test_127c() { # LU-12394
15269         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15270         local size
15271         local bsize
15272         local reads
15273         local writes
15274         local count
15275
15276         $LCTL set_param llite.*.extents_stats=1
15277         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15278
15279         # Use two stripes so there is enough space in default config
15280         $LFS setstripe -c 2 $DIR/$tfile
15281
15282         # Extent stats start at 0-4K and go in power of two buckets
15283         # LL_HIST_START = 12 --> 2^12 = 4K
15284         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15285         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15286         # small configs
15287         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15288                 do
15289                 # Write and read, 2x each, second time at a non-zero offset
15290                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15291                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15292                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15293                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15294                 rm -f $DIR/$tfile
15295         done
15296
15297         $LCTL get_param llite.*.extents_stats
15298
15299         count=2
15300         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15301                 do
15302                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15303                                 grep -m 1 $bsize)
15304                 reads=$(echo $bucket | awk '{print $5}')
15305                 writes=$(echo $bucket | awk '{print $9}')
15306                 [ "$reads" -eq $count ] ||
15307                         error "$reads reads in < $bsize bucket, expect $count"
15308                 [ "$writes" -eq $count ] ||
15309                         error "$writes writes in < $bsize bucket, expect $count"
15310         done
15311
15312         # Test mmap write and read
15313         $LCTL set_param llite.*.extents_stats=c
15314         size=512
15315         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15316         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15317         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15318
15319         $LCTL get_param llite.*.extents_stats
15320
15321         count=$(((size*1024) / PAGE_SIZE))
15322
15323         bsize=$((2 * PAGE_SIZE / 1024))K
15324
15325         bucket=$($LCTL get_param -n llite.*.extents_stats |
15326                         grep -m 1 $bsize)
15327         reads=$(echo $bucket | awk '{print $5}')
15328         writes=$(echo $bucket | awk '{print $9}')
15329         # mmap writes fault in the page first, creating an additonal read
15330         [ "$reads" -eq $((2 * count)) ] ||
15331                 error "$reads reads in < $bsize bucket, expect $count"
15332         [ "$writes" -eq $count ] ||
15333                 error "$writes writes in < $bsize bucket, expect $count"
15334 }
15335 run_test 127c "test llite extent stats with regular & mmap i/o"
15336
15337 test_128() { # bug 15212
15338         touch $DIR/$tfile
15339         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15340                 find $DIR/$tfile
15341                 find $DIR/$tfile
15342         EOF
15343
15344         result=$(grep error $TMP/$tfile.log)
15345         rm -f $DIR/$tfile $TMP/$tfile.log
15346         [ -z "$result" ] ||
15347                 error "consecutive find's under interactive lfs failed"
15348 }
15349 run_test 128 "interactive lfs for 2 consecutive find's"
15350
15351 set_dir_limits () {
15352         local mntdev
15353         local canondev
15354         local node
15355
15356         local ldproc=/proc/fs/ldiskfs
15357         local facets=$(get_facets MDS)
15358
15359         for facet in ${facets//,/ }; do
15360                 canondev=$(ldiskfs_canon \
15361                            *.$(convert_facet2label $facet).mntdev $facet)
15362                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15363                         ldproc=/sys/fs/ldiskfs
15364                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15365                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15366         done
15367 }
15368
15369 check_mds_dmesg() {
15370         local facets=$(get_facets MDS)
15371         for facet in ${facets//,/ }; do
15372                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15373         done
15374         return 1
15375 }
15376
15377 test_129() {
15378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15379         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15380                 skip "Need MDS version with at least 2.5.56"
15381         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15382                 skip_env "ldiskfs only test"
15383         fi
15384         remote_mds_nodsh && skip "remote MDS with nodsh"
15385
15386         local ENOSPC=28
15387         local has_warning=false
15388
15389         rm -rf $DIR/$tdir
15390         mkdir -p $DIR/$tdir
15391
15392         # block size of mds1
15393         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15394         set_dir_limits $maxsize $((maxsize * 6 / 8))
15395         stack_trap "set_dir_limits 0 0"
15396         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15397         local dirsize=$(stat -c%s "$DIR/$tdir")
15398         local nfiles=0
15399         while (( $dirsize <= $maxsize )); do
15400                 $MCREATE $DIR/$tdir/file_base_$nfiles
15401                 rc=$?
15402                 # check two errors:
15403                 # ENOSPC for ext4 max_dir_size, which has been used since
15404                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15405                 if (( rc == ENOSPC )); then
15406                         set_dir_limits 0 0
15407                         echo "rc=$rc returned as expected after $nfiles files"
15408
15409                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15410                                 error "create failed w/o dir size limit"
15411
15412                         # messages may be rate limited if test is run repeatedly
15413                         check_mds_dmesg '"is approaching max"' ||
15414                                 echo "warning message should be output"
15415                         check_mds_dmesg '"has reached max"' ||
15416                                 echo "reached message should be output"
15417
15418                         dirsize=$(stat -c%s "$DIR/$tdir")
15419
15420                         [[ $dirsize -ge $maxsize ]] && return 0
15421                         error "dirsize $dirsize < $maxsize after $nfiles files"
15422                 elif (( rc != 0 )); then
15423                         break
15424                 fi
15425                 nfiles=$((nfiles + 1))
15426                 dirsize=$(stat -c%s "$DIR/$tdir")
15427         done
15428
15429         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15430 }
15431 run_test 129 "test directory size limit ========================"
15432
15433 OLDIFS="$IFS"
15434 cleanup_130() {
15435         trap 0
15436         IFS="$OLDIFS"
15437         rm -f $DIR/$tfile
15438 }
15439
15440 test_130a() {
15441         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15442         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15443
15444         trap cleanup_130 EXIT RETURN
15445
15446         local fm_file=$DIR/$tfile
15447         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15448         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15449                 error "dd failed for $fm_file"
15450
15451         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15452         filefrag -ves $fm_file
15453         local rc=$?
15454         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15455                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15456         (( $rc == 0 )) || error "filefrag $fm_file failed"
15457
15458         filefrag_op=$(filefrag -ve -k $fm_file |
15459                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15460         local lun=$($LFS getstripe -i $fm_file)
15461
15462         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15463         IFS=$'\n'
15464         local tot_len=0
15465         for line in $filefrag_op; do
15466                 local frag_lun=$(echo $line | cut -d: -f5)
15467                 local ext_len=$(echo $line | cut -d: -f4)
15468
15469                 if (( $frag_lun != $lun )); then
15470                         error "FIEMAP on 1-stripe file($fm_file) failed"
15471                         return
15472                 fi
15473                 (( tot_len += ext_len ))
15474         done
15475
15476         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15477                 error "FIEMAP on 1-stripe file($fm_file) failed"
15478                 return
15479         fi
15480
15481         echo "FIEMAP on single striped file succeeded"
15482 }
15483 run_test 130a "FIEMAP (1-stripe file)"
15484
15485 test_130b() {
15486         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15487
15488         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15489         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15490         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15491                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15492
15493         trap cleanup_130 EXIT RETURN
15494
15495         local fm_file=$DIR/$tfile
15496         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15497                 error "setstripe on $fm_file"
15498
15499         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15500                 error "dd failed on $fm_file"
15501
15502         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15503         filefrag_op=$(filefrag -ve -k $fm_file |
15504                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15505
15506         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15507                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15508
15509         IFS=$'\n'
15510         local tot_len=0
15511         local num_luns=1
15512
15513         for line in $filefrag_op; do
15514                 local frag_lun=$(echo $line | cut -d: -f5 |
15515                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15516                 local ext_len=$(echo $line | cut -d: -f4)
15517                 if (( $frag_lun != $last_lun )); then
15518                         if (( tot_len != 1024 )); then
15519                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15520                                 return
15521                         else
15522                                 (( num_luns += 1 ))
15523                                 tot_len=0
15524                         fi
15525                 fi
15526                 (( tot_len += ext_len ))
15527                 last_lun=$frag_lun
15528         done
15529         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15530                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15531                 return
15532         fi
15533
15534         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15535 }
15536 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15537
15538 test_130c() {
15539         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15540
15541         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15542         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15543         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15544                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15545
15546         trap cleanup_130 EXIT RETURN
15547
15548         local fm_file=$DIR/$tfile
15549         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15550
15551         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15552                 error "dd failed on $fm_file"
15553
15554         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15555         filefrag_op=$(filefrag -ve -k $fm_file |
15556                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15557
15558         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15559                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15560
15561         IFS=$'\n'
15562         local tot_len=0
15563         local num_luns=1
15564         for line in $filefrag_op; do
15565                 local frag_lun=$(echo $line | cut -d: -f5 |
15566                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15567                 local ext_len=$(echo $line | cut -d: -f4)
15568                 if (( $frag_lun != $last_lun )); then
15569                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15570                         if (( logical != 512 )); then
15571                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15572                                 return
15573                         fi
15574                         if (( tot_len != 512 )); then
15575                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15576                                 return
15577                         else
15578                                 (( num_luns += 1 ))
15579                                 tot_len=0
15580                         fi
15581                 fi
15582                 (( tot_len += ext_len ))
15583                 last_lun=$frag_lun
15584         done
15585         if (( num_luns != 2 || tot_len != 512 )); then
15586                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15587                 return
15588         fi
15589
15590         echo "FIEMAP on 2-stripe file with hole succeeded"
15591 }
15592 run_test 130c "FIEMAP (2-stripe file with hole)"
15593
15594 test_130d() {
15595         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15596
15597         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15598         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15599         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15600                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15601
15602         trap cleanup_130 EXIT RETURN
15603
15604         local fm_file=$DIR/$tfile
15605         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15606                         error "setstripe on $fm_file"
15607
15608         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15609         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15610                 error "dd failed on $fm_file"
15611
15612         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15613         filefrag_op=$(filefrag -ve -k $fm_file |
15614                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15615
15616         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15617                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15618
15619         IFS=$'\n'
15620         local tot_len=0
15621         local num_luns=1
15622         for line in $filefrag_op; do
15623                 local frag_lun=$(echo $line | cut -d: -f5 |
15624                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15625                 local ext_len=$(echo $line | cut -d: -f4)
15626                 if (( $frag_lun != $last_lun )); then
15627                         if (( tot_len != 1024 )); then
15628                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15629                                 return
15630                         else
15631                                 (( num_luns += 1 ))
15632                                 local tot_len=0
15633                         fi
15634                 fi
15635                 (( tot_len += ext_len ))
15636                 last_lun=$frag_lun
15637         done
15638         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15639                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15640                 return
15641         fi
15642
15643         echo "FIEMAP on N-stripe file succeeded"
15644 }
15645 run_test 130d "FIEMAP (N-stripe file)"
15646
15647 test_130e() {
15648         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15649
15650         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15651         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15652         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15653                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15654
15655         trap cleanup_130 EXIT RETURN
15656
15657         local fm_file=$DIR/$tfile
15658         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15659         stack_trap "rm -f $fm_file"
15660
15661         local num_blks=512
15662         local expected_len=$(( (num_blks / 2) * 64 ))
15663         for ((i = 0; i < $num_blks; i++)); do
15664                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15665                         conv=notrunc > /dev/null 2>&1
15666         done
15667
15668         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15669         filefrag_op=$(filefrag -ve -k $fm_file |
15670                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15671
15672         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15673
15674         IFS=$'\n'
15675         local tot_len=0
15676         local num_luns=1
15677         for line in $filefrag_op; do
15678                 local frag_lun=$(echo $line | cut -d: -f5)
15679                 local ext_len=$(echo $line | cut -d: -f4)
15680                 if (( $frag_lun != $last_lun )); then
15681                         if (( tot_len != $expected_len )); then
15682                                 error "OST$last_lun $tot_len != $expected_len"
15683                         else
15684                                 (( num_luns += 1 ))
15685                                 tot_len=0
15686                         fi
15687                 fi
15688                 (( tot_len += ext_len ))
15689                 last_lun=$frag_lun
15690         done
15691         if (( num_luns != 2 || tot_len != $expected_len )); then
15692                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15693         fi
15694
15695         echo "FIEMAP with continuation calls succeeded"
15696 }
15697 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15698
15699 test_130f() {
15700         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15701         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15702         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15703                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15704
15705         local fm_file=$DIR/$tfile
15706         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15707                 error "multiop create with lov_delay_create on $fm_file"
15708
15709         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15710         filefrag_extents=$(filefrag -vek $fm_file |
15711                            awk '/extents? found/ { print $2 }')
15712         if (( $filefrag_extents != 0 )); then
15713                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15714         fi
15715
15716         rm -f $fm_file
15717 }
15718 run_test 130f "FIEMAP (unstriped file)"
15719
15720 test_130g() {
15721         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15722                 skip "Need MDS version with at least 2.12.53 for overstriping"
15723         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15724         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15725         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15726                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15727
15728         local file=$DIR/$tfile
15729         local nr=$((OSTCOUNT * 100))
15730
15731         $LFS setstripe -C $nr -S1M $file ||
15732                 error "failed to setstripe -C $nr $file"
15733
15734         stack_trap "rm -f $file"
15735         dd if=/dev/zero of=$file count=$nr bs=1M
15736         sync
15737         nr=$($LFS getstripe -c $file)
15738
15739         local extents=$(filefrag -v $file |
15740                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15741
15742         echo "filefrag list $extents extents in file with stripecount $nr"
15743         if (( extents < nr )); then
15744                 $LFS getstripe $file
15745                 filefrag -v $file
15746                 error "filefrag printed $extents < $nr extents"
15747         fi
15748 }
15749 run_test 130g "FIEMAP (overstripe file)"
15750
15751 # Test for writev/readv
15752 test_131a() {
15753         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15754                 error "writev test failed"
15755         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15756                 error "readv failed"
15757         rm -f $DIR/$tfile
15758 }
15759 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15760
15761 test_131b() {
15762         local fsize=$((524288 + 1048576 + 1572864))
15763         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15764                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15765                         error "append writev test failed"
15766
15767         ((fsize += 1572864 + 1048576))
15768         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15769                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15770                         error "append writev test failed"
15771         rm -f $DIR/$tfile
15772 }
15773 run_test 131b "test append writev"
15774
15775 test_131c() {
15776         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15777         error "NOT PASS"
15778 }
15779 run_test 131c "test read/write on file w/o objects"
15780
15781 test_131d() {
15782         rwv -f $DIR/$tfile -w -n 1 1572864
15783         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15784         if [ "$NOB" != 1572864 ]; then
15785                 error "Short read filed: read $NOB bytes instead of 1572864"
15786         fi
15787         rm -f $DIR/$tfile
15788 }
15789 run_test 131d "test short read"
15790
15791 test_131e() {
15792         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15793         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15794         error "read hitting hole failed"
15795         rm -f $DIR/$tfile
15796 }
15797 run_test 131e "test read hitting hole"
15798
15799 check_stats() {
15800         local facet=$1
15801         local op=$2
15802         local want=${3:-0}
15803         local res
15804
15805         # open             11 samples [usecs] 468 4793 13658 35791898
15806         case $facet in
15807         mds*) res=($(do_facet $facet \
15808                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15809                  ;;
15810         ost*) res=($(do_facet $facet \
15811                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15812                  ;;
15813         *) error "Wrong facet '$facet'" ;;
15814         esac
15815         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15816         # if $want is zero, it means any stat increment is ok.
15817         if (( $want > 0 )); then
15818                 local count=${res[1]}
15819
15820                 if (( $count != $want )); then
15821                         if [[ $facet =~ "mds" ]]; then
15822                                 do_nodes $(comma_list $(mdts_nodes)) \
15823                                         $LCTL get_param mdt.*.md_stats
15824                         else
15825                                 do_nodes $(comma_list $(osts-nodes)) \
15826                                         $LCTL get_param obdfilter.*.stats
15827                         fi
15828                         error "The $op counter on $facet is $count, not $want"
15829                 fi
15830         fi
15831 }
15832
15833 test_133a() {
15834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15835         remote_ost_nodsh && skip "remote OST with nodsh"
15836         remote_mds_nodsh && skip "remote MDS with nodsh"
15837         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15838                 skip_env "MDS doesn't support rename stats"
15839
15840         local testdir=$DIR/${tdir}/stats_testdir
15841
15842         mkdir_on_mdt0 $DIR/${tdir}
15843
15844         # clear stats.
15845         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15846         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15847
15848         # verify mdt stats first.
15849         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15850         check_stats $SINGLEMDS "mkdir" 1
15851
15852         # clear "open" from "lfs mkdir" above
15853         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15854         touch ${testdir}/${tfile} || error "touch failed"
15855         check_stats $SINGLEMDS "open" 1
15856         check_stats $SINGLEMDS "close" 1
15857         (( $MDS1_VERSION >= $(version_code 2.15.62) )) && {
15858                 # open should match close
15859                 ls -lR ${testdir}
15860                 check_stats $SINGLEMDS "open" 2
15861                 check_stats $SINGLEMDS "close" 2
15862         }
15863         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15864                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15865                 check_stats $SINGLEMDS "mknod" 2
15866         }
15867         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15868         check_stats $SINGLEMDS "unlink" 1
15869         rm -f ${testdir}/${tfile} || error "file remove failed"
15870         check_stats $SINGLEMDS "unlink" 2
15871
15872         # remove working dir and check mdt stats again.
15873         rmdir ${testdir} || error "rmdir failed"
15874         check_stats $SINGLEMDS "rmdir" 1
15875
15876         local testdir1=$DIR/${tdir}/stats_testdir1
15877         mkdir_on_mdt0 ${testdir}
15878         mkdir_on_mdt0 ${testdir1}
15879         touch ${testdir1}/test1
15880         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15881         check_stats $SINGLEMDS "crossdir_rename" 1
15882
15883         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15884         check_stats $SINGLEMDS "samedir_rename" 1
15885
15886         rm -rf $DIR/${tdir}
15887 }
15888 run_test 133a "Verifying MDT stats ========================================"
15889
15890 test_133b() {
15891         local res
15892
15893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15894         remote_ost_nodsh && skip "remote OST with nodsh"
15895         remote_mds_nodsh && skip "remote MDS with nodsh"
15896
15897         local testdir=$DIR/${tdir}/stats_testdir
15898
15899         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15900         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15901         touch ${testdir}/${tfile} || error "touch failed"
15902         cancel_lru_locks mdc
15903
15904         # clear stats.
15905         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15906         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15907
15908         # extra mdt stats verification.
15909         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15910         check_stats $SINGLEMDS "setattr" 1
15911         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15912         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15913         then            # LU-1740
15914                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15915                 check_stats $SINGLEMDS "getattr" 1
15916         fi
15917         rm -rf $DIR/${tdir}
15918
15919         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15920         # so the check below is not reliable
15921         [ $MDSCOUNT -eq 1 ] || return 0
15922
15923         # Sleep to avoid a cached response.
15924         #define OBD_STATFS_CACHE_SECONDS 1
15925         sleep 2
15926         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15927         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15928         $LFS df || error "lfs failed"
15929         check_stats $SINGLEMDS "statfs" 1
15930
15931         # check aggregated statfs (LU-10018)
15932         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15933                 return 0
15934         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15935                 return 0
15936         sleep 2
15937         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15938         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15939         df $DIR
15940         check_stats $SINGLEMDS "statfs" 1
15941
15942         # We want to check that the client didn't send OST_STATFS to
15943         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15944         # extra care is needed here.
15945         if remote_mds; then
15946                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15947                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15948
15949                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15950                 [ "$res" ] && error "OST got STATFS"
15951         fi
15952
15953         return 0
15954 }
15955 run_test 133b "Verifying extra MDT stats =================================="
15956
15957 test_133c() {
15958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15959         remote_ost_nodsh && skip "remote OST with nodsh"
15960         remote_mds_nodsh && skip "remote MDS with nodsh"
15961
15962         local testdir=$DIR/$tdir/stats_testdir
15963
15964         test_mkdir -p $testdir
15965
15966         # verify obdfilter stats.
15967         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15968         sync
15969         cancel_lru_locks osc
15970         wait_delete_completed
15971
15972         # clear stats.
15973         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15974         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15975
15976         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15977                 error "dd failed"
15978         sync
15979         cancel_lru_locks osc
15980         check_stats ost1 "write" 1
15981
15982         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15983         check_stats ost1 "read" 1
15984
15985         > $testdir/$tfile || error "truncate failed"
15986         check_stats ost1 "punch" 1
15987
15988         rm -f $testdir/$tfile || error "file remove failed"
15989         wait_delete_completed
15990         check_stats ost1 "destroy" 1
15991
15992         rm -rf $DIR/$tdir
15993 }
15994 run_test 133c "Verifying OST stats ========================================"
15995
15996 order_2() {
15997         local value=$1
15998         local orig=$value
15999         local order=1
16000
16001         while [ $value -ge 2 ]; do
16002                 order=$((order*2))
16003                 value=$((value/2))
16004         done
16005
16006         if [ $orig -gt $order ]; then
16007                 order=$((order*2))
16008         fi
16009         echo $order
16010 }
16011
16012 size_in_KMGT() {
16013     local value=$1
16014     local size=('K' 'M' 'G' 'T');
16015     local i=0
16016     local size_string=$value
16017
16018     while [ $value -ge 1024 ]; do
16019         if [ $i -gt 3 ]; then
16020             #T is the biggest unit we get here, if that is bigger,
16021             #just return XXXT
16022             size_string=${value}T
16023             break
16024         fi
16025         value=$((value >> 10))
16026         if [ $value -lt 1024 ]; then
16027             size_string=${value}${size[$i]}
16028             break
16029         fi
16030         i=$((i + 1))
16031     done
16032
16033     echo $size_string
16034 }
16035
16036 get_rename_size() {
16037         local size=$1
16038         local context=${2:-.}
16039         local sample=$(do_facet $SINGLEMDS $LCTL \
16040                 get_param mdt.$FSNAME-MDT0000.rename_stats |
16041                 grep -A1 $context |
16042                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
16043         echo $sample
16044 }
16045
16046 test_133d() {
16047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16048         remote_ost_nodsh && skip "remote OST with nodsh"
16049         remote_mds_nodsh && skip "remote MDS with nodsh"
16050         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
16051                 skip_env "MDS doesn't support rename stats"
16052
16053         local testdir1=$DIR/${tdir}/stats_testdir1
16054         local testdir2=$DIR/${tdir}/stats_testdir2
16055         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
16056
16057         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16058
16059         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16060         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16061
16062         createmany -o $testdir1/test 512 || error "createmany failed"
16063
16064         # check samedir rename size
16065         mv ${testdir1}/test0 ${testdir1}/test_0
16066
16067         local testdir1_size=$(ls -l $DIR/${tdir} |
16068                 awk '/stats_testdir1/ {print $5}')
16069         local testdir2_size=$(ls -l $DIR/${tdir} |
16070                 awk '/stats_testdir2/ {print $5}')
16071
16072         testdir1_size=$(order_2 $testdir1_size)
16073         testdir2_size=$(order_2 $testdir2_size)
16074
16075         testdir1_size=$(size_in_KMGT $testdir1_size)
16076         testdir2_size=$(size_in_KMGT $testdir2_size)
16077
16078         echo "source rename dir size: ${testdir1_size}"
16079         echo "target rename dir size: ${testdir2_size}"
16080
16081         local cmd="do_facet $SINGLEMDS $LCTL "
16082         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16083
16084         eval $cmd || error "$cmd failed"
16085         local samedir=$($cmd | grep 'same_dir')
16086         local same_sample=$(get_rename_size $testdir1_size)
16087         [ -z "$samedir" ] && error "samedir_rename_size count error"
16088         [[ $same_sample -eq 1 ]] ||
16089                 error "samedir_rename_size error $same_sample"
16090         echo "Check same dir rename stats success"
16091
16092         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16093
16094         # check crossdir rename size
16095         mv ${testdir1}/test_0 ${testdir2}/test_0
16096
16097         testdir1_size=$(ls -l $DIR/${tdir} |
16098                 awk '/stats_testdir1/ {print $5}')
16099         testdir2_size=$(ls -l $DIR/${tdir} |
16100                 awk '/stats_testdir2/ {print $5}')
16101
16102         testdir1_size=$(order_2 $testdir1_size)
16103         testdir2_size=$(order_2 $testdir2_size)
16104
16105         testdir1_size=$(size_in_KMGT $testdir1_size)
16106         testdir2_size=$(size_in_KMGT $testdir2_size)
16107
16108         echo "source rename dir size: ${testdir1_size}"
16109         echo "target rename dir size: ${testdir2_size}"
16110
16111         eval $cmd || error "$cmd failed"
16112         local crossdir=$($cmd | grep 'crossdir')
16113         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16114         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16115         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16116         [[ $src_sample -eq 1 ]] ||
16117                 error "crossdir_rename_size error $src_sample"
16118         [[ $tgt_sample -eq 1 ]] ||
16119                 error "crossdir_rename_size error $tgt_sample"
16120         echo "Check cross dir rename stats success"
16121         rm -rf $DIR/${tdir}
16122 }
16123 run_test 133d "Verifying rename_stats ========================================"
16124
16125 test_133e() {
16126         remote_mds_nodsh && skip "remote MDS with nodsh"
16127         remote_ost_nodsh && skip "remote OST with nodsh"
16128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16129
16130         local testdir=$DIR/${tdir}/stats_testdir
16131         local ctr f0 f1 bs=32768 count=42 sum
16132
16133         mkdir -p ${testdir} || error "mkdir failed"
16134
16135         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16136
16137         for ctr in {write,read}_bytes; do
16138                 sync
16139                 cancel_lru_locks osc
16140
16141                 do_facet ost1 $LCTL set_param -n \
16142                         "obdfilter.*.exports.clear=clear"
16143
16144                 if [ $ctr = write_bytes ]; then
16145                         f0=/dev/zero
16146                         f1=${testdir}/${tfile}
16147                 else
16148                         f0=${testdir}/${tfile}
16149                         f1=/dev/null
16150                 fi
16151
16152                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16153                         error "dd failed"
16154                 sync
16155                 cancel_lru_locks osc
16156
16157                 sum=$(do_facet ost1 $LCTL get_param \
16158                         "obdfilter.*.exports.*.stats" |
16159                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16160                                 $1 == ctr { sum += $7 }
16161                                 END { printf("%0.0f", sum) }')
16162
16163                 if ((sum != bs * count)); then
16164                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16165                 fi
16166         done
16167
16168         rm -rf $DIR/${tdir}
16169 }
16170 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16171
16172 test_133f() {
16173         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16174                 skip "too old lustre for get_param -R ($facet_ver)"
16175
16176         # verifying readability.
16177         $LCTL get_param -R '*' &> /dev/null
16178
16179         # Verifing writability with badarea_io.
16180         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16181         local skipped_params='force_lbug|changelog_mask|daemon_file'
16182         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16183                 egrep -v "$skipped_params" |
16184                 xargs -n 1 find $proc_dirs -name |
16185                 xargs -n 1 badarea_io ||
16186                 error "client badarea_io failed"
16187
16188         # remount the FS in case writes/reads /proc break the FS
16189         cleanup || error "failed to unmount"
16190         setup || error "failed to setup"
16191 }
16192 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16193
16194 test_133g() {
16195         remote_mds_nodsh && skip "remote MDS with nodsh"
16196         remote_ost_nodsh && skip "remote OST with nodsh"
16197
16198         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16199         local proc_dirs_str=$(eval echo $proc_dirs)
16200         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16201         local facet
16202         for facet in mds1 ost1; do
16203                 local facet_ver=$(lustre_version_code $facet)
16204                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16205                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16206                 else
16207                         log "$facet: too old lustre for get_param -R"
16208                 fi
16209                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16210                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16211                                 tr -d = | egrep -v $skipped_params |
16212                                 xargs -n 1 find $proc_dirs_str -name |
16213                                 xargs -n 1 badarea_io" ||
16214                                         error "$facet badarea_io failed"
16215                 else
16216                         skip_noexit "$facet: too old lustre for get_param -R"
16217                 fi
16218         done
16219
16220         # remount the FS in case writes/reads /proc break the FS
16221         cleanup || error "failed to unmount"
16222         setup || error "failed to setup"
16223 }
16224 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16225
16226 test_133h() {
16227         remote_mds_nodsh && skip "remote MDS with nodsh"
16228         remote_ost_nodsh && skip "remote OST with nodsh"
16229         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16230                 skip "Need MDS version at least 2.9.54"
16231
16232         local facet
16233         for facet in client mds1 ost1; do
16234                 # Get the list of files that are missing the terminating newline
16235                 local plist=$(do_facet $facet
16236                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16237                 local ent
16238                 for ent in $plist; do
16239                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16240                                 awk -v FS='\v' -v RS='\v\v' \
16241                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16242                                         print FILENAME}'" 2>/dev/null)
16243                         [ -z $missing ] || {
16244                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16245                                 error "file does not end with newline: $facet-$ent"
16246                         }
16247                 done
16248         done
16249 }
16250 run_test 133h "Proc files should end with newlines"
16251
16252 test_134a() {
16253         remote_mds_nodsh && skip "remote MDS with nodsh"
16254         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16255                 skip "Need MDS version at least 2.7.54"
16256
16257         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16258         cancel_lru_locks mdc
16259
16260         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16261         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16262         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16263
16264         local nr=1000
16265         createmany -o $DIR/$tdir/f $nr ||
16266                 error "failed to create $nr files in $DIR/$tdir"
16267         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16268
16269         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16270         do_facet mds1 $LCTL set_param fail_loc=0x327
16271         do_facet mds1 $LCTL set_param fail_val=500
16272         touch $DIR/$tdir/m
16273
16274         echo "sleep 10 seconds ..."
16275         sleep 10
16276         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16277
16278         do_facet mds1 $LCTL set_param fail_loc=0
16279         do_facet mds1 $LCTL set_param fail_val=0
16280         [ $lck_cnt -lt $unused ] ||
16281                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16282
16283         rm $DIR/$tdir/m
16284         unlinkmany $DIR/$tdir/f $nr
16285 }
16286 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16287
16288 test_134b() {
16289         remote_mds_nodsh && skip "remote MDS with nodsh"
16290         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16291                 skip "Need MDS version at least 2.7.54"
16292
16293         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16294         cancel_lru_locks mdc
16295
16296         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16297                         ldlm.lock_reclaim_threshold_mb)
16298         # disable reclaim temporarily
16299         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16300
16301         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16302         do_facet mds1 $LCTL set_param fail_loc=0x328
16303         do_facet mds1 $LCTL set_param fail_val=500
16304
16305         $LCTL set_param debug=+trace
16306
16307         local nr=600
16308         createmany -o $DIR/$tdir/f $nr &
16309         local create_pid=$!
16310
16311         echo "Sleep $TIMEOUT seconds ..."
16312         sleep $TIMEOUT
16313         if ! ps -p $create_pid  > /dev/null 2>&1; then
16314                 do_facet mds1 $LCTL set_param fail_loc=0
16315                 do_facet mds1 $LCTL set_param fail_val=0
16316                 do_facet mds1 $LCTL set_param \
16317                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16318                 error "createmany finished incorrectly!"
16319         fi
16320         do_facet mds1 $LCTL set_param fail_loc=0
16321         do_facet mds1 $LCTL set_param fail_val=0
16322         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16323         wait $create_pid || return 1
16324
16325         unlinkmany $DIR/$tdir/f $nr
16326 }
16327 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16328
16329 test_135() {
16330         remote_mds_nodsh && skip "remote MDS with nodsh"
16331         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16332                 skip "Need MDS version at least 2.13.50"
16333         local fname
16334
16335         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16336
16337 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16338         #set only one record at plain llog
16339         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16340
16341         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16342
16343         #fill already existed plain llog each 64767
16344         #wrapping whole catalog
16345         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16346
16347         createmany -o $DIR/$tdir/$tfile_ 64700
16348         for (( i = 0; i < 64700; i = i + 2 ))
16349         do
16350                 rm $DIR/$tdir/$tfile_$i &
16351                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16352                 local pid=$!
16353                 wait $pid
16354         done
16355
16356         #waiting osp synchronization
16357         wait_delete_completed
16358 }
16359 run_test 135 "Race catalog processing"
16360
16361 test_136() {
16362         remote_mds_nodsh && skip "remote MDS with nodsh"
16363         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16364                 skip "Need MDS version at least 2.13.50"
16365         local fname
16366
16367         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16368         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16369         #set only one record at plain llog
16370 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16371         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16372
16373         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16374
16375         #fill already existed 2 plain llogs each 64767
16376         #wrapping whole catalog
16377         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16378         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16379         wait_delete_completed
16380
16381         createmany -o $DIR/$tdir/$tfile_ 10
16382         sleep 25
16383
16384         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16385         for (( i = 0; i < 10; i = i + 3 ))
16386         do
16387                 rm $DIR/$tdir/$tfile_$i &
16388                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16389                 local pid=$!
16390                 wait $pid
16391                 sleep 7
16392                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16393         done
16394
16395         #waiting osp synchronization
16396         wait_delete_completed
16397 }
16398 run_test 136 "Race catalog processing 2"
16399
16400 test_140() { #bug-17379
16401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16402
16403         test_mkdir $DIR/$tdir
16404         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16405         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16406
16407         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16408         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16409         local i=0
16410         while i=$((i + 1)); do
16411                 test_mkdir $i
16412                 cd $i || error "Changing to $i"
16413                 ln -s ../stat stat || error "Creating stat symlink"
16414                 # Read the symlink until ELOOP present,
16415                 # not LBUGing the system is considered success,
16416                 # we didn't overrun the stack.
16417                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16418                 if [ $ret -ne 0 ]; then
16419                         if [ $ret -eq 40 ]; then
16420                                 break  # -ELOOP
16421                         else
16422                                 error "Open stat symlink"
16423                                         return
16424                         fi
16425                 fi
16426         done
16427         i=$((i - 1))
16428         echo "The symlink depth = $i"
16429         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16430                 error "Invalid symlink depth"
16431
16432         # Test recursive symlink
16433         ln -s symlink_self symlink_self
16434         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16435         echo "open symlink_self returns $ret"
16436         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16437 }
16438 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16439
16440 test_150a() {
16441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16442
16443         local TF="$TMP/$tfile"
16444
16445         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16446         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16447         cp $TF $DIR/$tfile
16448         cancel_lru_locks $OSC
16449         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16450         remount_client $MOUNT
16451         df -P $MOUNT
16452         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16453
16454         $TRUNCATE $TF 6000
16455         $TRUNCATE $DIR/$tfile 6000
16456         cancel_lru_locks $OSC
16457         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16458
16459         echo "12345" >>$TF
16460         echo "12345" >>$DIR/$tfile
16461         cancel_lru_locks $OSC
16462         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16463
16464         echo "12345" >>$TF
16465         echo "12345" >>$DIR/$tfile
16466         cancel_lru_locks $OSC
16467         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16468 }
16469 run_test 150a "truncate/append tests"
16470
16471 test_150b() {
16472         check_set_fallocate_or_skip
16473         local out
16474
16475         touch $DIR/$tfile
16476         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16477         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16478                 skip_eopnotsupp "$out|check_fallocate failed"
16479 }
16480 run_test 150b "Verify fallocate (prealloc) functionality"
16481
16482 test_150bb() {
16483         check_set_fallocate_or_skip
16484
16485         touch $DIR/$tfile
16486         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16487         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16488         > $DIR/$tfile
16489         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16490         # precomputed md5sum for 20MB of zeroes
16491         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16492         local sum=($(md5sum $DIR/$tfile))
16493
16494         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16495
16496         check_set_fallocate 1
16497
16498         > $DIR/$tfile
16499         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16500         sum=($(md5sum $DIR/$tfile))
16501
16502         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16503 }
16504 run_test 150bb "Verify fallocate modes both zero space"
16505
16506 test_150c() {
16507         check_set_fallocate_or_skip
16508         local striping="-c2"
16509
16510         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16511         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16512         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16513         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16514         local want=$((OSTCOUNT * 1048576))
16515
16516         # Must allocate all requested space, not more than 5% extra
16517         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16518                 error "bytes $bytes is not $want"
16519
16520         rm -f $DIR/$tfile
16521
16522         echo "verify fallocate on PFL file"
16523
16524         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16525
16526         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16527                 error "Create $DIR/$tfile failed"
16528         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16529         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16530         want=$((512 * 1048576))
16531
16532         # Must allocate all requested space, not more than 5% extra
16533         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16534                 error "bytes $bytes is not $want"
16535 }
16536 run_test 150c "Verify fallocate Size and Blocks"
16537
16538 test_150d() {
16539         check_set_fallocate_or_skip
16540         local striping="-c2"
16541
16542         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16543
16544         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16545         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16546                 error "setstripe failed"
16547         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16548         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16549         local want=$((OSTCOUNT * 1048576))
16550
16551         # Must allocate all requested space, not more than 5% extra
16552         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16553                 error "bytes $bytes is not $want"
16554 }
16555 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16556
16557 test_150e() {
16558         check_set_fallocate_or_skip
16559
16560         echo "df before:"
16561         $LFS df
16562         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16563         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16564                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16565
16566         # Find OST with Minimum Size
16567         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16568                        sort -un | head -1)
16569
16570         # Get 100MB per OST of the available space to reduce run time
16571         # else 60% of the available space if we are running SLOW tests
16572         if [ $SLOW == "no" ]; then
16573                 local space=$((1024 * 100 * OSTCOUNT))
16574         else
16575                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16576         fi
16577
16578         fallocate -l${space}k $DIR/$tfile ||
16579                 error "fallocate ${space}k $DIR/$tfile failed"
16580         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16581
16582         # get size immediately after fallocate. This should be correctly
16583         # updated
16584         local size=$(stat -c '%s' $DIR/$tfile)
16585         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16586
16587         # Sleep for a while for statfs to get updated. And not pull from cache.
16588         sleep 2
16589
16590         echo "df after fallocate:"
16591         $LFS df
16592
16593         (( size / 1024 == space )) || error "size $size != requested $space"
16594         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16595                 error "used $used < space $space"
16596
16597         rm $DIR/$tfile || error "rm failed"
16598         sync
16599         wait_delete_completed
16600
16601         echo "df after unlink:"
16602         $LFS df
16603 }
16604 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16605
16606 test_150f() {
16607         local size
16608         local blocks
16609         local want_size_before=20480 # in bytes
16610         local want_blocks_before=40 # 512 sized blocks
16611         local want_blocks_after=24  # 512 sized blocks
16612         local length=$(((want_blocks_before - want_blocks_after) * 512))
16613
16614         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16615                 skip "need at least 2.14.0 for fallocate punch"
16616
16617         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16618                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16619         fi
16620
16621         check_set_fallocate_or_skip
16622         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16623
16624         [[ "x$DOM" == "xyes" ]] &&
16625                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16626
16627         echo "Verify fallocate punch: Range within the file range"
16628         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16629                 error "dd failed for bs 4096 and count 5"
16630
16631         # Call fallocate with punch range which is within the file range
16632         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16633                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16634         # client must see changes immediately after fallocate
16635         size=$(stat -c '%s' $DIR/$tfile)
16636         blocks=$(stat -c '%b' $DIR/$tfile)
16637
16638         # Verify punch worked.
16639         (( blocks == want_blocks_after )) ||
16640                 error "punch failed: blocks $blocks != $want_blocks_after"
16641
16642         (( size == want_size_before )) ||
16643                 error "punch failed: size $size != $want_size_before"
16644
16645         # Verify there is hole in file
16646         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16647         # precomputed md5sum
16648         local expect="4a9a834a2db02452929c0a348273b4aa"
16649
16650         cksum=($(md5sum $DIR/$tfile))
16651         [[ "${cksum[0]}" == "$expect" ]] ||
16652                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16653
16654         # Start second sub-case for fallocate punch.
16655         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16656         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16657                 error "dd failed for bs 4096 and count 5"
16658
16659         # Punch range less than block size will have no change in block count
16660         want_blocks_after=40  # 512 sized blocks
16661
16662         # Punch overlaps two blocks and less than blocksize
16663         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16664                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16665         size=$(stat -c '%s' $DIR/$tfile)
16666         blocks=$(stat -c '%b' $DIR/$tfile)
16667
16668         # Verify punch worked.
16669         (( blocks == want_blocks_after )) ||
16670                 error "punch failed: blocks $blocks != $want_blocks_after"
16671
16672         (( size == want_size_before )) ||
16673                 error "punch failed: size $size != $want_size_before"
16674
16675         # Verify if range is really zero'ed out. We expect Zeros.
16676         # precomputed md5sum
16677         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16678         cksum=($(md5sum $DIR/$tfile))
16679         [[ "${cksum[0]}" == "$expect" ]] ||
16680                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16681 }
16682 run_test 150f "Verify fallocate punch functionality"
16683
16684 test_150g() {
16685         local space
16686         local size
16687         local blocks
16688         local blocks_after
16689         local size_after
16690         local BS=4096 # Block size in bytes
16691
16692         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16693                 skip "need at least 2.14.0 for fallocate punch"
16694
16695         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16696                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16697         fi
16698
16699         check_set_fallocate_or_skip
16700         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16701
16702         if [[ "x$DOM" == "xyes" ]]; then
16703                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16704                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16705         else
16706                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16707                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16708         fi
16709
16710         # Get 100MB per OST of the available space to reduce run time
16711         # else 60% of the available space if we are running SLOW tests
16712         if [ $SLOW == "no" ]; then
16713                 space=$((1024 * 100 * OSTCOUNT))
16714         else
16715                 # Find OST with Minimum Size
16716                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16717                         sort -un | head -1)
16718                 echo "min size OST: $space"
16719                 space=$(((space * 60)/100 * OSTCOUNT))
16720         fi
16721         # space in 1k units, round to 4k blocks
16722         local blkcount=$((space * 1024 / $BS))
16723
16724         echo "Verify fallocate punch: Very large Range"
16725         fallocate -l${space}k $DIR/$tfile ||
16726                 error "fallocate ${space}k $DIR/$tfile failed"
16727         # write 1M at the end, start and in the middle
16728         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16729                 error "dd failed: bs $BS count 256"
16730         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16731                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16732         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16733                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16734
16735         # Gather stats.
16736         size=$(stat -c '%s' $DIR/$tfile)
16737
16738         # gather punch length.
16739         local punch_size=$((size - (BS * 2)))
16740
16741         echo "punch_size = $punch_size"
16742         echo "size - punch_size: $((size - punch_size))"
16743         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16744
16745         # Call fallocate to punch all except 2 blocks. We leave the
16746         # first and the last block
16747         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16748         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16749                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16750
16751         size_after=$(stat -c '%s' $DIR/$tfile)
16752         blocks_after=$(stat -c '%b' $DIR/$tfile)
16753
16754         # Verify punch worked.
16755         # Size should be kept
16756         (( size == size_after )) ||
16757                 error "punch failed: size $size != $size_after"
16758
16759         # two 4k data blocks to remain plus possible 1 extra extent block
16760         (( blocks_after <= ((BS / 512) * 3) )) ||
16761                 error "too many blocks remains: $blocks_after"
16762
16763         # Verify that file has hole between the first and the last blocks
16764         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16765         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16766
16767         echo "Hole at [$hole_start, $hole_end)"
16768         (( hole_start == BS )) ||
16769                 error "no hole at offset $BS after punch"
16770
16771         (( hole_end == BS + punch_size )) ||
16772                 error "data at offset $hole_end < $((BS + punch_size))"
16773 }
16774 run_test 150g "Verify fallocate punch on large range"
16775
16776 test_150h() {
16777         local file=$DIR/$tfile
16778         local size
16779
16780         check_set_fallocate_or_skip
16781         statx_supported || skip_env "Test must be statx() syscall supported"
16782
16783         # fallocate() does not update the size information on the MDT
16784         fallocate -l 16K $file || error "failed to fallocate $file"
16785         cancel_lru_locks $OSC
16786         # STATX with cached-always mode will not send glimpse RPCs to OST,
16787         # it uses the caching attrs on the client side as much as possible.
16788         size=$($STATX --cached=always -c %s $file)
16789         [ $size == 16384 ] ||
16790                 error "size after fallocate() is $size, expected 16384"
16791 }
16792 run_test 150h "Verify extend fallocate updates the file size"
16793
16794 #LU-2902 roc_hit was not able to read all values from lproc
16795 function roc_hit_init() {
16796         local list=$(comma_list $(osts_nodes))
16797         local dir=$DIR/$tdir-check
16798         local file=$dir/$tfile
16799         local BEFORE
16800         local AFTER
16801         local idx
16802
16803         test_mkdir $dir
16804         #use setstripe to do a write to every ost
16805         for i in $(seq 0 $((OSTCOUNT-1))); do
16806                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16807                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16808                 idx=$(printf %04x $i)
16809                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16810                         awk '$1 == "cache_access" {sum += $7}
16811                                 END { printf("%0.0f", sum) }')
16812
16813                 cancel_lru_locks osc
16814                 cat $file >/dev/null
16815
16816                 AFTER=$(get_osd_param $list *OST*$idx stats |
16817                         awk '$1 == "cache_access" {sum += $7}
16818                                 END { printf("%0.0f", sum) }')
16819
16820                 echo BEFORE:$BEFORE AFTER:$AFTER
16821                 if ! let "AFTER - BEFORE == 4"; then
16822                         rm -rf $dir
16823                         error "roc_hit is not safe to use"
16824                 fi
16825                 rm $file
16826         done
16827
16828         rm -rf $dir
16829 }
16830
16831 function roc_hit() {
16832         local list=$(comma_list $(osts_nodes))
16833         echo $(get_osd_param $list '' stats |
16834                 awk '$1 == "cache_hit" {sum += $7}
16835                         END { printf("%0.0f", sum) }')
16836 }
16837
16838 function set_cache() {
16839         local on=1
16840
16841         if [ "$2" == "off" ]; then
16842                 on=0;
16843         fi
16844         local list=$(comma_list $(osts_nodes))
16845         set_osd_param $list '' $1_cache_enable $on
16846
16847         cancel_lru_locks osc
16848 }
16849
16850 test_151() {
16851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16852         remote_ost_nodsh && skip "remote OST with nodsh"
16853         (( CLIENT_VERSION == OST1_VERSION )) ||
16854                 skip "LU-13081: no interop testing for OSS cache"
16855
16856         local CPAGES=3
16857         local list=$(comma_list $(osts_nodes))
16858
16859         # check whether obdfilter is cache capable at all
16860         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16861                 skip "not cache-capable obdfilter"
16862         fi
16863
16864         # check cache is enabled on all obdfilters
16865         if get_osd_param $list '' read_cache_enable | grep 0; then
16866                 skip "oss cache is disabled"
16867         fi
16868
16869         set_osd_param $list '' writethrough_cache_enable 1
16870
16871         # check write cache is enabled on all obdfilters
16872         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16873                 skip "oss write cache is NOT enabled"
16874         fi
16875
16876         roc_hit_init
16877
16878         #define OBD_FAIL_OBD_NO_LRU  0x609
16879         do_nodes $list $LCTL set_param fail_loc=0x609
16880
16881         # pages should be in the case right after write
16882         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16883                 error "dd failed"
16884
16885         local BEFORE=$(roc_hit)
16886         cancel_lru_locks osc
16887         cat $DIR/$tfile >/dev/null
16888         local AFTER=$(roc_hit)
16889
16890         do_nodes $list $LCTL set_param fail_loc=0
16891
16892         if ! let "AFTER - BEFORE == CPAGES"; then
16893                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16894         fi
16895
16896         cancel_lru_locks osc
16897         # invalidates OST cache
16898         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16899         set_osd_param $list '' read_cache_enable 0
16900         cat $DIR/$tfile >/dev/null
16901
16902         # now data shouldn't be found in the cache
16903         BEFORE=$(roc_hit)
16904         cancel_lru_locks osc
16905         cat $DIR/$tfile >/dev/null
16906         AFTER=$(roc_hit)
16907         if let "AFTER - BEFORE != 0"; then
16908                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16909         fi
16910
16911         set_osd_param $list '' read_cache_enable 1
16912         rm -f $DIR/$tfile
16913 }
16914 run_test 151 "test cache on oss and controls ==============================="
16915
16916 test_152() {
16917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16918
16919         local TF="$TMP/$tfile"
16920
16921         # simulate ENOMEM during write
16922 #define OBD_FAIL_OST_NOMEM      0x226
16923         lctl set_param fail_loc=0x80000226
16924         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16925         cp $TF $DIR/$tfile
16926         sync || error "sync failed"
16927         lctl set_param fail_loc=0
16928
16929         # discard client's cache
16930         cancel_lru_locks osc
16931
16932         # simulate ENOMEM during read
16933         lctl set_param fail_loc=0x80000226
16934         cmp $TF $DIR/$tfile || error "cmp failed"
16935         lctl set_param fail_loc=0
16936
16937         rm -f $TF
16938 }
16939 run_test 152 "test read/write with enomem ============================"
16940
16941 test_153() {
16942         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16943 }
16944 run_test 153 "test if fdatasync does not crash ======================="
16945
16946 dot_lustre_fid_permission_check() {
16947         local fid=$1
16948         local ffid=$MOUNT/.lustre/fid/$fid
16949         local test_dir=$2
16950
16951         echo "stat fid $fid"
16952         stat $ffid || error "stat $ffid failed."
16953         echo "touch fid $fid"
16954         touch $ffid || error "touch $ffid failed."
16955         echo "write to fid $fid"
16956         cat /etc/hosts > $ffid || error "write $ffid failed."
16957         echo "read fid $fid"
16958         diff /etc/hosts $ffid || error "read $ffid failed."
16959         echo "append write to fid $fid"
16960         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16961         echo "rename fid $fid"
16962         mv $ffid $test_dir/$tfile.1 &&
16963                 error "rename $ffid to $tfile.1 should fail."
16964         touch $test_dir/$tfile.1
16965         mv $test_dir/$tfile.1 $ffid &&
16966                 error "rename $tfile.1 to $ffid should fail."
16967         rm -f $test_dir/$tfile.1
16968         echo "truncate fid $fid"
16969         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16970         echo "link fid $fid"
16971         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16972         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16973                 id $USER0 || skip_env "missing user $USER0"
16974                 echo "setfacl fid $fid"
16975                 setfacl -R -m u:$USER0:rwx $ffid ||
16976                         error "setfacl $ffid failed"
16977                 echo "getfacl fid $fid"
16978                 getfacl $ffid || error "getfacl $ffid failed."
16979         fi
16980         echo "unlink fid $fid"
16981         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16982         echo "mknod fid $fid"
16983         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16984
16985         fid=[0xf00000400:0x1:0x0]
16986         ffid=$MOUNT/.lustre/fid/$fid
16987
16988         echo "stat non-exist fid $fid"
16989         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16990         echo "write to non-exist fid $fid"
16991         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16992         echo "link new fid $fid"
16993         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16994
16995         mkdir -p $test_dir/$tdir
16996         touch $test_dir/$tdir/$tfile
16997         fid=$($LFS path2fid $test_dir/$tdir)
16998         rc=$?
16999         [ $rc -ne 0 ] &&
17000                 error "error: could not get fid for $test_dir/$dir/$tfile."
17001
17002         ffid=$MOUNT/.lustre/fid/$fid
17003
17004         echo "ls $fid"
17005         ls $ffid || error "ls $ffid failed."
17006         echo "touch $fid/$tfile.1"
17007         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
17008
17009         echo "touch $MOUNT/.lustre/fid/$tfile"
17010         touch $MOUNT/.lustre/fid/$tfile && \
17011                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
17012
17013         echo "setxattr to $MOUNT/.lustre/fid"
17014         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
17015
17016         echo "listxattr for $MOUNT/.lustre/fid"
17017         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
17018
17019         echo "delxattr from $MOUNT/.lustre/fid"
17020         setfattr -x trusted.name1 $MOUNT/.lustre/fid
17021
17022         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
17023         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
17024                 error "touch invalid fid should fail."
17025
17026         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
17027         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
17028                 error "touch non-normal fid should fail."
17029
17030         echo "rename $tdir to $MOUNT/.lustre/fid"
17031         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
17032                 error "rename to $MOUNT/.lustre/fid should fail."
17033
17034         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
17035         then            # LU-3547
17036                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
17037                 local new_obf_mode=777
17038
17039                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
17040                 chmod $new_obf_mode $DIR/.lustre/fid ||
17041                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
17042
17043                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
17044                 [ $obf_mode -eq $new_obf_mode ] ||
17045                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
17046
17047                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
17048                 chmod $old_obf_mode $DIR/.lustre/fid ||
17049                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
17050         fi
17051
17052         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
17053         fid=$($LFS path2fid $test_dir/$tfile-2)
17054
17055         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
17056         then # LU-5424
17057                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17058                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17059                         error "create lov data thru .lustre failed"
17060         fi
17061         echo "cp /etc/passwd $test_dir/$tfile-2"
17062         cp /etc/passwd $test_dir/$tfile-2 ||
17063                 error "copy to $test_dir/$tfile-2 failed."
17064         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17065         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17066                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17067
17068         rm -rf $test_dir/tfile.lnk
17069         rm -rf $test_dir/$tfile-2
17070 }
17071
17072 test_154A() {
17073         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17074                 skip "Need MDS version at least 2.4.1"
17075
17076         local tf=$DIR/$tfile
17077         touch $tf
17078
17079         local fid=$($LFS path2fid $tf)
17080         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17081
17082         # check that we get the same pathname back
17083         local rootpath
17084         local found
17085         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17086                 echo "$rootpath $fid"
17087                 found=$($LFS fid2path $rootpath "$fid")
17088                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17089                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17090         done
17091
17092         # check wrong root path format
17093         rootpath=$MOUNT"_wrong"
17094         found=$($LFS fid2path $rootpath "$fid")
17095         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17096 }
17097 run_test 154A "lfs path2fid and fid2path basic checks"
17098
17099 test_154B() {
17100         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17101                 skip "Need MDS version at least 2.4.1"
17102
17103         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17104         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17105         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17106         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17107
17108         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17109         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17110
17111         # check that we get the same pathname
17112         echo "PFID: $PFID, name: $name"
17113         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17114         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17115         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17116                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17117
17118         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17119 }
17120 run_test 154B "verify the ll_decode_linkea tool"
17121
17122 test_154a() {
17123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17124         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17125         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17126                 skip "Need MDS version at least 2.2.51"
17127         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17128
17129         cp /etc/hosts $DIR/$tfile
17130
17131         fid=$($LFS path2fid $DIR/$tfile)
17132         rc=$?
17133         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17134
17135         dot_lustre_fid_permission_check "$fid" $DIR ||
17136                 error "dot lustre permission check $fid failed"
17137
17138         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17139
17140         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17141
17142         touch $MOUNT/.lustre/file &&
17143                 error "creation is not allowed under .lustre"
17144
17145         mkdir $MOUNT/.lustre/dir &&
17146                 error "mkdir is not allowed under .lustre"
17147
17148         rm -rf $DIR/$tfile
17149 }
17150 run_test 154a "Open-by-FID"
17151
17152 test_154b() {
17153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17154         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17155         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17156         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17157                 skip "Need MDS version at least 2.2.51"
17158
17159         local remote_dir=$DIR/$tdir/remote_dir
17160         local MDTIDX=1
17161         local rc=0
17162
17163         mkdir -p $DIR/$tdir
17164         $LFS mkdir -i $MDTIDX $remote_dir ||
17165                 error "create remote directory failed"
17166
17167         cp /etc/hosts $remote_dir/$tfile
17168
17169         fid=$($LFS path2fid $remote_dir/$tfile)
17170         rc=$?
17171         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17172
17173         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17174                 error "dot lustre permission check $fid failed"
17175         rm -rf $DIR/$tdir
17176 }
17177 run_test 154b "Open-by-FID for remote directory"
17178
17179 test_154c() {
17180         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17181                 skip "Need MDS version at least 2.4.1"
17182
17183         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17184         local FID1=$($LFS path2fid $DIR/$tfile.1)
17185         local FID2=$($LFS path2fid $DIR/$tfile.2)
17186         local FID3=$($LFS path2fid $DIR/$tfile.3)
17187
17188         local N=1
17189         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17190                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17191                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17192                 local want=FID$N
17193                 [ "$FID" = "${!want}" ] ||
17194                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17195                 N=$((N + 1))
17196         done
17197
17198         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17199         do
17200                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17201                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17202                 N=$((N + 1))
17203         done
17204 }
17205 run_test 154c "lfs path2fid and fid2path multiple arguments"
17206
17207 test_154d() {
17208         remote_mds_nodsh && skip "remote MDS with nodsh"
17209         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17210                 skip "Need MDS version at least 2.5.53"
17211
17212         if remote_mds; then
17213                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17214         else
17215                 nid="0@lo"
17216         fi
17217         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17218         local fd
17219         local cmd
17220
17221         rm -f $DIR/$tfile
17222         touch $DIR/$tfile
17223
17224         local fid=$($LFS path2fid $DIR/$tfile)
17225         # Open the file
17226         fd=$(free_fd)
17227         cmd="exec $fd<$DIR/$tfile"
17228         eval $cmd
17229         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17230         echo "$fid_list" | grep "$fid"
17231         rc=$?
17232
17233         cmd="exec $fd>/dev/null"
17234         eval $cmd
17235         if [ $rc -ne 0 ]; then
17236                 error "FID $fid not found in open files list $fid_list"
17237         fi
17238 }
17239 run_test 154d "Verify open file fid"
17240
17241 test_154e()
17242 {
17243         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17244                 skip "Need MDS version at least 2.6.50"
17245
17246         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17247                 error ".lustre returned by readdir"
17248         fi
17249 }
17250 run_test 154e ".lustre is not returned by readdir"
17251
17252 test_154f() {
17253         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17254
17255         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17256         mkdir_on_mdt0 $DIR/$tdir
17257         # test dirs inherit from its stripe
17258         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17259         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17260         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17261         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17262         touch $DIR/f
17263
17264         # get fid of parents
17265         local FID0=$($LFS path2fid $DIR/$tdir)
17266         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17267         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17268         local FID3=$($LFS path2fid $DIR)
17269
17270         # check that path2fid --parents returns expected <parent_fid>/name
17271         # 1) test for a directory (single parent)
17272         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17273         [ "$parent" == "$FID0/foo1" ] ||
17274                 error "expected parent: $FID0/foo1, got: $parent"
17275
17276         # 2) test for a file with nlink > 1 (multiple parents)
17277         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17278         echo "$parent" | grep -F "$FID1/$tfile" ||
17279                 error "$FID1/$tfile not returned in parent list"
17280         echo "$parent" | grep -F "$FID2/link" ||
17281                 error "$FID2/link not returned in parent list"
17282
17283         # 3) get parent by fid
17284         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17285         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17286         echo "$parent" | grep -F "$FID1/$tfile" ||
17287                 error "$FID1/$tfile not returned in parent list (by fid)"
17288         echo "$parent" | grep -F "$FID2/link" ||
17289                 error "$FID2/link not returned in parent list (by fid)"
17290
17291         # 4) test for entry in root directory
17292         parent=$($LFS path2fid --parents $DIR/f)
17293         echo "$parent" | grep -F "$FID3/f" ||
17294                 error "$FID3/f not returned in parent list"
17295
17296         # 5) test it on root directory
17297         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17298                 error "$MOUNT should not have parents"
17299
17300         # enable xattr caching and check that linkea is correctly updated
17301         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17302         save_lustre_params client "llite.*.xattr_cache" > $save
17303         lctl set_param llite.*.xattr_cache 1
17304
17305         # 6.1) linkea update on rename
17306         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17307
17308         # get parents by fid
17309         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17310         # foo1 should no longer be returned in parent list
17311         echo "$parent" | grep -F "$FID1" &&
17312                 error "$FID1 should no longer be in parent list"
17313         # the new path should appear
17314         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17315                 error "$FID2/$tfile.moved is not in parent list"
17316
17317         # 6.2) linkea update on unlink
17318         rm -f $DIR/$tdir/foo2/link
17319         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17320         # foo2/link should no longer be returned in parent list
17321         echo "$parent" | grep -F "$FID2/link" &&
17322                 error "$FID2/link should no longer be in parent list"
17323         true
17324
17325         rm -f $DIR/f
17326         restore_lustre_params < $save
17327         rm -f $save
17328 }
17329 run_test 154f "get parent fids by reading link ea"
17330
17331 test_154g()
17332 {
17333         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17334            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17335                 skip "Need MDS version at least 2.6.92"
17336
17337         mkdir_on_mdt0 $DIR/$tdir
17338         llapi_fid_test -d $DIR/$tdir
17339 }
17340 run_test 154g "various llapi FID tests"
17341
17342 test_154h()
17343 {
17344         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17345                 skip "Need client at least version 2.15.55.1"
17346
17347         # Create an empty file
17348         touch $DIR/$tfile
17349
17350         # Get FID (interactive mode) and save under $TMP/$tfile.log
17351         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17352                 path2fid $DIR/$tfile
17353         EOF
17354
17355         fid=$(cat $TMP/$tfile.log)
17356         # $fid should not be empty
17357         [[ ! -z $fid ]] || error "FID is empty"
17358         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17359 }
17360 run_test 154h "Verify interactive path2fid"
17361
17362 test_155_small_load() {
17363     local temp=$TMP/$tfile
17364     local file=$DIR/$tfile
17365
17366     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17367         error "dd of=$temp bs=6096 count=1 failed"
17368     cp $temp $file
17369     cancel_lru_locks $OSC
17370     cmp $temp $file || error "$temp $file differ"
17371
17372     $TRUNCATE $temp 6000
17373     $TRUNCATE $file 6000
17374     cmp $temp $file || error "$temp $file differ (truncate1)"
17375
17376     echo "12345" >>$temp
17377     echo "12345" >>$file
17378     cmp $temp $file || error "$temp $file differ (append1)"
17379
17380     echo "12345" >>$temp
17381     echo "12345" >>$file
17382     cmp $temp $file || error "$temp $file differ (append2)"
17383
17384     rm -f $temp $file
17385     true
17386 }
17387
17388 test_155_big_load() {
17389         remote_ost_nodsh && skip "remote OST with nodsh"
17390
17391         local temp=$TMP/$tfile
17392         local file=$DIR/$tfile
17393
17394         free_min_max
17395         local cache_size=$(do_facet ost$((MAXI+1)) \
17396                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17397
17398         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17399         # pre-set value
17400         if [ -z "$cache_size" ]; then
17401                 cache_size=256
17402         fi
17403         local large_file_size=$((cache_size * 2))
17404
17405         echo "OSS cache size: $cache_size KB"
17406         echo "Large file size: $large_file_size KB"
17407
17408         [ $MAXV -le $large_file_size ] &&
17409                 skip_env "max available OST size needs > $large_file_size KB"
17410
17411         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17412
17413         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17414                 error "dd of=$temp bs=$large_file_size count=1k failed"
17415         cp $temp $file
17416         ls -lh $temp $file
17417         cancel_lru_locks osc
17418         cmp $temp $file || error "$temp $file differ"
17419
17420         rm -f $temp $file
17421         true
17422 }
17423
17424 save_writethrough() {
17425         local facets=$(get_facets OST)
17426
17427         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17428 }
17429
17430 test_155a() {
17431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17432
17433         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17434
17435         save_writethrough $p
17436
17437         set_cache read on
17438         set_cache writethrough on
17439         test_155_small_load
17440         restore_lustre_params < $p
17441         rm -f $p
17442 }
17443 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17444
17445 test_155b() {
17446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17447
17448         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17449
17450         save_writethrough $p
17451
17452         set_cache read on
17453         set_cache writethrough off
17454         test_155_small_load
17455         restore_lustre_params < $p
17456         rm -f $p
17457 }
17458 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17459
17460 test_155c() {
17461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17462
17463         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17464
17465         save_writethrough $p
17466
17467         set_cache read off
17468         set_cache writethrough on
17469         test_155_small_load
17470         restore_lustre_params < $p
17471         rm -f $p
17472 }
17473 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17474
17475 test_155d() {
17476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17477
17478         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17479
17480         save_writethrough $p
17481
17482         set_cache read off
17483         set_cache writethrough off
17484         test_155_small_load
17485         restore_lustre_params < $p
17486         rm -f $p
17487 }
17488 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17489
17490 test_155e() {
17491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17492
17493         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17494
17495         save_writethrough $p
17496
17497         set_cache read on
17498         set_cache writethrough on
17499         test_155_big_load
17500         restore_lustre_params < $p
17501         rm -f $p
17502 }
17503 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17504
17505 test_155f() {
17506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17507
17508         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17509
17510         save_writethrough $p
17511
17512         set_cache read on
17513         set_cache writethrough off
17514         test_155_big_load
17515         restore_lustre_params < $p
17516         rm -f $p
17517 }
17518 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17519
17520 test_155g() {
17521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17522
17523         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17524
17525         save_writethrough $p
17526
17527         set_cache read off
17528         set_cache writethrough on
17529         test_155_big_load
17530         restore_lustre_params < $p
17531         rm -f $p
17532 }
17533 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17534
17535 test_155h() {
17536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17537
17538         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17539
17540         save_writethrough $p
17541
17542         set_cache read off
17543         set_cache writethrough off
17544         test_155_big_load
17545         restore_lustre_params < $p
17546         rm -f $p
17547 }
17548 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17549
17550 test_156() {
17551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17552         remote_ost_nodsh && skip "remote OST with nodsh"
17553         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17554                 skip "stats not implemented on old servers"
17555         [ "$ost1_FSTYPE" = "zfs" ] &&
17556                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17557         (( CLIENT_VERSION == OST1_VERSION )) ||
17558                 skip "LU-13081: no interop testing for OSS cache"
17559
17560         local CPAGES=3
17561         local BEFORE
17562         local AFTER
17563         local file="$DIR/$tfile"
17564         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17565
17566         save_writethrough $p
17567         roc_hit_init
17568
17569         log "Turn on read and write cache"
17570         set_cache read on
17571         set_cache writethrough on
17572
17573         log "Write data and read it back."
17574         log "Read should be satisfied from the cache."
17575         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17576         BEFORE=$(roc_hit)
17577         cancel_lru_locks osc
17578         cat $file >/dev/null
17579         AFTER=$(roc_hit)
17580         if ! let "AFTER - BEFORE == CPAGES"; then
17581                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17582         else
17583                 log "cache hits: before: $BEFORE, after: $AFTER"
17584         fi
17585
17586         log "Read again; it should be satisfied from the cache."
17587         BEFORE=$AFTER
17588         cancel_lru_locks osc
17589         cat $file >/dev/null
17590         AFTER=$(roc_hit)
17591         if ! let "AFTER - BEFORE == CPAGES"; then
17592                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17593         else
17594                 log "cache hits:: before: $BEFORE, after: $AFTER"
17595         fi
17596
17597         log "Turn off the read cache and turn on the write cache"
17598         set_cache read off
17599         set_cache writethrough on
17600
17601         log "Read again; it should be satisfied from the cache."
17602         BEFORE=$(roc_hit)
17603         cancel_lru_locks osc
17604         cat $file >/dev/null
17605         AFTER=$(roc_hit)
17606         if ! let "AFTER - BEFORE == CPAGES"; then
17607                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17608         else
17609                 log "cache hits:: before: $BEFORE, after: $AFTER"
17610         fi
17611
17612         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17613                 # > 2.12.56 uses pagecache if cached
17614                 log "Read again; it should not be satisfied from the cache."
17615                 BEFORE=$AFTER
17616                 cancel_lru_locks osc
17617                 cat $file >/dev/null
17618                 AFTER=$(roc_hit)
17619                 if ! let "AFTER - BEFORE == 0"; then
17620                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17621                 else
17622                         log "cache hits:: before: $BEFORE, after: $AFTER"
17623                 fi
17624         fi
17625
17626         log "Write data and read it back."
17627         log "Read should be satisfied from the cache."
17628         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17629         BEFORE=$(roc_hit)
17630         cancel_lru_locks osc
17631         cat $file >/dev/null
17632         AFTER=$(roc_hit)
17633         if ! let "AFTER - BEFORE == CPAGES"; then
17634                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17635         else
17636                 log "cache hits:: before: $BEFORE, after: $AFTER"
17637         fi
17638
17639         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17640                 # > 2.12.56 uses pagecache if cached
17641                 log "Read again; it should not be satisfied from the cache."
17642                 BEFORE=$AFTER
17643                 cancel_lru_locks osc
17644                 cat $file >/dev/null
17645                 AFTER=$(roc_hit)
17646                 if ! let "AFTER - BEFORE == 0"; then
17647                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17648                 else
17649                         log "cache hits:: before: $BEFORE, after: $AFTER"
17650                 fi
17651         fi
17652
17653         log "Turn off read and write cache"
17654         set_cache read off
17655         set_cache writethrough off
17656
17657         log "Write data and read it back"
17658         log "It should not be satisfied from the cache."
17659         rm -f $file
17660         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17661         cancel_lru_locks osc
17662         BEFORE=$(roc_hit)
17663         cat $file >/dev/null
17664         AFTER=$(roc_hit)
17665         if ! let "AFTER - BEFORE == 0"; then
17666                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17667         else
17668                 log "cache hits:: before: $BEFORE, after: $AFTER"
17669         fi
17670
17671         log "Turn on the read cache and turn off the write cache"
17672         set_cache read on
17673         set_cache writethrough off
17674
17675         log "Write data and read it back"
17676         log "It should not be satisfied from the cache."
17677         rm -f $file
17678         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17679         BEFORE=$(roc_hit)
17680         cancel_lru_locks osc
17681         cat $file >/dev/null
17682         AFTER=$(roc_hit)
17683         if ! let "AFTER - BEFORE == 0"; then
17684                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17685         else
17686                 log "cache hits:: before: $BEFORE, after: $AFTER"
17687         fi
17688
17689         log "Read again; it should be satisfied from the cache."
17690         BEFORE=$(roc_hit)
17691         cancel_lru_locks osc
17692         cat $file >/dev/null
17693         AFTER=$(roc_hit)
17694         if ! let "AFTER - BEFORE == CPAGES"; then
17695                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17696         else
17697                 log "cache hits:: before: $BEFORE, after: $AFTER"
17698         fi
17699
17700         restore_lustre_params < $p
17701         rm -f $p $file
17702 }
17703 run_test 156 "Verification of tunables"
17704
17705 test_160a() {
17706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17707         remote_mds_nodsh && skip "remote MDS with nodsh"
17708         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17709                 skip "Need MDS version at least 2.2.0"
17710
17711         changelog_register || error "changelog_register failed"
17712         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17713         changelog_users $SINGLEMDS | grep -q $cl_user ||
17714                 error "User $cl_user not found in changelog_users"
17715
17716         mkdir_on_mdt0 $DIR/$tdir
17717
17718         # change something
17719         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17720         changelog_clear 0 || error "changelog_clear failed"
17721         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17722         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17723         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17724         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17725         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17726         rm $DIR/$tdir/pics/desktop.jpg
17727
17728         echo "verifying changelog mask"
17729         changelog_chmask "-MKDIR"
17730         changelog_chmask "-CLOSE"
17731
17732         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17733         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17734
17735         changelog_chmask "+MKDIR"
17736         changelog_chmask "+CLOSE"
17737
17738         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17739         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17740
17741         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17742         CLOSES=$(changelog_dump | grep -c "CLOSE")
17743         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17744         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17745
17746         # verify contents
17747         echo "verifying target fid"
17748         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17749         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17750         [ "$fidc" == "$fidf" ] ||
17751                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17752         echo "verifying parent fid"
17753         # The FID returned from the Changelog may be the directory shard on
17754         # a different MDT, and not the FID returned by path2fid on the parent.
17755         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17756         # since this is what will matter when recreating this file in the tree.
17757         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17758         local pathp=$($LFS fid2path $MOUNT "$fidp")
17759         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17760                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17761
17762         echo "getting records for $cl_user"
17763         changelog_users $SINGLEMDS
17764         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17765         local nclr=3
17766         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17767                 error "changelog_clear failed"
17768         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17769         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17770         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17771                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17772
17773         local min0_rec=$(changelog_users $SINGLEMDS |
17774                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17775         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17776                           awk '{ print $1; exit; }')
17777
17778         changelog_dump | tail -n 5
17779         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17780         [ $first_rec == $((min0_rec + 1)) ] ||
17781                 error "first index should be $min0_rec + 1 not $first_rec"
17782
17783         # LU-3446 changelog index reset on MDT restart
17784         local cur_rec1=$(changelog_users $SINGLEMDS |
17785                          awk '/^current.index:/ { print $NF }')
17786         changelog_clear 0 ||
17787                 error "clear all changelog records for $cl_user failed"
17788         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17789         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17790                 error "Fail to start $SINGLEMDS"
17791         local cur_rec2=$(changelog_users $SINGLEMDS |
17792                          awk '/^current.index:/ { print $NF }')
17793         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17794         [ $cur_rec1 == $cur_rec2 ] ||
17795                 error "current index should be $cur_rec1 not $cur_rec2"
17796
17797         echo "verifying users from this test are deregistered"
17798         changelog_deregister || error "changelog_deregister failed"
17799         changelog_users $SINGLEMDS | grep -q $cl_user &&
17800                 error "User '$cl_user' still in changelog_users"
17801
17802         # lctl get_param -n mdd.*.changelog_users
17803         # current_index: 144
17804         # ID    index (idle seconds)
17805         # cl3   144   (2) mask=<list>
17806         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17807                 # this is the normal case where all users were deregistered
17808                 # make sure no new records are added when no users are present
17809                 local last_rec1=$(changelog_users $SINGLEMDS |
17810                                   awk '/^current.index:/ { print $NF }')
17811                 touch $DIR/$tdir/chloe
17812                 local last_rec2=$(changelog_users $SINGLEMDS |
17813                                   awk '/^current.index:/ { print $NF }')
17814                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17815                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17816         else
17817                 # any changelog users must be leftovers from a previous test
17818                 changelog_users $SINGLEMDS
17819                 echo "other changelog users; can't verify off"
17820         fi
17821 }
17822 run_test 160a "changelog sanity"
17823
17824 test_160b() { # LU-3587
17825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17826         remote_mds_nodsh && skip "remote MDS with nodsh"
17827         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17828                 skip "Need MDS version at least 2.2.0"
17829
17830         changelog_register || error "changelog_register failed"
17831         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17832         changelog_users $SINGLEMDS | grep -q $cl_user ||
17833                 error "User '$cl_user' not found in changelog_users"
17834
17835         local longname1=$(str_repeat a 255)
17836         local longname2=$(str_repeat b 255)
17837
17838         cd $DIR
17839         echo "creating very long named file"
17840         touch $longname1 || error "create of '$longname1' failed"
17841         echo "renaming very long named file"
17842         mv $longname1 $longname2
17843
17844         changelog_dump | grep RENME | tail -n 5
17845         rm -f $longname2
17846 }
17847 run_test 160b "Verify that very long rename doesn't crash in changelog"
17848
17849 test_160c() {
17850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17851         remote_mds_nodsh && skip "remote MDS with nodsh"
17852
17853         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17854                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17855                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17856                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17857
17858         local rc=0
17859
17860         # Registration step
17861         changelog_register || error "changelog_register failed"
17862
17863         rm -rf $DIR/$tdir
17864         mkdir -p $DIR/$tdir
17865         $MCREATE $DIR/$tdir/foo_160c
17866         changelog_chmask "-TRUNC"
17867         $TRUNCATE $DIR/$tdir/foo_160c 200
17868         changelog_chmask "+TRUNC"
17869         $TRUNCATE $DIR/$tdir/foo_160c 199
17870         changelog_dump | tail -n 5
17871         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17872         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17873 }
17874 run_test 160c "verify that changelog log catch the truncate event"
17875
17876 test_160d() {
17877         remote_mds_nodsh && skip "remote MDS with nodsh"
17878         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17880         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17881                 skip "Need MDS version at least 2.7.60"
17882
17883         # Registration step
17884         changelog_register || error "changelog_register failed"
17885
17886         mkdir -p $DIR/$tdir/migrate_dir
17887         changelog_clear 0 || error "changelog_clear failed"
17888
17889         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17890         changelog_dump | tail -n 5
17891         local migrates=$(changelog_dump | grep -c "MIGRT")
17892         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17893 }
17894 run_test 160d "verify that changelog log catch the migrate event"
17895
17896 test_160e() {
17897         remote_mds_nodsh && skip "remote MDS with nodsh"
17898
17899         # Create a user
17900         changelog_register || error "changelog_register failed"
17901
17902         local MDT0=$(facet_svc $SINGLEMDS)
17903         local rc
17904
17905         # No user (expect fail)
17906         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17907         rc=$?
17908         if [ $rc -eq 0 ]; then
17909                 error "Should fail without user"
17910         elif [ $rc -ne 4 ]; then
17911                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17912         fi
17913
17914         # Delete a future user (expect fail)
17915         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17916         rc=$?
17917         if [ $rc -eq 0 ]; then
17918                 error "Deleted non-existant user cl77"
17919         elif [ $rc -ne 2 ]; then
17920                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17921         fi
17922
17923         # Clear to a bad index (1 billion should be safe)
17924         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17925         rc=$?
17926
17927         if [ $rc -eq 0 ]; then
17928                 error "Successfully cleared to invalid CL index"
17929         elif [ $rc -ne 22 ]; then
17930                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17931         fi
17932 }
17933 run_test 160e "changelog negative testing (should return errors)"
17934
17935 test_160f() {
17936         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17937         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17938                 skip "Need MDS version at least 2.10.56"
17939
17940         local mdts=$(comma_list $(mdts_nodes))
17941
17942         # Create a user
17943         changelog_register || error "first changelog_register failed"
17944         changelog_register || error "second changelog_register failed"
17945         local cl_users
17946         declare -A cl_user1
17947         declare -A cl_user2
17948         local user_rec1
17949         local user_rec2
17950         local i
17951
17952         # generate some changelog records to accumulate on each MDT
17953         # use all_char because created files should be evenly distributed
17954         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17955                 error "test_mkdir $tdir failed"
17956         log "$(date +%s): creating first files"
17957         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17958                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17959                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17960         done
17961
17962         # check changelogs have been generated
17963         local start=$SECONDS
17964         local idle_time=$((MDSCOUNT * 5 + 5))
17965         local nbcl=$(changelog_dump | wc -l)
17966         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17967
17968         for param in "changelog_max_idle_time=$idle_time" \
17969                      "changelog_gc=1" \
17970                      "changelog_min_gc_interval=2" \
17971                      "changelog_min_free_cat_entries=3"; do
17972                 local MDT0=$(facet_svc $SINGLEMDS)
17973                 local var="${param%=*}"
17974                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17975
17976                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17977                 do_nodes $mdts $LCTL set_param mdd.*.$param
17978         done
17979
17980         # force cl_user2 to be idle (1st part), but also cancel the
17981         # cl_user1 records so that it is not evicted later in the test.
17982         local sleep1=$((idle_time / 2))
17983         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17984         sleep $sleep1
17985
17986         # simulate changelog catalog almost full
17987         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17988         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17989
17990         for i in $(seq $MDSCOUNT); do
17991                 cl_users=(${CL_USERS[mds$i]})
17992                 cl_user1[mds$i]="${cl_users[0]}"
17993                 cl_user2[mds$i]="${cl_users[1]}"
17994
17995                 [ -n "${cl_user1[mds$i]}" ] ||
17996                         error "mds$i: no user registered"
17997                 [ -n "${cl_user2[mds$i]}" ] ||
17998                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17999
18000                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18001                 [ -n "$user_rec1" ] ||
18002                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18003                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18004                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18005                 [ -n "$user_rec2" ] ||
18006                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18007                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18008                      "$user_rec1 + 2 == $user_rec2"
18009                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18010                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18011                               "$user_rec1 + 2, but is $user_rec2"
18012                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18013                 [ -n "$user_rec2" ] ||
18014                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18015                 [ $user_rec1 == $user_rec2 ] ||
18016                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18017                               "$user_rec1, but is $user_rec2"
18018         done
18019
18020         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
18021         local sleep2=$((idle_time - (SECONDS - start) + 1))
18022         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
18023         sleep $sleep2
18024
18025         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18026         # cl_user1 should be OK because it recently processed records.
18027         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
18028         for ((i = 0; i < MDSCOUNT * 2; i++)); do
18029                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
18030                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
18031         done
18032
18033         # ensure gc thread is done
18034         for i in $(mdts_nodes); do
18035                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18036                         error "$i: GC-thread not done"
18037         done
18038
18039         local first_rec
18040         for (( i = 1; i <= MDSCOUNT; i++ )); do
18041                 # check cl_user1 still registered
18042                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18043                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18044                 # check cl_user2 unregistered
18045                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18046                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18047
18048                 # check changelogs are present and starting at $user_rec1 + 1
18049                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18050                 [ -n "$user_rec1" ] ||
18051                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18052                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18053                             awk '{ print $1; exit; }')
18054
18055                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18056                 [ $((user_rec1 + 1)) == $first_rec ] ||
18057                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18058         done
18059 }
18060 run_test 160f "changelog garbage collect (timestamped users)"
18061
18062 test_160g() {
18063         remote_mds_nodsh && skip "remote MDS with nodsh"
18064         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18065                 skip "Need MDS version at least 2.14.55"
18066
18067         local mdts=$(comma_list $(mdts_nodes))
18068
18069         # Create a user
18070         changelog_register || error "first changelog_register failed"
18071         changelog_register || error "second changelog_register failed"
18072         local cl_users
18073         declare -A cl_user1
18074         declare -A cl_user2
18075         local user_rec1
18076         local user_rec2
18077         local i
18078
18079         # generate some changelog records to accumulate on each MDT
18080         # use all_char because created files should be evenly distributed
18081         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18082                 error "test_mkdir $tdir failed"
18083         for ((i = 0; i < MDSCOUNT; i++)); do
18084                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18085                         error "create $DIR/$tdir/d$i.1 failed"
18086         done
18087
18088         # check changelogs have been generated
18089         local nbcl=$(changelog_dump | wc -l)
18090         (( $nbcl > 0 )) || error "no changelogs found"
18091
18092         # reduce the max_idle_indexes value to make sure we exceed it
18093         for param in "changelog_max_idle_indexes=2" \
18094                      "changelog_gc=1" \
18095                      "changelog_min_gc_interval=2"; do
18096                 local MDT0=$(facet_svc $SINGLEMDS)
18097                 local var="${param%=*}"
18098                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18099
18100                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18101                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18102                         error "unable to set mdd.*.$param"
18103         done
18104
18105         local start=$SECONDS
18106         for i in $(seq $MDSCOUNT); do
18107                 cl_users=(${CL_USERS[mds$i]})
18108                 cl_user1[mds$i]="${cl_users[0]}"
18109                 cl_user2[mds$i]="${cl_users[1]}"
18110
18111                 [ -n "${cl_user1[mds$i]}" ] ||
18112                         error "mds$i: user1 is not registered"
18113                 [ -n "${cl_user2[mds$i]}" ] ||
18114                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18115
18116                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18117                 [ -n "$user_rec1" ] ||
18118                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18119                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18120                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18121                 [ -n "$user_rec2" ] ||
18122                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18123                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18124                      "$user_rec1 + 2 == $user_rec2"
18125                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18126                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18127                               "expected $user_rec1 + 2, but is $user_rec2"
18128                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18129                 [ -n "$user_rec2" ] ||
18130                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18131                 [ $user_rec1 == $user_rec2 ] ||
18132                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18133                               "expected $user_rec1, but is $user_rec2"
18134         done
18135
18136         # ensure we are past the previous changelog_min_gc_interval set above
18137         local sleep2=$((start + 2 - SECONDS))
18138         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18139         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18140         # cl_user1 should be OK because it recently processed records.
18141         for ((i = 0; i < MDSCOUNT; i++)); do
18142                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18143                         error "create $DIR/$tdir/d$i.3 failed"
18144         done
18145
18146         # ensure gc thread is done
18147         for i in $(mdts_nodes); do
18148                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18149                         error "$i: GC-thread not done"
18150         done
18151
18152         local first_rec
18153         for (( i = 1; i <= MDSCOUNT; i++ )); do
18154                 # check cl_user1 still registered
18155                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18156                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18157                 # check cl_user2 unregistered
18158                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18159                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18160
18161                 # check changelogs are present and starting at $user_rec1 + 1
18162                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18163                 [ -n "$user_rec1" ] ||
18164                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18165                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18166                             awk '{ print $1; exit; }')
18167
18168                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18169                 [ $((user_rec1 + 1)) == $first_rec ] ||
18170                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18171         done
18172 }
18173 run_test 160g "changelog garbage collect on idle records"
18174
18175 test_160h() {
18176         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18177         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18178                 skip "Need MDS version at least 2.10.56"
18179
18180         local mdts=$(comma_list $(mdts_nodes))
18181
18182         # Create a user
18183         changelog_register || error "first changelog_register failed"
18184         changelog_register || error "second changelog_register failed"
18185         local cl_users
18186         declare -A cl_user1
18187         declare -A cl_user2
18188         local user_rec1
18189         local user_rec2
18190         local i
18191
18192         # generate some changelog records to accumulate on each MDT
18193         # use all_char because created files should be evenly distributed
18194         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18195                 error "test_mkdir $tdir failed"
18196         for ((i = 0; i < MDSCOUNT; i++)); do
18197                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18198                         error "create $DIR/$tdir/d$i.1 failed"
18199         done
18200
18201         # check changelogs have been generated
18202         local nbcl=$(changelog_dump | wc -l)
18203         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18204
18205         for param in "changelog_max_idle_time=10" \
18206                      "changelog_gc=1" \
18207                      "changelog_min_gc_interval=2"; do
18208                 local MDT0=$(facet_svc $SINGLEMDS)
18209                 local var="${param%=*}"
18210                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18211
18212                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18213                 do_nodes $mdts $LCTL set_param mdd.*.$param
18214         done
18215
18216         # force cl_user2 to be idle (1st part)
18217         sleep 9
18218
18219         for i in $(seq $MDSCOUNT); do
18220                 cl_users=(${CL_USERS[mds$i]})
18221                 cl_user1[mds$i]="${cl_users[0]}"
18222                 cl_user2[mds$i]="${cl_users[1]}"
18223
18224                 [ -n "${cl_user1[mds$i]}" ] ||
18225                         error "mds$i: no user registered"
18226                 [ -n "${cl_user2[mds$i]}" ] ||
18227                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18228
18229                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18230                 [ -n "$user_rec1" ] ||
18231                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18232                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18233                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18234                 [ -n "$user_rec2" ] ||
18235                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18236                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18237                      "$user_rec1 + 2 == $user_rec2"
18238                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18239                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18240                               "$user_rec1 + 2, but is $user_rec2"
18241                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18242                 [ -n "$user_rec2" ] ||
18243                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18244                 [ $user_rec1 == $user_rec2 ] ||
18245                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18246                               "$user_rec1, but is $user_rec2"
18247         done
18248
18249         # force cl_user2 to be idle (2nd part) and to reach
18250         # changelog_max_idle_time
18251         sleep 2
18252
18253         # force each GC-thread start and block then
18254         # one per MDT/MDD, set fail_val accordingly
18255         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18256         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18257
18258         # generate more changelogs to trigger fail_loc
18259         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18260                 error "create $DIR/$tdir/${tfile}bis failed"
18261
18262         # stop MDT to stop GC-thread, should be done in back-ground as it will
18263         # block waiting for the thread to be released and exit
18264         declare -A stop_pids
18265         for i in $(seq $MDSCOUNT); do
18266                 stop mds$i &
18267                 stop_pids[mds$i]=$!
18268         done
18269
18270         for i in $(mdts_nodes); do
18271                 local facet
18272                 local nb=0
18273                 local facets=$(facets_up_on_host $i)
18274
18275                 for facet in ${facets//,/ }; do
18276                         if [[ $facet == mds* ]]; then
18277                                 nb=$((nb + 1))
18278                         fi
18279                 done
18280                 # ensure each MDS's gc threads are still present and all in "R"
18281                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18282                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18283                         error "$i: expected $nb GC-thread"
18284                 wait_update $i \
18285                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18286                         "R" 20 ||
18287                         error "$i: GC-thread not found in R-state"
18288                 # check umounts of each MDT on MDS have reached kthread_stop()
18289                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18290                         error "$i: expected $nb umount"
18291                 wait_update $i \
18292                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18293                         error "$i: umount not found in D-state"
18294         done
18295
18296         # release all GC-threads
18297         do_nodes $mdts $LCTL set_param fail_loc=0
18298
18299         # wait for MDT stop to complete
18300         for i in $(seq $MDSCOUNT); do
18301                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18302         done
18303
18304         # XXX
18305         # may try to check if any orphan changelog records are present
18306         # via ldiskfs/zfs and llog_reader...
18307
18308         # re-start/mount MDTs
18309         for i in $(seq $MDSCOUNT); do
18310                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18311                         error "Fail to start mds$i"
18312         done
18313
18314         local first_rec
18315         for i in $(seq $MDSCOUNT); do
18316                 # check cl_user1 still registered
18317                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18318                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18319                 # check cl_user2 unregistered
18320                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18321                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18322
18323                 # check changelogs are present and starting at $user_rec1 + 1
18324                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18325                 [ -n "$user_rec1" ] ||
18326                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18327                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18328                             awk '{ print $1; exit; }')
18329
18330                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18331                 [ $((user_rec1 + 1)) == $first_rec ] ||
18332                         error "mds$i: first index should be $user_rec1 + 1, " \
18333                               "but is $first_rec"
18334         done
18335 }
18336 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18337               "during mount"
18338
18339 test_160i() {
18340
18341         local mdts=$(comma_list $(mdts_nodes))
18342
18343         changelog_register || error "first changelog_register failed"
18344
18345         # generate some changelog records to accumulate on each MDT
18346         # use all_char because created files should be evenly distributed
18347         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18348                 error "test_mkdir $tdir failed"
18349         for ((i = 0; i < MDSCOUNT; i++)); do
18350                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18351                         error "create $DIR/$tdir/d$i.1 failed"
18352         done
18353
18354         # check changelogs have been generated
18355         local nbcl=$(changelog_dump | wc -l)
18356         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18357
18358         # simulate race between register and unregister
18359         # XXX as fail_loc is set per-MDS, with DNE configs the race
18360         # simulation will only occur for one MDT per MDS and for the
18361         # others the normal race scenario will take place
18362         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18363         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18364         do_nodes $mdts $LCTL set_param fail_val=1
18365
18366         # unregister 1st user
18367         changelog_deregister &
18368         local pid1=$!
18369         # wait some time for deregister work to reach race rdv
18370         sleep 2
18371         # register 2nd user
18372         changelog_register || error "2nd user register failed"
18373
18374         wait $pid1 || error "1st user deregister failed"
18375
18376         local i
18377         local last_rec
18378         declare -A LAST_REC
18379         for i in $(seq $MDSCOUNT); do
18380                 if changelog_users mds$i | grep "^cl"; then
18381                         # make sure new records are added with one user present
18382                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18383                                           awk '/^current.index:/ { print $NF }')
18384                 else
18385                         error "mds$i has no user registered"
18386                 fi
18387         done
18388
18389         # generate more changelog records to accumulate on each MDT
18390         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18391                 error "create $DIR/$tdir/${tfile}bis failed"
18392
18393         for i in $(seq $MDSCOUNT); do
18394                 last_rec=$(changelog_users $SINGLEMDS |
18395                            awk '/^current.index:/ { print $NF }')
18396                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18397                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18398                         error "changelogs are off on mds$i"
18399         done
18400 }
18401 run_test 160i "changelog user register/unregister race"
18402
18403 test_160j() {
18404         remote_mds_nodsh && skip "remote MDS with nodsh"
18405         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18406                 skip "Need MDS version at least 2.12.56"
18407
18408         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18409         stack_trap "umount $MOUNT2" EXIT
18410
18411         changelog_register || error "first changelog_register failed"
18412         stack_trap "changelog_deregister" EXIT
18413
18414         # generate some changelog
18415         # use all_char because created files should be evenly distributed
18416         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18417                 error "mkdir $tdir failed"
18418         for ((i = 0; i < MDSCOUNT; i++)); do
18419                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18420                         error "create $DIR/$tdir/d$i.1 failed"
18421         done
18422
18423         # open the changelog device
18424         exec 3>/dev/changelog-$FSNAME-MDT0000
18425         stack_trap "exec 3>&-" EXIT
18426         exec 4</dev/changelog-$FSNAME-MDT0000
18427         stack_trap "exec 4<&-" EXIT
18428
18429         # umount the first lustre mount
18430         umount $MOUNT
18431         stack_trap "mount_client $MOUNT" EXIT
18432
18433         # read changelog, which may or may not fail, but should not crash
18434         cat <&4 >/dev/null
18435
18436         # clear changelog
18437         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18438         changelog_users $SINGLEMDS | grep -q $cl_user ||
18439                 error "User $cl_user not found in changelog_users"
18440
18441         printf 'clear:'$cl_user':0' >&3
18442 }
18443 run_test 160j "client can be umounted while its chanangelog is being used"
18444
18445 test_160k() {
18446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18447         remote_mds_nodsh && skip "remote MDS with nodsh"
18448
18449         mkdir -p $DIR/$tdir/1/1
18450
18451         changelog_register || error "changelog_register failed"
18452         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18453
18454         changelog_users $SINGLEMDS | grep -q $cl_user ||
18455                 error "User '$cl_user' not found in changelog_users"
18456 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18457         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18458         rmdir $DIR/$tdir/1/1 & sleep 1
18459         mkdir $DIR/$tdir/2
18460         touch $DIR/$tdir/2/2
18461         rm -rf $DIR/$tdir/2
18462
18463         wait
18464         sleep 4
18465
18466         changelog_dump | grep rmdir || error "rmdir not recorded"
18467 }
18468 run_test 160k "Verify that changelog records are not lost"
18469
18470 # Verifies that a file passed as a parameter has recently had an operation
18471 # performed on it that has generated an MTIME changelog which contains the
18472 # correct parent FID. As files might reside on a different MDT from the
18473 # parent directory in DNE configurations, the FIDs are translated to paths
18474 # before being compared, which should be identical
18475 compare_mtime_changelog() {
18476         local file="${1}"
18477         local mdtidx
18478         local mtime
18479         local cl_fid
18480         local pdir
18481         local dir
18482
18483         mdtidx=$($LFS getstripe --mdt-index $file)
18484         mdtidx=$(printf "%04x" $mdtidx)
18485
18486         # Obtain the parent FID from the MTIME changelog
18487         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18488         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18489
18490         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18491         [ -z "$cl_fid" ] && error "parent FID not present"
18492
18493         # Verify that the path for the parent FID is the same as the path for
18494         # the test directory
18495         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18496
18497         dir=$(dirname $1)
18498
18499         [[ "${pdir%/}" == "$dir" ]] ||
18500                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18501 }
18502
18503 test_160l() {
18504         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18505
18506         remote_mds_nodsh && skip "remote MDS with nodsh"
18507         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18508                 skip "Need MDS version at least 2.13.55"
18509
18510         local cl_user
18511
18512         changelog_register || error "changelog_register failed"
18513         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18514
18515         changelog_users $SINGLEMDS | grep -q $cl_user ||
18516                 error "User '$cl_user' not found in changelog_users"
18517
18518         # Clear some types so that MTIME changelogs are generated
18519         changelog_chmask "-CREAT"
18520         changelog_chmask "-CLOSE"
18521
18522         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18523
18524         # Test CL_MTIME during setattr
18525         touch $DIR/$tdir/$tfile
18526         compare_mtime_changelog $DIR/$tdir/$tfile
18527
18528         # Test CL_MTIME during close
18529         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18530         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18531 }
18532 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18533
18534 test_160m() {
18535         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18536         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18537                 skip "Need MDS version at least 2.14.51"
18538         local cl_users
18539         local cl_user1
18540         local cl_user2
18541         local pid1
18542
18543         # Create a user
18544         changelog_register || error "first changelog_register failed"
18545         changelog_register || error "second changelog_register failed"
18546
18547         cl_users=(${CL_USERS[mds1]})
18548         cl_user1="${cl_users[0]}"
18549         cl_user2="${cl_users[1]}"
18550         # generate some changelog records to accumulate on MDT0
18551         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18552         createmany -m $DIR/$tdir/$tfile 50 ||
18553                 error "create $DIR/$tdir/$tfile failed"
18554         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18555         rm -f $DIR/$tdir
18556
18557         # check changelogs have been generated
18558         local nbcl=$(changelog_dump | wc -l)
18559         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18560
18561 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18562         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18563
18564         __changelog_clear mds1 $cl_user1 +10
18565         __changelog_clear mds1 $cl_user2 0 &
18566         pid1=$!
18567         sleep 2
18568         __changelog_clear mds1 $cl_user1 0 ||
18569                 error "fail to cancel record for $cl_user1"
18570         wait $pid1
18571         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18572 }
18573 run_test 160m "Changelog clear race"
18574
18575 test_160n() {
18576         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18577         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18578                 skip "Need MDS version at least 2.14.51"
18579         local cl_users
18580         local cl_user1
18581         local cl_user2
18582         local pid1
18583         local first_rec
18584         local last_rec=0
18585
18586         # Create a user
18587         changelog_register || error "first changelog_register failed"
18588
18589         cl_users=(${CL_USERS[mds1]})
18590         cl_user1="${cl_users[0]}"
18591
18592         # generate some changelog records to accumulate on MDT0
18593         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18594         first_rec=$(changelog_users $SINGLEMDS |
18595                         awk '/^current.index:/ { print $NF }')
18596         while (( last_rec < (( first_rec + 65000)) )); do
18597                 createmany -m $DIR/$tdir/$tfile 10000 ||
18598                         error "create $DIR/$tdir/$tfile failed"
18599
18600                 for i in $(seq 0 10000); do
18601                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18602                                 > /dev/null
18603                 done
18604
18605                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18606                         error "unlinkmany failed unlink"
18607                 last_rec=$(changelog_users $SINGLEMDS |
18608                         awk '/^current.index:/ { print $NF }')
18609                 echo last record $last_rec
18610                 (( last_rec == 0 )) && error "no changelog found"
18611         done
18612
18613 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18614         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18615
18616         __changelog_clear mds1 $cl_user1 0 &
18617         pid1=$!
18618         sleep 2
18619         __changelog_clear mds1 $cl_user1 0 ||
18620                 error "fail to cancel record for $cl_user1"
18621         wait $pid1
18622         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18623 }
18624 run_test 160n "Changelog destroy race"
18625
18626 test_160o() {
18627         local mdt="$(facet_svc $SINGLEMDS)"
18628
18629         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18630         remote_mds_nodsh && skip "remote MDS with nodsh"
18631         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18632                 skip "Need MDS version at least 2.14.52"
18633
18634         changelog_register --user test_160o -m unlnk+close+open ||
18635                 error "changelog_register failed"
18636
18637         do_facet $SINGLEMDS $LCTL --device $mdt \
18638                                 changelog_register -u "Tt3_-#" &&
18639                 error "bad symbols in name should fail"
18640
18641         do_facet $SINGLEMDS $LCTL --device $mdt \
18642                                 changelog_register -u test_160o &&
18643                 error "the same name registration should fail"
18644
18645         do_facet $SINGLEMDS $LCTL --device $mdt \
18646                         changelog_register -u test_160toolongname &&
18647                 error "too long name registration should fail"
18648
18649         changelog_chmask "MARK+HSM"
18650         lctl get_param mdd.*.changelog*mask
18651         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18652         changelog_users $SINGLEMDS | grep -q $cl_user ||
18653                 error "User $cl_user not found in changelog_users"
18654         #verify username
18655         echo $cl_user | grep -q test_160o ||
18656                 error "User $cl_user has no specific name 'test160o'"
18657
18658         # change something
18659         changelog_clear 0 || error "changelog_clear failed"
18660         # generate some changelog records to accumulate on MDT0
18661         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18662         touch $DIR/$tdir/$tfile                 # open 1
18663
18664         OPENS=$(changelog_dump | grep -c "OPEN")
18665         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18666
18667         # must be no MKDIR it wasn't set as user mask
18668         MKDIR=$(changelog_dump | grep -c "MKDIR")
18669         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18670
18671         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18672                                 mdd.$mdt.changelog_current_mask -n)
18673         # register maskless user
18674         changelog_register || error "changelog_register failed"
18675         # effective mask should be not changed because it is not minimal
18676         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18677                                 mdd.$mdt.changelog_current_mask -n)
18678         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18679         # set server mask to minimal value
18680         changelog_chmask "MARK"
18681         # check effective mask again, should be treated as DEFMASK now
18682         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18683                                 mdd.$mdt.changelog_current_mask -n)
18684         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18685
18686         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18687                 # set server mask back to some value
18688                 changelog_chmask "CLOSE,UNLNK"
18689                 # check effective mask again, should not remain as DEFMASK
18690                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18691                                 mdd.$mdt.changelog_current_mask -n)
18692                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18693         fi
18694
18695         do_facet $SINGLEMDS $LCTL --device $mdt \
18696                                 changelog_deregister -u test_160o ||
18697                 error "cannot deregister by name"
18698 }
18699 run_test 160o "changelog user name and mask"
18700
18701 test_160p() {
18702         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18703         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18704                 skip "Need MDS version at least 2.14.51"
18705         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18706         local cl_users
18707         local cl_user1
18708         local entry_count
18709
18710         # Create a user
18711         changelog_register || error "first changelog_register failed"
18712
18713         cl_users=(${CL_USERS[mds1]})
18714         cl_user1="${cl_users[0]}"
18715
18716         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18717         createmany -m $DIR/$tdir/$tfile 50 ||
18718                 error "create $DIR/$tdir/$tfile failed"
18719         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18720         rm -rf $DIR/$tdir
18721
18722         # check changelogs have been generated
18723         entry_count=$(changelog_dump | wc -l)
18724         ((entry_count != 0)) || error "no changelog entries found"
18725
18726         # remove changelog_users and check that orphan entries are removed
18727         stop mds1
18728         local dev=$(mdsdevname 1)
18729         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18730         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18731         entry_count=$(changelog_dump | wc -l)
18732         ((entry_count == 0)) ||
18733                 error "found $entry_count changelog entries, expected none"
18734 }
18735 run_test 160p "Changelog orphan cleanup with no users"
18736
18737 test_160q() {
18738         local mdt="$(facet_svc $SINGLEMDS)"
18739         local clu
18740
18741         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18742         remote_mds_nodsh && skip "remote MDS with nodsh"
18743         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18744                 skip "Need MDS version at least 2.14.54"
18745
18746         # set server mask to minimal value like server init does
18747         changelog_chmask "MARK"
18748         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18749                 error "changelog_register failed"
18750         # check effective mask again, should be treated as DEFMASK now
18751         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18752                                 mdd.$mdt.changelog_current_mask -n)
18753         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18754                 error "changelog_deregister failed"
18755         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18756 }
18757 run_test 160q "changelog effective mask is DEFMASK if not set"
18758
18759 test_160s() {
18760         remote_mds_nodsh && skip "remote MDS with nodsh"
18761         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18762                 skip "Need MDS version at least 2.14.55"
18763
18764         local mdts=$(comma_list $(mdts_nodes))
18765
18766         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18767         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18768                                        fail_val=$((24 * 3600 * 10))
18769
18770         # Create a user which is 10 days old
18771         changelog_register || error "first changelog_register failed"
18772         local cl_users
18773         declare -A cl_user1
18774         local i
18775
18776         # generate some changelog records to accumulate on each MDT
18777         # use all_char because created files should be evenly distributed
18778         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18779                 error "test_mkdir $tdir failed"
18780         for ((i = 0; i < MDSCOUNT; i++)); do
18781                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18782                         error "create $DIR/$tdir/d$i.1 failed"
18783         done
18784
18785         # check changelogs have been generated
18786         local nbcl=$(changelog_dump | wc -l)
18787         (( nbcl > 0 )) || error "no changelogs found"
18788
18789         # reduce the max_idle_indexes value to make sure we exceed it
18790         for param in "changelog_max_idle_indexes=2097446912" \
18791                      "changelog_max_idle_time=2592000" \
18792                      "changelog_gc=1" \
18793                      "changelog_min_gc_interval=2"; do
18794                 local MDT0=$(facet_svc $SINGLEMDS)
18795                 local var="${param%=*}"
18796                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18797
18798                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18799                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18800                         error "unable to set mdd.*.$param"
18801         done
18802
18803         local start=$SECONDS
18804         for i in $(seq $MDSCOUNT); do
18805                 cl_users=(${CL_USERS[mds$i]})
18806                 cl_user1[mds$i]="${cl_users[0]}"
18807
18808                 [[ -n "${cl_user1[mds$i]}" ]] ||
18809                         error "mds$i: no user registered"
18810         done
18811
18812         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18813         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18814
18815         # ensure we are past the previous changelog_min_gc_interval set above
18816         local sleep2=$((start + 2 - SECONDS))
18817         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18818
18819         # Generate one more changelog to trigger GC
18820         for ((i = 0; i < MDSCOUNT; i++)); do
18821                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18822                         error "create $DIR/$tdir/d$i.3 failed"
18823         done
18824
18825         # ensure gc thread is done
18826         for node in $(mdts_nodes); do
18827                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18828                         error "$node: GC-thread not done"
18829         done
18830
18831         do_nodes $mdts $LCTL set_param fail_loc=0
18832
18833         for (( i = 1; i <= MDSCOUNT; i++ )); do
18834                 # check cl_user1 is purged
18835                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18836                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18837         done
18838         return 0
18839 }
18840 run_test 160s "changelog garbage collect on idle records * time"
18841
18842 test_160t() {
18843         remote_mds_nodsh && skip "remote MDS with nodsh"
18844         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18845                 skip "Need MDS version at least 2.15.50"
18846
18847         local MDT0=$(facet_svc $SINGLEMDS)
18848         local cl_users
18849         local cl_user1
18850         local cl_user2
18851         local start
18852
18853         changelog_register --user user1 -m all ||
18854                 error "user1 failed to register"
18855
18856         mkdir_on_mdt0 $DIR/$tdir
18857         # create default overstripe to maximize changelog size
18858         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18859         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18860         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18861
18862         # user2 consumes less records so less space
18863         changelog_register --user user2 || error "user2 failed to register"
18864         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18865         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18866
18867         # check changelogs have been generated
18868         local nbcl=$(changelog_dump | wc -l)
18869         (( nbcl > 0 )) || error "no changelogs found"
18870
18871         # reduce the changelog_min_gc_interval to force check
18872         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18873                 local var="${param%=*}"
18874                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18875
18876                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18877                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18878                         error "unable to set mdd.*.$param"
18879         done
18880
18881         start=$SECONDS
18882         cl_users=(${CL_USERS[mds1]})
18883         cl_user1="${cl_users[0]}"
18884         cl_user2="${cl_users[1]}"
18885
18886         [[ -n $cl_user1 ]] ||
18887                 error "mds1: user #1 isn't registered"
18888         [[ -n $cl_user2 ]] ||
18889                 error "mds1: user #2 isn't registered"
18890
18891         # ensure we are past the previous changelog_min_gc_interval set above
18892         local sleep2=$((start + 2 - SECONDS))
18893         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18894
18895         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18896         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18897                         fail_val=$(((llog_size1 + llog_size2) / 2))
18898
18899         # Generate more changelog to trigger GC
18900         createmany -o $DIR/$tdir/u3_ 4 ||
18901                 error "create failed for more files"
18902
18903         # ensure gc thread is done
18904         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18905                 error "mds1: GC-thread not done"
18906
18907         do_facet mds1 $LCTL set_param fail_loc=0
18908
18909         # check cl_user1 is purged
18910         changelog_users mds1 | grep -q "$cl_user1" &&
18911                 error "User $cl_user1 is registered"
18912         # check cl_user2 is not purged
18913         changelog_users mds1 | grep -q "$cl_user2" ||
18914                 error "User $cl_user2 is not registered"
18915 }
18916 run_test 160t "changelog garbage collect on lack of space"
18917
18918 test_160u() { # LU-17400
18919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18920         remote_mds_nodsh && skip "remote MDS with nodsh"
18921         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18922                 skip "Need MDS version at least 2.2.0"
18923
18924         cd $DIR || error "cd $DIR failed"
18925
18926         # ensure changelog has a clean view if tests are run multiple times
18927         [ -d rename ] && rm -rf rename
18928
18929         changelog_register || error "changelog_register failed"
18930         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18931
18932         changelog_users $SINGLEMDS | grep -q $cl_user ||
18933                 error "User '$cl_user' not found in changelog_users"
18934
18935         local longname1=$(str_repeat a 255)
18936
18937         echo "creating simple directory tree"
18938         mkdir -p rename/a || error "create of simple directory tree failed"
18939         echo "creating rename/hw file"
18940         echo "hello world" > rename/hw || error "create of rename/hw failed"
18941         echo "creating very long named file"
18942         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18943         echo "move rename/hw to rename/a/a.hw"
18944         mv rename/hw rename/a/a.hw || error "mv failed"
18945
18946         RENME=($(changelog_dump | grep "RENME"))
18947         #declare -p RENME # for debugging captured value with indexes
18948
18949         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18950                 error "changelog rename record type name/sname error"
18951 }
18952 run_test 160u "changelog rename record type name and sname strings are correct"
18953
18954 test_161a() {
18955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18956
18957         test_mkdir -c1 $DIR/$tdir
18958         cp /etc/hosts $DIR/$tdir/$tfile
18959         test_mkdir -c1 $DIR/$tdir/foo1
18960         test_mkdir -c1 $DIR/$tdir/foo2
18961         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18962         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18963         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18964         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18965         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18966         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18967                 $LFS fid2path $DIR $FID
18968                 error "bad link ea"
18969         fi
18970         # middle
18971         rm $DIR/$tdir/foo2/zachary
18972         # last
18973         rm $DIR/$tdir/foo2/thor
18974         # first
18975         rm $DIR/$tdir/$tfile
18976         # rename
18977         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18978         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18979                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18980         rm $DIR/$tdir/foo2/maggie
18981
18982         # overflow the EA
18983         local longname=$tfile.avg_len_is_thirty_two_
18984         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18985                 error_noexit 'failed to unlink many hardlinks'" EXIT
18986         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18987                 error "failed to hardlink many files"
18988         links=$($LFS fid2path $DIR $FID | wc -l)
18989         echo -n "${links}/1000 links in link EA"
18990         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18991 }
18992 run_test 161a "link ea sanity"
18993
18994 test_161b() {
18995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18996         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18997
18998         local MDTIDX=1
18999         local remote_dir=$DIR/$tdir/remote_dir
19000
19001         mkdir -p $DIR/$tdir
19002         $LFS mkdir -i $MDTIDX $remote_dir ||
19003                 error "create remote directory failed"
19004
19005         cp /etc/hosts $remote_dir/$tfile
19006         mkdir -p $remote_dir/foo1
19007         mkdir -p $remote_dir/foo2
19008         ln $remote_dir/$tfile $remote_dir/foo1/sofia
19009         ln $remote_dir/$tfile $remote_dir/foo2/zachary
19010         ln $remote_dir/$tfile $remote_dir/foo1/luna
19011         ln $remote_dir/$tfile $remote_dir/foo2/thor
19012
19013         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
19014                      tr -d ']')
19015         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
19016                 $LFS fid2path $DIR $FID
19017                 error "bad link ea"
19018         fi
19019         # middle
19020         rm $remote_dir/foo2/zachary
19021         # last
19022         rm $remote_dir/foo2/thor
19023         # first
19024         rm $remote_dir/$tfile
19025         # rename
19026         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
19027         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
19028         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
19029                 $LFS fid2path $DIR $FID
19030                 error "bad link rename"
19031         fi
19032         rm $remote_dir/foo2/maggie
19033
19034         # overflow the EA
19035         local longname=filename_avg_len_is_thirty_two_
19036         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
19037                 error "failed to hardlink many files"
19038         links=$($LFS fid2path $DIR $FID | wc -l)
19039         echo -n "${links}/1000 links in link EA"
19040         [[ ${links} -gt 60 ]] ||
19041                 error "expected at least 60 links in link EA"
19042         unlinkmany $remote_dir/foo2/$longname 1000 ||
19043         error "failed to unlink many hardlinks"
19044 }
19045 run_test 161b "link ea sanity under remote directory"
19046
19047 test_161c() {
19048         remote_mds_nodsh && skip "remote MDS with nodsh"
19049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19050         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
19051                 skip "Need MDS version at least 2.1.5"
19052
19053         # define CLF_RENAME_LAST 0x0001
19054         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
19055         changelog_register || error "changelog_register failed"
19056
19057         rm -rf $DIR/$tdir
19058         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19059         touch $DIR/$tdir/foo_161c
19060         touch $DIR/$tdir/bar_161c
19061         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19062         changelog_dump | grep RENME | tail -n 5
19063         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19064         changelog_clear 0 || error "changelog_clear failed"
19065         if [ x$flags != "x0x1" ]; then
19066                 error "flag $flags is not 0x1"
19067         fi
19068
19069         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19070         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19071         touch $DIR/$tdir/foo_161c
19072         touch $DIR/$tdir/bar_161c
19073         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19074         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19075         changelog_dump | grep RENME | tail -n 5
19076         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19077         changelog_clear 0 || error "changelog_clear failed"
19078         if [ x$flags != "x0x0" ]; then
19079                 error "flag $flags is not 0x0"
19080         fi
19081         echo "rename overwrite a target having nlink > 1," \
19082                 "changelog record has flags of $flags"
19083
19084         # rename doesn't overwrite a target (changelog flag 0x0)
19085         touch $DIR/$tdir/foo_161c
19086         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19087         changelog_dump | grep RENME | tail -n 5
19088         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19089         changelog_clear 0 || error "changelog_clear failed"
19090         if [ x$flags != "x0x0" ]; then
19091                 error "flag $flags is not 0x0"
19092         fi
19093         echo "rename doesn't overwrite a target," \
19094                 "changelog record has flags of $flags"
19095
19096         # define CLF_UNLINK_LAST 0x0001
19097         # unlink a file having nlink = 1 (changelog flag 0x1)
19098         rm -f $DIR/$tdir/foo2_161c
19099         changelog_dump | grep UNLNK | tail -n 5
19100         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19101         changelog_clear 0 || error "changelog_clear failed"
19102         if [ x$flags != "x0x1" ]; then
19103                 error "flag $flags is not 0x1"
19104         fi
19105         echo "unlink a file having nlink = 1," \
19106                 "changelog record has flags of $flags"
19107
19108         # unlink a file having nlink > 1 (changelog flag 0x0)
19109         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19110         rm -f $DIR/$tdir/foobar_161c
19111         changelog_dump | grep UNLNK | tail -n 5
19112         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19113         changelog_clear 0 || error "changelog_clear failed"
19114         if [ x$flags != "x0x0" ]; then
19115                 error "flag $flags is not 0x0"
19116         fi
19117         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19118 }
19119 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19120
19121 test_161d() {
19122         remote_mds_nodsh && skip "remote MDS with nodsh"
19123         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19124
19125         local pid
19126         local fid
19127
19128         changelog_register || error "changelog_register failed"
19129
19130         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19131         # interfer with $MOUNT/.lustre/fid/ access
19132         mkdir $DIR/$tdir
19133         [[ $? -eq 0 ]] || error "mkdir failed"
19134
19135         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19136         $LCTL set_param fail_loc=0x8000140c
19137         # 5s pause
19138         $LCTL set_param fail_val=5
19139
19140         # create file
19141         echo foofoo > $DIR/$tdir/$tfile &
19142         pid=$!
19143
19144         # wait for create to be delayed
19145         sleep 2
19146
19147         ps -p $pid
19148         [[ $? -eq 0 ]] || error "create should be blocked"
19149
19150         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19151         stack_trap "rm -f $tempfile"
19152         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19153         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19154         # some delay may occur during ChangeLog publishing and file read just
19155         # above, that could allow file write to happen finally
19156         [[ -s $tempfile ]] && echo "file should be empty"
19157
19158         $LCTL set_param fail_loc=0
19159
19160         wait $pid
19161         [[ $? -eq 0 ]] || error "create failed"
19162 }
19163 run_test 161d "create with concurrent .lustre/fid access"
19164
19165 check_path() {
19166         local expected="$1"
19167         shift
19168         local fid="$2"
19169
19170         local path
19171         path=$($LFS fid2path "$@")
19172         local rc=$?
19173
19174         if [ $rc -ne 0 ]; then
19175                 error "path looked up of '$expected' failed: rc=$rc"
19176         elif [ "$path" != "$expected" ]; then
19177                 error "path looked up '$path' instead of '$expected'"
19178         else
19179                 echo "FID '$fid' resolves to path '$path' as expected"
19180         fi
19181 }
19182
19183 test_162a() { # was test_162
19184         test_mkdir -p -c1 $DIR/$tdir/d2
19185         touch $DIR/$tdir/d2/$tfile
19186         touch $DIR/$tdir/d2/x1
19187         touch $DIR/$tdir/d2/x2
19188         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19189         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19190         # regular file
19191         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19192         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19193
19194         # softlink
19195         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19196         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19197         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19198
19199         # softlink to wrong file
19200         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19201         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19202         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19203
19204         # hardlink
19205         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19206         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19207         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19208         # fid2path dir/fsname should both work
19209         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19210         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19211
19212         # hardlink count: check that there are 2 links
19213         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19214         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19215
19216         # hardlink indexing: remove the first link
19217         rm $DIR/$tdir/d2/p/q/r/hlink
19218         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19219 }
19220 run_test 162a "path lookup sanity"
19221
19222 test_162b() {
19223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19224         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19225
19226         mkdir $DIR/$tdir
19227         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19228                                 error "create striped dir failed"
19229
19230         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19231                                         tail -n 1 | awk '{print $2}')
19232         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19233
19234         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19235         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19236
19237         # regular file
19238         for ((i=0;i<5;i++)); do
19239                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19240                         error "get fid for f$i failed"
19241                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19242
19243                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19244                         error "get fid for d$i failed"
19245                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19246         done
19247
19248         return 0
19249 }
19250 run_test 162b "striped directory path lookup sanity"
19251
19252 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19253 test_162c() {
19254         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19255                 skip "Need MDS version at least 2.7.51"
19256
19257         local lpath=$tdir.local
19258         local rpath=$tdir.remote
19259
19260         test_mkdir $DIR/$lpath
19261         test_mkdir $DIR/$rpath
19262
19263         for ((i = 0; i <= 101; i++)); do
19264                 lpath="$lpath/$i"
19265                 mkdir $DIR/$lpath
19266                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19267                         error "get fid for local directory $DIR/$lpath failed"
19268                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19269
19270                 rpath="$rpath/$i"
19271                 test_mkdir $DIR/$rpath
19272                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19273                         error "get fid for remote directory $DIR/$rpath failed"
19274                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19275         done
19276
19277         return 0
19278 }
19279 run_test 162c "fid2path works with paths 100 or more directories deep"
19280
19281 oalr_event_count() {
19282         local event="${1}"
19283         local trace="${2}"
19284
19285         awk -v name="${FSNAME}-OST0000" \
19286             -v event="${event}" \
19287             '$1 == "TRACE" && $2 == event && $3 == name' \
19288             "${trace}" |
19289         wc -l
19290 }
19291
19292 oalr_expect_event_count() {
19293         local event="${1}"
19294         local trace="${2}"
19295         local expect="${3}"
19296         local count
19297
19298         count=$(oalr_event_count "${event}" "${trace}")
19299         if ((count == expect)); then
19300                 return 0
19301         fi
19302
19303         error_noexit "${event} event count was '${count}', expected ${expect}"
19304         cat "${trace}" >&2
19305         exit 1
19306 }
19307
19308 cleanup_165() {
19309         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19310         stop ost1
19311         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19312 }
19313
19314 setup_165() {
19315         sync # Flush previous IOs so we can count log entries.
19316         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19317         stack_trap cleanup_165 EXIT
19318 }
19319
19320 test_165a() {
19321         local trace="/tmp/${tfile}.trace"
19322         local rc
19323         local count
19324
19325         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19326                 skip "OFD access log unsupported"
19327
19328         setup_165
19329         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19330         sleep 5
19331
19332         do_facet ost1 ofd_access_log_reader --list
19333         stop ost1
19334
19335         do_facet ost1 killall -TERM ofd_access_log_reader
19336         wait
19337         rc=$?
19338
19339         if ((rc != 0)); then
19340                 error "ofd_access_log_reader exited with rc = '${rc}'"
19341         fi
19342
19343         # Parse trace file for discovery events:
19344         oalr_expect_event_count alr_log_add "${trace}" 1
19345         oalr_expect_event_count alr_log_eof "${trace}" 1
19346         oalr_expect_event_count alr_log_free "${trace}" 1
19347 }
19348 run_test 165a "ofd access log discovery"
19349
19350 test_165b() {
19351         local trace="/tmp/${tfile}.trace"
19352         local file="${DIR}/${tfile}"
19353         local pfid1
19354         local pfid2
19355         local -a entry
19356         local rc
19357         local count
19358         local size
19359         local flags
19360
19361         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19362                 skip "OFD access log unsupported"
19363
19364         setup_165
19365         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19366         sleep 5
19367
19368         do_facet ost1 ofd_access_log_reader --list
19369
19370         lfs setstripe -c 1 -i 0 "${file}"
19371         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19372                 error "cannot create '${file}'"
19373
19374         sleep 5
19375         do_facet ost1 killall -TERM ofd_access_log_reader
19376         wait
19377         rc=$?
19378
19379         if ((rc != 0)); then
19380                 error "ofd_access_log_reader exited with rc = '${rc}'"
19381         fi
19382
19383         oalr_expect_event_count alr_log_entry "${trace}" 1
19384
19385         pfid1=$($LFS path2fid "${file}")
19386
19387         # 1     2             3   4    5     6   7    8    9     10
19388         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19389         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19390
19391         echo "entry = '${entry[*]}'" >&2
19392
19393         pfid2=${entry[4]}
19394         if [[ "${pfid1}" != "${pfid2}" ]]; then
19395                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19396         fi
19397
19398         size=${entry[8]}
19399         if ((size != 1048576)); then
19400                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19401         fi
19402
19403         flags=${entry[10]}
19404         if [[ "${flags}" != "w" ]]; then
19405                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19406         fi
19407
19408         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19409         sleep 5
19410
19411         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19412                 error "cannot read '${file}'"
19413         sleep 5
19414
19415         do_facet ost1 killall -TERM ofd_access_log_reader
19416         wait
19417         rc=$?
19418
19419         if ((rc != 0)); then
19420                 error "ofd_access_log_reader exited with rc = '${rc}'"
19421         fi
19422
19423         oalr_expect_event_count alr_log_entry "${trace}" 1
19424
19425         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19426         echo "entry = '${entry[*]}'" >&2
19427
19428         pfid2=${entry[4]}
19429         if [[ "${pfid1}" != "${pfid2}" ]]; then
19430                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19431         fi
19432
19433         size=${entry[8]}
19434         if ((size != 524288)); then
19435                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19436         fi
19437
19438         flags=${entry[10]}
19439         if [[ "${flags}" != "r" ]]; then
19440                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19441         fi
19442 }
19443 run_test 165b "ofd access log entries are produced and consumed"
19444
19445 test_165c() {
19446         local trace="/tmp/${tfile}.trace"
19447         local file="${DIR}/${tdir}/${tfile}"
19448
19449         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19450                 skip "OFD access log unsupported"
19451
19452         test_mkdir "${DIR}/${tdir}"
19453
19454         setup_165
19455         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19456         sleep 5
19457
19458         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19459
19460         # 4096 / 64 = 64. Create twice as many entries.
19461         for ((i = 0; i < 128; i++)); do
19462                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19463                         error "cannot create file"
19464         done
19465
19466         sync
19467
19468         do_facet ost1 killall -TERM ofd_access_log_reader
19469         wait
19470         rc=$?
19471         if ((rc != 0)); then
19472                 error "ofd_access_log_reader exited with rc = '${rc}'"
19473         fi
19474
19475         unlinkmany  "${file}-%d" 128
19476 }
19477 run_test 165c "full ofd access logs do not block IOs"
19478
19479 oal_get_read_count() {
19480         local stats="$1"
19481
19482         # STATS lustre-OST0001 alr_read_count 1
19483
19484         do_facet ost1 cat "${stats}" |
19485         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19486              END { print count; }'
19487 }
19488
19489 oal_expect_read_count() {
19490         local stats="$1"
19491         local count
19492         local expect="$2"
19493
19494         # Ask ofd_access_log_reader to write stats.
19495         do_facet ost1 killall -USR1 ofd_access_log_reader
19496
19497         # Allow some time for things to happen.
19498         sleep 1
19499
19500         count=$(oal_get_read_count "${stats}")
19501         if ((count == expect)); then
19502                 return 0
19503         fi
19504
19505         error_noexit "bad read count, got ${count}, expected ${expect}"
19506         do_facet ost1 cat "${stats}" >&2
19507         exit 1
19508 }
19509
19510 test_165d() {
19511         local stats="/tmp/${tfile}.stats"
19512         local file="${DIR}/${tdir}/${tfile}"
19513         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19514
19515         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19516                 skip "OFD access log unsupported"
19517
19518         test_mkdir "${DIR}/${tdir}"
19519
19520         setup_165
19521         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19522         sleep 5
19523
19524         lfs setstripe -c 1 -i 0 "${file}"
19525
19526         do_facet ost1 lctl set_param "${param}=rw"
19527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19528                 error "cannot create '${file}'"
19529         oal_expect_read_count "${stats}" 1
19530
19531         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19532                 error "cannot read '${file}'"
19533         oal_expect_read_count "${stats}" 2
19534
19535         do_facet ost1 lctl set_param "${param}=r"
19536         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19537                 error "cannot create '${file}'"
19538         oal_expect_read_count "${stats}" 2
19539
19540         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19541                 error "cannot read '${file}'"
19542         oal_expect_read_count "${stats}" 3
19543
19544         do_facet ost1 lctl set_param "${param}=w"
19545         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19546                 error "cannot create '${file}'"
19547         oal_expect_read_count "${stats}" 4
19548
19549         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19550                 error "cannot read '${file}'"
19551         oal_expect_read_count "${stats}" 4
19552
19553         do_facet ost1 lctl set_param "${param}=0"
19554         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19555                 error "cannot create '${file}'"
19556         oal_expect_read_count "${stats}" 4
19557
19558         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19559                 error "cannot read '${file}'"
19560         oal_expect_read_count "${stats}" 4
19561
19562         do_facet ost1 killall -TERM ofd_access_log_reader
19563         wait
19564         rc=$?
19565         if ((rc != 0)); then
19566                 error "ofd_access_log_reader exited with rc = '${rc}'"
19567         fi
19568 }
19569 run_test 165d "ofd_access_log mask works"
19570
19571 test_165e() {
19572         local stats="/tmp/${tfile}.stats"
19573         local file0="${DIR}/${tdir}-0/${tfile}"
19574         local file1="${DIR}/${tdir}-1/${tfile}"
19575
19576         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19577                 skip "OFD access log unsupported"
19578
19579         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19580
19581         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19582         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19583
19584         lfs setstripe -c 1 -i 0 "${file0}"
19585         lfs setstripe -c 1 -i 0 "${file1}"
19586
19587         setup_165
19588         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19589         sleep 5
19590
19591         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19592                 error "cannot create '${file0}'"
19593         sync
19594         oal_expect_read_count "${stats}" 0
19595
19596         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19597                 error "cannot create '${file1}'"
19598         sync
19599         oal_expect_read_count "${stats}" 1
19600
19601         do_facet ost1 killall -TERM ofd_access_log_reader
19602         wait
19603         rc=$?
19604         if ((rc != 0)); then
19605                 error "ofd_access_log_reader exited with rc = '${rc}'"
19606         fi
19607 }
19608 run_test 165e "ofd_access_log MDT index filter works"
19609
19610 test_165f() {
19611         local trace="/tmp/${tfile}.trace"
19612         local rc
19613         local count
19614
19615         setup_165
19616         do_facet ost1 timeout 60 ofd_access_log_reader \
19617                 --exit-on-close --debug=- --trace=- > "${trace}" &
19618         sleep 5
19619         stop ost1
19620
19621         wait
19622         rc=$?
19623
19624         if ((rc != 0)); then
19625                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19626                 cat "${trace}"
19627                 exit 1
19628         fi
19629 }
19630 run_test 165f "ofd_access_log_reader --exit-on-close works"
19631
19632 test_169() {
19633         # do directio so as not to populate the page cache
19634         log "creating a 10 Mb file"
19635         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19636                 error "multiop failed while creating a file"
19637         log "starting reads"
19638         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19639         log "truncating the file"
19640         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19641                 error "multiop failed while truncating the file"
19642         log "killing dd"
19643         kill %+ || true # reads might have finished
19644         echo "wait until dd is finished"
19645         wait
19646         log "removing the temporary file"
19647         rm -rf $DIR/$tfile || error "tmp file removal failed"
19648 }
19649 run_test 169 "parallel read and truncate should not deadlock"
19650
19651 test_170() {
19652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19653
19654         $LCTL clear     # bug 18514
19655         $LCTL debug_daemon start $TMP/${tfile}_log_good
19656         touch $DIR/$tfile
19657         $LCTL debug_daemon stop
19658         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19659                 error "sed failed to read log_good"
19660
19661         $LCTL debug_daemon start $TMP/${tfile}_log_good
19662         rm -rf $DIR/$tfile
19663         $LCTL debug_daemon stop
19664
19665         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19666                error "lctl df log_bad failed"
19667
19668         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19669         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19670
19671         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19672         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19673
19674         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19675                 error "bad_line good_line1 good_line2 are empty"
19676
19677         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19678         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19679         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19680
19681         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19682         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19683         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19684
19685         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19686                 error "bad_line_new good_line_new are empty"
19687
19688         local expected_good=$((good_line1 + good_line2*2))
19689
19690         rm -f $TMP/${tfile}*
19691         # LU-231, short malformed line may not be counted into bad lines
19692         if [ $bad_line -ne $bad_line_new ] &&
19693                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19694                 error "expected $bad_line bad lines, but got $bad_line_new"
19695                 return 1
19696         fi
19697
19698         if [ $expected_good -ne $good_line_new ]; then
19699                 error "expected $expected_good good lines, but got $good_line_new"
19700                 return 2
19701         fi
19702         true
19703 }
19704 run_test 170 "test lctl df to handle corrupted log ====================="
19705
19706 test_171() { # bug20592
19707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19708
19709         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19710         $LCTL set_param fail_loc=0x50e
19711         $LCTL set_param fail_val=3000
19712         multiop_bg_pause $DIR/$tfile O_s || true
19713         local MULTIPID=$!
19714         kill -USR1 $MULTIPID
19715         # cause log dump
19716         sleep 3
19717         wait $MULTIPID
19718         if dmesg | grep "recursive fault"; then
19719                 error "caught a recursive fault"
19720         fi
19721         $LCTL set_param fail_loc=0
19722         true
19723 }
19724 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19725
19726 test_172() {
19727
19728         #define OBD_FAIL_OBD_CLEANUP  0x60e
19729         $LCTL set_param fail_loc=0x60e
19730         umount $MOUNT || error "umount $MOUNT failed"
19731         stack_trap "mount_client $MOUNT"
19732
19733         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19734                 error "no client OBDs are remained"
19735
19736         $LCTL dl | while read devno state type name foo; do
19737                 case $type in
19738                 lov|osc|lmv|mdc)
19739                         $LCTL --device $name cleanup
19740                         $LCTL --device $name detach
19741                         ;;
19742                 *)
19743                         # skip server devices
19744                         ;;
19745                 esac
19746         done
19747
19748         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19749                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19750                 error "some client OBDs are still remained"
19751         fi
19752
19753 }
19754 run_test 172 "manual device removal with lctl cleanup/detach ======"
19755
19756 # it would be good to share it with obdfilter-survey/iokit-libecho code
19757 setup_obdecho_osc () {
19758         local rc=0
19759         local ost_nid=$1
19760         local obdfilter_name=$2
19761         echo "Creating new osc for $obdfilter_name on $ost_nid"
19762         # make sure we can find loopback nid
19763         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19764
19765         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19766                            ${obdfilter_name}_osc_UUID || rc=2; }
19767         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19768                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19769         return $rc
19770 }
19771
19772 cleanup_obdecho_osc () {
19773         local obdfilter_name=$1
19774         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19775         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19776         return 0
19777 }
19778
19779 obdecho_test() {
19780         local OBD=$1
19781         local node=$2
19782         local pages=${3:-64}
19783         local rc=0
19784         local id
19785
19786         local count=10
19787         local obd_size=$(get_obd_size $node $OBD)
19788         local page_size=$(get_page_size $node)
19789         if [[ -n "$obd_size" ]]; then
19790                 local new_count=$((obd_size / (pages * page_size / 1024)))
19791                 [[ $new_count -ge $count ]] || count=$new_count
19792         fi
19793
19794         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19795         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19796                            rc=2; }
19797         if [ $rc -eq 0 ]; then
19798             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19799             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19800         fi
19801         echo "New object id is $id"
19802         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19803                            rc=4; }
19804         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19805                            "test_brw $count w v $pages $id" || rc=4; }
19806         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19807                            rc=4; }
19808         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19809                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19810         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19811                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19812         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19813         return $rc
19814 }
19815
19816 test_180a() {
19817         skip "obdecho on osc is no longer supported"
19818 }
19819 run_test 180a "test obdecho on osc"
19820
19821 test_180b() {
19822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19823         remote_ost_nodsh && skip "remote OST with nodsh"
19824
19825         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19826                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19827                 error "failed to load module obdecho"
19828
19829         local target=$(do_facet ost1 $LCTL dl |
19830                        awk '/obdfilter/ { print $4; exit; }')
19831
19832         if [ -n "$target" ]; then
19833                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19834         else
19835                 do_facet ost1 $LCTL dl
19836                 error "there is no obdfilter target on ost1"
19837         fi
19838 }
19839 run_test 180b "test obdecho directly on obdfilter"
19840
19841 test_180c() { # LU-2598
19842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19843         remote_ost_nodsh && skip "remote OST with nodsh"
19844         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19845                 skip "Need MDS version at least 2.4.0"
19846
19847         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19848                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19849                 error "failed to load module obdecho"
19850
19851         local target=$(do_facet ost1 $LCTL dl |
19852                        awk '/obdfilter/ { print $4; exit; }')
19853
19854         if [ -n "$target" ]; then
19855                 local pages=16384 # 64MB bulk I/O RPC size
19856
19857                 obdecho_test "$target" ost1 "$pages" ||
19858                         error "obdecho_test with pages=$pages failed with $?"
19859         else
19860                 do_facet ost1 $LCTL dl
19861                 error "there is no obdfilter target on ost1"
19862         fi
19863 }
19864 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19865
19866 test_181() { # bug 22177
19867         test_mkdir $DIR/$tdir
19868         # create enough files to index the directory
19869         createmany -o $DIR/$tdir/foobar 4000
19870         # print attributes for debug purpose
19871         lsattr -d .
19872         # open dir
19873         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19874         MULTIPID=$!
19875         # remove the files & current working dir
19876         unlinkmany $DIR/$tdir/foobar 4000
19877         rmdir $DIR/$tdir
19878         kill -USR1 $MULTIPID
19879         wait $MULTIPID
19880         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19881         return 0
19882 }
19883 run_test 181 "Test open-unlinked dir ========================"
19884
19885 test_182a() {
19886         local fcount=1000
19887         local tcount=10
19888
19889         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19890
19891         $LCTL set_param mdc.*.rpc_stats=clear
19892
19893         for (( i = 0; i < $tcount; i++ )) ; do
19894                 mkdir $DIR/$tdir/$i
19895         done
19896
19897         for (( i = 0; i < $tcount; i++ )) ; do
19898                 createmany -o $DIR/$tdir/$i/f- $fcount &
19899         done
19900         wait
19901
19902         for (( i = 0; i < $tcount; i++ )) ; do
19903                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19904         done
19905         wait
19906
19907         $LCTL get_param mdc.*.rpc_stats
19908
19909         rm -rf $DIR/$tdir
19910 }
19911 run_test 182a "Test parallel modify metadata operations from mdc"
19912
19913 test_182b() {
19914         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19915         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19916         local dcount=1000
19917         local tcount=10
19918         local stime
19919         local etime
19920         local delta
19921
19922         do_facet mds1 $LCTL list_param \
19923                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19924                 skip "MDS lacks parallel RPC handling"
19925
19926         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19927
19928         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19929                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19930
19931         stime=$(date +%s)
19932         createmany -i 0 -d $DIR/$tdir/t- $tcount
19933
19934         for (( i = 0; i < $tcount; i++ )) ; do
19935                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19936         done
19937         wait
19938         etime=$(date +%s)
19939         delta=$((etime - stime))
19940         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19941
19942         stime=$(date +%s)
19943         for (( i = 0; i < $tcount; i++ )) ; do
19944                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19945         done
19946         wait
19947         etime=$(date +%s)
19948         delta=$((etime - stime))
19949         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19950
19951         rm -rf $DIR/$tdir
19952
19953         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19954
19955         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19956
19957         stime=$(date +%s)
19958         createmany -i 0 -d $DIR/$tdir/t- $tcount
19959
19960         for (( i = 0; i < $tcount; i++ )) ; do
19961                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19962         done
19963         wait
19964         etime=$(date +%s)
19965         delta=$((etime - stime))
19966         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19967
19968         stime=$(date +%s)
19969         for (( i = 0; i < $tcount; i++ )) ; do
19970                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19971         done
19972         wait
19973         etime=$(date +%s)
19974         delta=$((etime - stime))
19975         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19976
19977         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19978 }
19979 run_test 182b "Test parallel modify metadata operations from osp"
19980
19981 test_183() { # LU-2275
19982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19983         remote_mds_nodsh && skip "remote MDS with nodsh"
19984         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19985                 skip "Need MDS version at least 2.3.56"
19986
19987         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19988         echo aaa > $DIR/$tdir/$tfile
19989
19990 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19991         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19992
19993         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19994         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19995
19996         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19997
19998         # Flush negative dentry cache
19999         touch $DIR/$tdir/$tfile
20000
20001         # We are not checking for any leaked references here, they'll
20002         # become evident next time we do cleanup with module unload.
20003         rm -rf $DIR/$tdir
20004 }
20005 run_test 183 "No crash or request leak in case of strange dispositions ========"
20006
20007 # test suite 184 is for LU-2016, LU-2017
20008 test_184a() {
20009         check_swap_layouts_support
20010
20011         dir0=$DIR/$tdir/$testnum
20012         test_mkdir -p -c1 $dir0
20013         ref1=/etc/passwd
20014         ref2=/etc/group
20015         file1=$dir0/f1
20016         file2=$dir0/f2
20017         $LFS setstripe -c1 $file1
20018         cp $ref1 $file1
20019         $LFS setstripe -c2 $file2
20020         cp $ref2 $file2
20021         gen1=$($LFS getstripe -g $file1)
20022         gen2=$($LFS getstripe -g $file2)
20023
20024         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
20025         gen=$($LFS getstripe -g $file1)
20026         [[ $gen1 != $gen ]] ||
20027                 error "Layout generation on $file1 does not change"
20028         gen=$($LFS getstripe -g $file2)
20029         [[ $gen2 != $gen ]] ||
20030                 error "Layout generation on $file2 does not change"
20031
20032         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
20033         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
20034
20035         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
20036 }
20037 run_test 184a "Basic layout swap"
20038
20039 test_184b() {
20040         check_swap_layouts_support
20041
20042         dir0=$DIR/$tdir/$testnum
20043         mkdir -p $dir0 || error "creating dir $dir0"
20044         file1=$dir0/f1
20045         file2=$dir0/f2
20046         file3=$dir0/f3
20047         dir1=$dir0/d1
20048         dir2=$dir0/d2
20049         mkdir $dir1 $dir2
20050         $LFS setstripe -c1 $file1
20051         $LFS setstripe -c2 $file2
20052         $LFS setstripe -c1 $file3
20053         chown $RUNAS_ID $file3
20054         gen1=$($LFS getstripe -g $file1)
20055         gen2=$($LFS getstripe -g $file2)
20056
20057         $LFS swap_layouts $dir1 $dir2 &&
20058                 error "swap of directories layouts should fail"
20059         $LFS swap_layouts $dir1 $file1 &&
20060                 error "swap of directory and file layouts should fail"
20061         $RUNAS $LFS swap_layouts $file1 $file2 &&
20062                 error "swap of file we cannot write should fail"
20063         $LFS swap_layouts $file1 $file3 &&
20064                 error "swap of file with different owner should fail"
20065         /bin/true # to clear error code
20066 }
20067 run_test 184b "Forbidden layout swap (will generate errors)"
20068
20069 test_184c() {
20070         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20071         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20072         check_swap_layouts_support
20073         check_swap_layout_no_dom $DIR
20074
20075         local dir0=$DIR/$tdir/$testnum
20076         mkdir -p $dir0 || error "creating dir $dir0"
20077
20078         local ref1=$dir0/ref1
20079         local ref2=$dir0/ref2
20080         local file1=$dir0/file1
20081         local file2=$dir0/file2
20082         # create a file large enough for the concurrent test
20083         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20084         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20085         echo "ref file size: ref1($(stat -c %s $ref1))," \
20086              "ref2($(stat -c %s $ref2))"
20087
20088         cp $ref2 $file2
20089         dd if=$ref1 of=$file1 bs=16k &
20090         local DD_PID=$!
20091
20092         # Make sure dd starts to copy file, but wait at most 5 seconds
20093         local loops=0
20094         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20095
20096         $LFS swap_layouts $file1 $file2
20097         local rc=$?
20098         wait $DD_PID
20099         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20100         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20101
20102         # how many bytes copied before swapping layout
20103         local copied=$(stat -c %s $file2)
20104         local remaining=$(stat -c %s $ref1)
20105         remaining=$((remaining - copied))
20106         echo "Copied $copied bytes before swapping layout..."
20107
20108         cmp -n $copied $file1 $ref2 | grep differ &&
20109                 error "Content mismatch [0, $copied) of ref2 and file1"
20110         cmp -n $copied $file2 $ref1 ||
20111                 error "Content mismatch [0, $copied) of ref1 and file2"
20112         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20113                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20114
20115         # clean up
20116         rm -f $ref1 $ref2 $file1 $file2
20117 }
20118 run_test 184c "Concurrent write and layout swap"
20119
20120 test_184d() {
20121         check_swap_layouts_support
20122         check_swap_layout_no_dom $DIR
20123         [ -z "$(which getfattr 2>/dev/null)" ] &&
20124                 skip_env "no getfattr command"
20125
20126         local file1=$DIR/$tdir/$tfile-1
20127         local file2=$DIR/$tdir/$tfile-2
20128         local file3=$DIR/$tdir/$tfile-3
20129         local lovea1
20130         local lovea2
20131
20132         mkdir -p $DIR/$tdir
20133         touch $file1 || error "create $file1 failed"
20134         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20135                 error "create $file2 failed"
20136         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20137                 error "create $file3 failed"
20138         lovea1=$(get_layout_param $file1)
20139
20140         $LFS swap_layouts $file2 $file3 ||
20141                 error "swap $file2 $file3 layouts failed"
20142         $LFS swap_layouts $file1 $file2 ||
20143                 error "swap $file1 $file2 layouts failed"
20144
20145         lovea2=$(get_layout_param $file2)
20146         echo "$lovea1"
20147         echo "$lovea2"
20148         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20149
20150         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20151         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20152 }
20153 run_test 184d "allow stripeless layouts swap"
20154
20155 test_184e() {
20156         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20157                 skip "Need MDS version at least 2.6.94"
20158         check_swap_layouts_support
20159         check_swap_layout_no_dom $DIR
20160         [ -z "$(which getfattr 2>/dev/null)" ] &&
20161                 skip_env "no getfattr command"
20162
20163         local file1=$DIR/$tdir/$tfile-1
20164         local file2=$DIR/$tdir/$tfile-2
20165         local file3=$DIR/$tdir/$tfile-3
20166         local lovea
20167
20168         mkdir -p $DIR/$tdir
20169         touch $file1 || error "create $file1 failed"
20170         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20171                 error "create $file2 failed"
20172         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20173                 error "create $file3 failed"
20174
20175         $LFS swap_layouts $file1 $file2 ||
20176                 error "swap $file1 $file2 layouts failed"
20177
20178         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20179         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20180
20181         echo 123 > $file1 || error "Should be able to write into $file1"
20182
20183         $LFS swap_layouts $file1 $file3 ||
20184                 error "swap $file1 $file3 layouts failed"
20185
20186         echo 123 > $file1 || error "Should be able to write into $file1"
20187
20188         rm -rf $file1 $file2 $file3
20189 }
20190 run_test 184e "Recreate layout after stripeless layout swaps"
20191
20192 test_184f() {
20193         # Create a file with name longer than sizeof(struct stat) ==
20194         # 144 to see if we can get chars from the file name to appear
20195         # in the returned striping. Note that 'f' == 0x66.
20196         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20197
20198         mkdir -p $DIR/$tdir
20199         mcreate $DIR/$tdir/$file
20200         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20201                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20202         fi
20203 }
20204 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20205
20206 test_185() { # LU-2441
20207         # LU-3553 - no volatile file support in old servers
20208         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20209                 skip "Need MDS version at least 2.3.60"
20210
20211         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20212         touch $DIR/$tdir/spoo
20213         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20214         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20215                 error "cannot create/write a volatile file"
20216         [ "$FILESET" == "" ] &&
20217         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20218                 error "FID is still valid after close"
20219
20220         multiop_bg_pause $DIR/$tdir Vw4096_c
20221         local multi_pid=$!
20222
20223         local OLD_IFS=$IFS
20224         IFS=":"
20225         local fidv=($fid)
20226         IFS=$OLD_IFS
20227         # assume that the next FID for this client is sequential, since stdout
20228         # is unfortunately eaten by multiop_bg_pause
20229         local n=$((${fidv[1]} + 1))
20230         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20231         if [ "$FILESET" == "" ]; then
20232                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20233                         error "FID is missing before close"
20234         fi
20235         kill -USR1 $multi_pid
20236         # 1 second delay, so if mtime change we will see it
20237         sleep 1
20238         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20239         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20240 }
20241 run_test 185 "Volatile file support"
20242
20243 function create_check_volatile() {
20244         local idx=$1
20245         local tgt
20246
20247         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20248         local PID=$!
20249         sleep 1
20250         local FID=$(cat /tmp/${tfile}.fid)
20251         [ "$FID" == "" ] && error "can't get FID for volatile"
20252         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20253         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20254         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20255         kill -USR1 $PID
20256         wait
20257         sleep 1
20258         cancel_lru_locks mdc # flush opencache
20259         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20260         return 0
20261 }
20262
20263 test_185a(){
20264         # LU-12516 - volatile creation via .lustre
20265         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20266                 skip "Need MDS version at least 2.3.55"
20267
20268         create_check_volatile 0
20269         [ $MDSCOUNT -lt 2 ] && return 0
20270
20271         # DNE case
20272         create_check_volatile 1
20273
20274         return 0
20275 }
20276 run_test 185a "Volatile file creation in .lustre/fid/"
20277
20278 test_187a() {
20279         remote_mds_nodsh && skip "remote MDS with nodsh"
20280         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20281                 skip "Need MDS version at least 2.3.0"
20282
20283         local dir0=$DIR/$tdir/$testnum
20284         mkdir -p $dir0 || error "creating dir $dir0"
20285
20286         local file=$dir0/file1
20287         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20288         stack_trap "rm -f $file"
20289         local dv1=$($LFS data_version $file)
20290         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20291         local dv2=$($LFS data_version $file)
20292         [[ $dv1 != $dv2 ]] ||
20293                 error "data version did not change on write $dv1 == $dv2"
20294 }
20295 run_test 187a "Test data version change"
20296
20297 test_187b() {
20298         remote_mds_nodsh && skip "remote MDS with nodsh"
20299         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20300                 skip "Need MDS version at least 2.3.0"
20301
20302         local dir0=$DIR/$tdir/$testnum
20303         mkdir -p $dir0 || error "creating dir $dir0"
20304
20305         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20306         [[ ${DV[0]} != ${DV[1]} ]] ||
20307                 error "data version did not change on write"\
20308                       " ${DV[0]} == ${DV[1]}"
20309
20310         # clean up
20311         rm -f $file1
20312 }
20313 run_test 187b "Test data version change on volatile file"
20314
20315 test_200() {
20316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20317         remote_mgs_nodsh && skip "remote MGS with nodsh"
20318         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20319
20320         local POOL=${POOL:-cea1}
20321         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20322         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20323         # Pool OST targets
20324         local first_ost=0
20325         local last_ost=$(($OSTCOUNT - 1))
20326         local ost_step=2
20327         local ost_list=$(seq $first_ost $ost_step $last_ost)
20328         local ost_range="$first_ost $last_ost $ost_step"
20329         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20330         local file_dir=$POOL_ROOT/file_tst
20331         local subdir=$test_path/subdir
20332         local rc=0
20333
20334         while : ; do
20335                 # former test_200a test_200b
20336                 pool_add $POOL                          || { rc=$? ; break; }
20337                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20338                 # former test_200c test_200d
20339                 mkdir -p $test_path
20340                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20341                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20342                 mkdir -p $subdir
20343                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20344                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20345                                                         || { rc=$? ; break; }
20346                 # former test_200e test_200f
20347                 local files=$((OSTCOUNT*3))
20348                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20349                                                         || { rc=$? ; break; }
20350                 pool_create_files $POOL $file_dir $files "$ost_list" \
20351                                                         || { rc=$? ; break; }
20352                 # former test_200g test_200h
20353                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20354                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20355
20356                 # former test_201a test_201b test_201c
20357                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20358
20359                 local f=$test_path/$tfile
20360                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20361                 pool_remove $POOL $f                    || { rc=$? ; break; }
20362                 break
20363         done
20364
20365         destroy_test_pools
20366
20367         return $rc
20368 }
20369 run_test 200 "OST pools"
20370
20371 # usage: default_attr <count | size | offset>
20372 default_attr() {
20373         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20374 }
20375
20376 # usage: check_default_stripe_attr
20377 check_default_stripe_attr() {
20378         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20379         case $1 in
20380         --stripe-count|-c)
20381                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20382         --stripe-size|-S)
20383                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20384         --stripe-index|-i)
20385                 EXPECTED=-1;;
20386         *)
20387                 error "unknown getstripe attr '$1'"
20388         esac
20389
20390         [ $ACTUAL == $EXPECTED ] ||
20391                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20392 }
20393
20394 test_204a() {
20395         test_mkdir $DIR/$tdir
20396         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20397
20398         check_default_stripe_attr --stripe-count
20399         check_default_stripe_attr --stripe-size
20400         check_default_stripe_attr --stripe-index
20401 }
20402 run_test 204a "Print default stripe attributes"
20403
20404 test_204b() {
20405         test_mkdir $DIR/$tdir
20406         $LFS setstripe --stripe-count 1 $DIR/$tdir
20407
20408         check_default_stripe_attr --stripe-size
20409         check_default_stripe_attr --stripe-index
20410 }
20411 run_test 204b "Print default stripe size and offset"
20412
20413 test_204c() {
20414         test_mkdir $DIR/$tdir
20415         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20416
20417         check_default_stripe_attr --stripe-count
20418         check_default_stripe_attr --stripe-index
20419 }
20420 run_test 204c "Print default stripe count and offset"
20421
20422 test_204d() {
20423         test_mkdir $DIR/$tdir
20424         $LFS setstripe --stripe-index 0 $DIR/$tdir
20425
20426         check_default_stripe_attr --stripe-count
20427         check_default_stripe_attr --stripe-size
20428 }
20429 run_test 204d "Print default stripe count and size"
20430
20431 test_204e() {
20432         test_mkdir $DIR/$tdir
20433         $LFS setstripe -d $DIR/$tdir
20434
20435         # LU-16904 check if root is set as PFL layout
20436         local numcomp=$($LFS getstripe --component-count $MOUNT)
20437
20438         if [[ $numcomp -gt 0 ]]; then
20439                 check_default_stripe_attr --stripe-count
20440         else
20441                 check_default_stripe_attr --stripe-count --raw
20442         fi
20443         check_default_stripe_attr --stripe-size --raw
20444         check_default_stripe_attr --stripe-index --raw
20445 }
20446 run_test 204e "Print raw stripe attributes"
20447
20448 test_204f() {
20449         test_mkdir $DIR/$tdir
20450         $LFS setstripe --stripe-count 1 $DIR/$tdir
20451
20452         check_default_stripe_attr --stripe-size --raw
20453         check_default_stripe_attr --stripe-index --raw
20454 }
20455 run_test 204f "Print raw stripe size and offset"
20456
20457 test_204g() {
20458         test_mkdir $DIR/$tdir
20459         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20460
20461         check_default_stripe_attr --stripe-count --raw
20462         check_default_stripe_attr --stripe-index --raw
20463 }
20464 run_test 204g "Print raw stripe count and offset"
20465
20466 test_204h() {
20467         test_mkdir $DIR/$tdir
20468         $LFS setstripe --stripe-index 0 $DIR/$tdir
20469
20470         check_default_stripe_attr --stripe-count --raw
20471         check_default_stripe_attr --stripe-size --raw
20472 }
20473 run_test 204h "Print raw stripe count and size"
20474
20475 # Figure out which job scheduler is being used, if any,
20476 # or use a fake one
20477 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20478         JOBENV=SLURM_JOB_ID
20479 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20480         JOBENV=LSB_JOBID
20481 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20482         JOBENV=PBS_JOBID
20483 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20484         JOBENV=LOADL_STEP_ID
20485 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20486         JOBENV=JOB_ID
20487 else
20488         $LCTL list_param jobid_name > /dev/null 2>&1
20489         if [ $? -eq 0 ]; then
20490                 JOBENV=nodelocal
20491         else
20492                 JOBENV=FAKE_JOBID
20493         fi
20494 fi
20495 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20496
20497 verify_jobstats() {
20498         local cmd=($1)
20499         shift
20500         local facets="$@"
20501
20502 # we don't really need to clear the stats for this test to work, since each
20503 # command has a unique jobid, but it makes debugging easier if needed.
20504 #       for facet in $facets; do
20505 #               local dev=$(convert_facet2label $facet)
20506 #               # clear old jobstats
20507 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20508 #       done
20509
20510         # use a new JobID for each test, or we might see an old one
20511         [ "$JOBENV" = "FAKE_JOBID" ] &&
20512                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20513
20514         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20515
20516         [ "$JOBENV" = "nodelocal" ] && {
20517                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20518                 $LCTL set_param jobid_name=$FAKE_JOBID
20519                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20520         }
20521
20522         log "Test: ${cmd[*]}"
20523         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20524
20525         if [ $JOBENV = "FAKE_JOBID" ]; then
20526                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20527         else
20528                 ${cmd[*]}
20529         fi
20530
20531         # all files are created on OST0000
20532         for facet in $facets; do
20533                 local stats="*.$(convert_facet2label $facet).job_stats"
20534
20535                 # strip out libtool wrappers for in-tree executables
20536                 if (( $(do_facet $facet lctl get_param $stats |
20537                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20538                         do_facet $facet lctl get_param $stats
20539                         error "No jobstats for $JOBVAL found on $facet::$stats"
20540                 fi
20541         done
20542 }
20543
20544 jobstats_set() {
20545         local new_jobenv=$1
20546
20547         set_persistent_param_and_check client "jobid_var" \
20548                 "$FSNAME.sys.jobid_var" $new_jobenv
20549 }
20550
20551 test_205a() { # Job stats
20552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20553         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20554                 skip "Need MDS version with at least 2.7.1"
20555         remote_mgs_nodsh && skip "remote MGS with nodsh"
20556         remote_mds_nodsh && skip "remote MDS with nodsh"
20557         remote_ost_nodsh && skip "remote OST with nodsh"
20558         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20559                 skip "Server doesn't support jobstats"
20560         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20561
20562         local old_jobenv=$($LCTL get_param -n jobid_var)
20563         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20564         stack_trap "jobstats_set $old_jobenv" EXIT
20565
20566         changelog_register
20567
20568         local old_jobid_name=$($LCTL get_param jobid_name)
20569         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20570
20571         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20572                                 mdt.*.job_cleanup_interval | head -n 1)
20573         local new_interval=5
20574         do_facet $SINGLEMDS \
20575                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20576         stack_trap "do_facet $SINGLEMDS \
20577                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20578         local start=$SECONDS
20579
20580         local cmd
20581         # mkdir
20582         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20583         verify_jobstats "$cmd" "$SINGLEMDS"
20584         # rmdir
20585         cmd="rmdir $DIR/$tdir"
20586         verify_jobstats "$cmd" "$SINGLEMDS"
20587         # mkdir on secondary MDT
20588         if [ $MDSCOUNT -gt 1 ]; then
20589                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20590                 verify_jobstats "$cmd" "mds2"
20591         fi
20592         # mknod
20593         cmd="mknod $DIR/$tfile c 1 3"
20594         verify_jobstats "$cmd" "$SINGLEMDS"
20595         # unlink
20596         cmd="rm -f $DIR/$tfile"
20597         verify_jobstats "$cmd" "$SINGLEMDS"
20598         # create all files on OST0000 so verify_jobstats can find OST stats
20599         # open & close
20600         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20601         verify_jobstats "$cmd" "$SINGLEMDS"
20602         # setattr
20603         cmd="touch $DIR/$tfile"
20604         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20605         # write
20606         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20607         verify_jobstats "$cmd" "ost1"
20608         # read
20609         cancel_lru_locks osc
20610         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20611         verify_jobstats "$cmd" "ost1"
20612         # truncate
20613         cmd="$TRUNCATE $DIR/$tfile 0"
20614         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20615         # rename
20616         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20617         verify_jobstats "$cmd" "$SINGLEMDS"
20618         # jobstats expiry - sleep until old stats should be expired
20619         local left=$((new_interval + 5 - (SECONDS - start)))
20620         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20621                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20622                         "0" $left
20623         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20624         verify_jobstats "$cmd" "$SINGLEMDS"
20625         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20626             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20627
20628         # Ensure that jobid are present in changelog (if supported by MDS)
20629         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20630                 changelog_dump | tail -10
20631                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20632                 [ $jobids -eq 9 ] ||
20633                         error "Wrong changelog jobid count $jobids != 9"
20634
20635                 # LU-5862
20636                 JOBENV="disable"
20637                 jobstats_set $JOBENV
20638                 touch $DIR/$tfile
20639                 changelog_dump | grep $tfile
20640                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20641                 [ $jobids -eq 0 ] ||
20642                         error "Unexpected jobids when jobid_var=$JOBENV"
20643         fi
20644
20645         # test '%j' access to environment variable - if supported
20646         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20647                 JOBENV="JOBCOMPLEX"
20648                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20649
20650                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20651         fi
20652
20653         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20654                 JOBENV="JOBCOMPLEX"
20655                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20656
20657                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20658         fi
20659
20660         # test '%j' access to per-session jobid - if supported
20661         if lctl list_param jobid_this_session > /dev/null 2>&1
20662         then
20663                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20664                 lctl set_param jobid_this_session=$USER
20665
20666                 JOBENV="JOBCOMPLEX"
20667                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20668
20669                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20670         fi
20671 }
20672 run_test 205a "Verify job stats"
20673
20674 # LU-13117, LU-13597, LU-16599
20675 test_205b() {
20676         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20677                 skip "Need MDS version at least 2.13.54.91"
20678
20679         local job_stats="mdt.*.job_stats"
20680         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20681
20682         do_facet mds1 $LCTL set_param $job_stats=clear
20683
20684         # Setting jobid_var to USER might not be supported
20685         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20686         $LCTL set_param jobid_var=USER || true
20687         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20688         $LCTL set_param jobid_name="%j.%e.%u"
20689
20690         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20691         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20692                 { do_facet mds1 $LCTL get_param $job_stats;
20693                   error "Unexpected jobid found"; }
20694         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20695                 { do_facet mds1 $LCTL get_param $job_stats;
20696                   error "wrong job_stats format found"; }
20697
20698         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20699                 echo "MDS does not yet escape jobid" && return 0
20700
20701         mkdir_on_mdt0 $DIR/$tdir
20702         $LCTL set_param jobid_var=TEST205b
20703         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20704         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20705                       awk '/has\\x20sp/ {print $3}')
20706         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20707                   error "jobid not escaped"; }
20708
20709         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20710                 # need to run such a command on mds1:
20711                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20712                 #
20713                 # there might be multiple MDTs on single mds server, so need to
20714                 # specifiy MDT0000. Or the command will fail due to other MDTs
20715                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20716                         error "cannot clear escaped jobid in job_stats";
20717         else
20718                 echo "MDS does not support clearing escaped jobid"
20719         fi
20720 }
20721 run_test 205b "Verify job stats jobid and output format"
20722
20723 # LU-13733
20724 test_205c() {
20725         $LCTL set_param llite.*.stats=0
20726         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20727         $LCTL get_param llite.*.stats
20728         $LCTL get_param llite.*.stats | grep \
20729                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20730                         error "wrong client stats format found"
20731 }
20732 run_test 205c "Verify client stats format"
20733
20734 test_205d() {
20735         local file=$DIR/$tdir/$tfile
20736
20737         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20738                 skip "need lustre >= 2.15.53 for lljobstat"
20739         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20740                 skip "need lustre >= 2.15.53 for lljobstat"
20741         verify_yaml_available || skip_env "YAML verification not installed"
20742
20743         test_mkdir -i 0 $DIR/$tdir
20744         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20745         stack_trap "rm -rf $DIR/$tdir"
20746
20747         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20748                 error "failed to write data to $file"
20749         mv $file $file.2
20750
20751         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20752         echo -n 'verify rename_stats...'
20753         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20754                 verify_yaml || error "rename_stats is not valid YAML"
20755         echo " OK"
20756
20757         echo -n 'verify mdt job_stats...'
20758         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20759                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20760         echo " OK"
20761
20762         echo -n 'verify ost job_stats...'
20763         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20764                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20765         echo " OK"
20766 }
20767 run_test 205d "verify the format of some stats files"
20768
20769 test_205e() {
20770         local ops_comma
20771         local file=$DIR/$tdir/$tfile
20772         local -a cli_params
20773
20774         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20775                 skip "need lustre >= 2.15.53 for lljobstat"
20776         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20777                 skip "need lustre >= 2.15.53 for lljobstat"
20778         verify_yaml_available || skip_env "YAML verification not installed"
20779
20780         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20781         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20782         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20783
20784         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20785         stack_trap "rm -rf $DIR/$tdir"
20786
20787         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20788                 error "failed to create $file on ost1"
20789         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20790                 error "failed to write data to $file"
20791
20792         do_facet mds1 "$LCTL get_param *.*.job_stats"
20793         do_facet ost1 "$LCTL get_param *.*.job_stats"
20794
20795         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20796         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20797                 error "The output of lljobstat is not an valid YAML"
20798
20799         # verify that job dd.0 does exist and has some ops on ost1
20800         # typically this line is like:
20801         # - 205e.dd.0:            {ops: 20, ...}
20802         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20803                     awk '$2=="205e.dd.0:" {print $4}')
20804
20805         (( ${ops_comma%,} >= 10 )) ||
20806                 error "cannot find job 205e.dd.0 with ops >= 10"
20807 }
20808 run_test 205e "verify the output of lljobstat"
20809
20810 test_205f() {
20811         verify_yaml_available || skip_env "YAML verification not installed"
20812
20813         # check both qos_ost_weights and qos_mdt_weights
20814         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20815         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20816                 error "qos_ost_weights is not valid YAML"
20817 }
20818 run_test 205f "verify qos_ost_weights YAML format "
20819
20820 __test_205_jobstats_dump() {
20821         local -a pids
20822         local nbr_instance=$1
20823
20824         while true; do
20825                 if (( ${#pids[@]} >= nbr_instance )); then
20826                         wait ${pids[@]}
20827                         pids=()
20828                 fi
20829
20830                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20831                 pids+=( $! )
20832         done
20833 }
20834
20835 __test_205_cleanup() {
20836         kill $@
20837         # Clear all job entries
20838         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20839 }
20840
20841 test_205g() {
20842         local -a mds1_params
20843         local -a cli_params
20844         local pids
20845         local interval=5
20846
20847         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20848         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20849         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20850
20851         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20852         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20853         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20854
20855         # start jobs loop
20856         export TEST205G_ID=205g
20857         stack_trap "unset TEST205G_ID" EXIT
20858         while true; do
20859                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20860         done & pids="$! "
20861
20862         __test_205_jobstats_dump 4 & pids+="$! "
20863         stack_trap "__test_205_cleanup $pids" EXIT INT
20864
20865         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20866 }
20867 run_test 205g "stress test for job_stats procfile"
20868
20869 test_205h() {
20870         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20871                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20872         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20873
20874         local dir=$DIR/$tdir
20875         local f=$dir/$tfile
20876         local f2=$dir/$tfile-2
20877         local f3=$dir/$tfile-3
20878         local subdir=$DIR/dir
20879         local val
20880
20881         local mdts=$(comma_list $(mdts_nodes))
20882         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20883         local client_saved=$($LCTL get_param -n jobid_var)
20884
20885         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20886         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20887
20888         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20889                 error "failed to set job_xattr parameter to user.job"
20890         $LCTL set_param jobid_var=procname.uid ||
20891                 error "failed to set jobid_var parameter"
20892
20893         test_mkdir $dir
20894
20895         touch $f
20896         val=$(getfattr -n user.job $f | grep user.job)
20897         [[ $val = user.job=\"touch.0\" ]] ||
20898                 error "expected user.job=\"touch.0\", got '$val'"
20899
20900         mkdir $subdir
20901         val=$(getfattr -n user.job $subdir | grep user.job)
20902         [[ $val = user.job=\"mkdir.0\" ]] ||
20903                 error "expected user.job=\"mkdir.0\", got '$val'"
20904
20905         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20906                 error "failed to set job_xattr parameter to NONE"
20907
20908         touch $f2
20909         val=$(getfattr -d $f2)
20910         [[ -z $val ]] ||
20911                 error "expected no user xattr, got '$val'"
20912
20913         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20914                 error "failed to set job_xattr parameter to trusted.job"
20915
20916         touch $f3
20917         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20918         [[ $val = trusted.job=\"touch.0\" ]] ||
20919                 error "expected trusted.job=\"touch.0\", got '$val'"
20920 }
20921 run_test 205h "check jobid xattr is stored correctly"
20922
20923 test_205i() {
20924         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20925                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20926
20927         local mdts=$(comma_list $(mdts_nodes))
20928         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20929
20930         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20931
20932         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20933                 error "failed to set mdt.*.job_xattr to user.1234567"
20934
20935         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20936                 error "failed to reject too long job_xattr name"
20937
20938         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20939                 error "failed to reject job_xattr name in bad format"
20940
20941         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20942                 error "failed to reject job_xattr name with invalid character"
20943
20944         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20945                         xargs $LCTL set_param" &&
20946                 error "failed to reject job_xattr name with non-ascii character"
20947
20948         return 0
20949 }
20950 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20951
20952 # LU-1480, LU-1773 and LU-1657
20953 test_206() {
20954         mkdir -p $DIR/$tdir
20955         $LFS setstripe -c -1 $DIR/$tdir
20956 #define OBD_FAIL_LOV_INIT 0x1403
20957         $LCTL set_param fail_loc=0xa0001403
20958         $LCTL set_param fail_val=1
20959         touch $DIR/$tdir/$tfile || true
20960 }
20961 run_test 206 "fail lov_init_raid0() doesn't lbug"
20962
20963 test_207a() {
20964         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20965         local fsz=`stat -c %s $DIR/$tfile`
20966         cancel_lru_locks mdc
20967
20968         # do not return layout in getattr intent
20969 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20970         $LCTL set_param fail_loc=0x170
20971         local sz=`stat -c %s $DIR/$tfile`
20972
20973         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20974
20975         rm -rf $DIR/$tfile
20976 }
20977 run_test 207a "can refresh layout at glimpse"
20978
20979 test_207b() {
20980         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20981         local cksum=`md5sum $DIR/$tfile`
20982         local fsz=`stat -c %s $DIR/$tfile`
20983         cancel_lru_locks mdc
20984         cancel_lru_locks osc
20985
20986         # do not return layout in getattr intent
20987 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20988         $LCTL set_param fail_loc=0x171
20989
20990         # it will refresh layout after the file is opened but before read issues
20991         echo checksum is "$cksum"
20992         echo "$cksum" |md5sum -c --quiet || error "file differs"
20993
20994         rm -rf $DIR/$tfile
20995 }
20996 run_test 207b "can refresh layout at open"
20997
20998 test_208() {
20999         # FIXME: in this test suite, only RD lease is used. This is okay
21000         # for now as only exclusive open is supported. After generic lease
21001         # is done, this test suite should be revised. - Jinshan
21002
21003         remote_mds_nodsh && skip "remote MDS with nodsh"
21004         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
21005                 skip "Need MDS version at least 2.4.52"
21006
21007         echo "==== test 1: verify get lease work"
21008         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
21009
21010         echo "==== test 2: verify lease can be broken by upcoming open"
21011         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21012         local PID=$!
21013         sleep 2
21014
21015         $MULTIOP $DIR/$tfile oO_RDWR:c
21016         kill -USR1 $PID && wait $PID || error "break lease error"
21017
21018         echo "==== test 3: verify lease can't be granted if an open already exists"
21019         $MULTIOP $DIR/$tfile oO_RDWR:_c &
21020         local PID=$!
21021         sleep 2
21022
21023         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
21024         kill -USR1 $PID && wait $PID || error "open file error"
21025
21026         echo "==== test 4: lease can sustain over recovery"
21027         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
21028         PID=$!
21029         sleep 2
21030
21031         fail mds1
21032
21033         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
21034
21035         echo "==== test 5: lease broken can't be regained by replay"
21036         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
21037         PID=$!
21038         sleep 2
21039
21040         # open file to break lease and then recovery
21041         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
21042         fail mds1
21043
21044         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
21045
21046         rm -f $DIR/$tfile
21047 }
21048 run_test 208 "Exclusive open"
21049
21050 test_209() {
21051         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
21052                 skip_env "must have disp_stripe"
21053
21054         touch $DIR/$tfile
21055         sync; sleep 5; sync;
21056
21057         echo 3 > /proc/sys/vm/drop_caches
21058         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21059                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21060         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21061
21062         # open/close 500 times
21063         for i in $(seq 500); do
21064                 cat $DIR/$tfile
21065         done
21066
21067         echo 3 > /proc/sys/vm/drop_caches
21068         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21069                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21070         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21071
21072         echo "before: $req_before, after: $req_after"
21073         [ $((req_after - req_before)) -ge 300 ] &&
21074                 error "open/close requests are not freed"
21075         return 0
21076 }
21077 run_test 209 "read-only open/close requests should be freed promptly"
21078
21079 test_210() {
21080         local pid
21081
21082         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21083         pid=$!
21084         sleep 1
21085
21086         $LFS getstripe $DIR/$tfile
21087         kill -USR1 $pid
21088         wait $pid || error "multiop failed"
21089
21090         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21091         pid=$!
21092         sleep 1
21093
21094         $LFS getstripe $DIR/$tfile
21095         kill -USR1 $pid
21096         wait $pid || error "multiop failed"
21097 }
21098 run_test 210 "lfs getstripe does not break leases"
21099
21100 function test_211() {
21101         local PID
21102         local id
21103         local rc
21104
21105         stack_trap "rm -f $DIR/$tfile" EXIT
21106         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21107                 error "can't create file"
21108         $LFS mirror extend -N $DIR/$tfile ||
21109                 error "can't create a replica"
21110         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21111         $LFS getstripe $DIR/$tfile
21112         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21113         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21114
21115         $MULTIOP $DIR/$tfile OeW_E+eUc &
21116         PID=$!
21117         sleep 0.3
21118
21119         id=$($LFS getstripe $DIR/$tfile |
21120                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21121         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21122                 error "removed last in-sync replica?"
21123
21124         kill -USR1 $PID
21125         wait $PID
21126         (( $? == 0 )) || error "failed split broke the lease"
21127 }
21128 run_test 211 "failed mirror split doesn't break write lease"
21129
21130 test_212() {
21131         size=`date +%s`
21132         size=$((size % 8192 + 1))
21133         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21134         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21135         rm -f $DIR/f212 $DIR/f212.xyz
21136 }
21137 run_test 212 "Sendfile test ============================================"
21138
21139 test_213() {
21140         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21141         cancel_lru_locks osc
21142         lctl set_param fail_loc=0x8000040f
21143         # generate a read lock
21144         cat $DIR/$tfile > /dev/null
21145         # write to the file, it will try to cancel the above read lock.
21146         cat /etc/hosts >> $DIR/$tfile
21147 }
21148 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21149
21150 test_214() { # for bug 20133
21151         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21152         for (( i=0; i < 340; i++ )) ; do
21153                 touch $DIR/$tdir/d214c/a$i
21154         done
21155
21156         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21157         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21158         ls $DIR/d214c || error "ls $DIR/d214c failed"
21159         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21160         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21161 }
21162 run_test 214 "hash-indexed directory test - bug 20133"
21163
21164 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21165 create_lnet_proc_files() {
21166         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21167 }
21168
21169 # counterpart of create_lnet_proc_files
21170 remove_lnet_proc_files() {
21171         rm -f $TMP/lnet_$1.sys
21172 }
21173
21174 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21175 # 3rd arg as regexp for body
21176 check_lnet_proc_stats() {
21177         local l=$(cat "$TMP/lnet_$1" |wc -l)
21178         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21179
21180         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21181 }
21182
21183 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21184 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21185 # optional and can be regexp for 2nd line (lnet.routes case)
21186 check_lnet_proc_entry() {
21187         local blp=2          # blp stands for 'position of 1st line of body'
21188         [ -z "$5" ] || blp=3 # lnet.routes case
21189
21190         local l=$(cat "$TMP/lnet_$1" |wc -l)
21191         # subtracting one from $blp because the body can be empty
21192         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21193
21194         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21195                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21196
21197         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21198                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21199
21200         # bail out if any unexpected line happened
21201         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21202         [ "$?" != 0 ] || error "$2 misformatted"
21203 }
21204
21205 test_215() { # for bugs 18102, 21079, 21517
21206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21207
21208         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21209         local P='[1-9][0-9]*'           # positive numeric
21210         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21211         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21212         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21213         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21214         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21215         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21216
21217         local L1 # regexp for 1st line
21218         local L2 # regexp for 2nd line (optional)
21219         local BR # regexp for the rest (body)
21220
21221         # lnet.stats should look as 11 space-separated non-negative numerics
21222         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21223         create_lnet_proc_files "stats"
21224         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21225         remove_lnet_proc_files "stats"
21226
21227         # lnet.routes should look like this:
21228         # Routing disabled/enabled
21229         # net hops priority state router
21230         # where net is a string like tcp0, hops > 0, priority >= 0,
21231         # state is up/down,
21232         # router is a string like 192.168.1.1@tcp2
21233         L1="^Routing (disabled|enabled)$"
21234         L2="^net +hops +priority +state +router$"
21235         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21236         create_lnet_proc_files "routes"
21237         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21238         remove_lnet_proc_files "routes"
21239
21240         # lnet.routers should look like this:
21241         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21242         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21243         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21244         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21245         L1="^ref +rtr_ref +alive +router$"
21246         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21247         create_lnet_proc_files "routers"
21248         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21249         remove_lnet_proc_files "routers"
21250
21251         # lnet.peers should look like this:
21252         # nid refs state last max rtr min tx min queue
21253         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21254         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21255         # numeric (0 or >0 or <0), queue >= 0.
21256         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21257         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21258         create_lnet_proc_files "peers"
21259         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21260         remove_lnet_proc_files "peers"
21261
21262         # lnet.buffers  should look like this:
21263         # pages count credits min
21264         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21265         L1="^pages +count +credits +min$"
21266         BR="^ +$N +$N +$I +$I$"
21267         create_lnet_proc_files "buffers"
21268         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21269         remove_lnet_proc_files "buffers"
21270
21271         # lnet.nis should look like this:
21272         # nid status alive refs peer rtr max tx min
21273         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21274         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21275         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21276         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21277         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21278         create_lnet_proc_files "nis"
21279         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21280         remove_lnet_proc_files "nis"
21281
21282         # can we successfully write to lnet.stats?
21283         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21284 }
21285 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21286
21287 test_216() { # bug 20317
21288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21289         remote_ost_nodsh && skip "remote OST with nodsh"
21290
21291         local node
21292         local facets=$(get_facets OST)
21293         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21294
21295         save_lustre_params client "osc.*.contention_seconds" > $p
21296         save_lustre_params $facets \
21297                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21298         save_lustre_params $facets \
21299                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21300         save_lustre_params $facets \
21301                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21302         clear_stats osc.*.osc_stats
21303
21304         # agressive lockless i/o settings
21305         do_nodes $(comma_list $(osts_nodes)) \
21306                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21307                         ldlm.namespaces.filter-*.contended_locks=0 \
21308                         ldlm.namespaces.filter-*.contention_seconds=60"
21309         lctl set_param -n osc.*.contention_seconds=60
21310
21311         $DIRECTIO write $DIR/$tfile 0 10 4096
21312         $CHECKSTAT -s 40960 $DIR/$tfile
21313
21314         # disable lockless i/o
21315         do_nodes $(comma_list $(osts_nodes)) \
21316                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21317                         ldlm.namespaces.filter-*.contended_locks=32 \
21318                         ldlm.namespaces.filter-*.contention_seconds=0"
21319         lctl set_param -n osc.*.contention_seconds=0
21320         clear_stats osc.*.osc_stats
21321
21322         dd if=/dev/zero of=$DIR/$tfile count=0
21323         $CHECKSTAT -s 0 $DIR/$tfile
21324
21325         restore_lustre_params <$p
21326         rm -f $p
21327         rm $DIR/$tfile
21328 }
21329 run_test 216 "check lockless direct write updates file size and kms correctly"
21330
21331 test_217() { # bug 22430
21332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21333
21334         local node
21335
21336         for node in $(nodes_list); do
21337                 local nid=$(host_nids_address $node $NETTYPE)
21338                 local node_ip=$(do_node $node getent ahostsv4 $node |
21339                                 awk '{ print $1; exit; }')
21340
21341                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21342                 # if hostname matches any NID, use hostname for better testing
21343                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21344                         echo "lctl ping node $node@$NETTYPE"
21345                         lctl ping $node@$NETTYPE ||
21346                                 error "ping $node@$NETTYPE failed rc=$?"
21347                 else # otherwise, at least test 'lctl ping' is working
21348                         echo "lctl ping nid $(h2nettype $nid)"
21349                         lctl ping $(h2nettype $nid) ||
21350                                 error "ping $(h2nettype $nid) failed rc=$?"
21351                         echo "skipping $node (no hyphen detected)"
21352                 fi
21353         done
21354
21355         return 0
21356 }
21357 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21358
21359 test_218() {
21360         # do directio so as not to populate the page cache
21361         log "creating a 10 Mb file"
21362         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21363                 error "multiop failed while creating a file"
21364         log "starting reads"
21365         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21366         log "truncating the file"
21367         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21368                 error "multiop failed while truncating the file"
21369         log "killing dd"
21370         kill %+ || true # reads might have finished
21371         echo "wait until dd is finished"
21372         wait
21373         log "removing the temporary file"
21374         rm -rf $DIR/$tfile || error "tmp file removal failed"
21375 }
21376 run_test 218 "parallel read and truncate should not deadlock"
21377
21378 test_219() {
21379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21380
21381         # write one partial page
21382         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21383         # set no grant so vvp_io_commit_write will do sync write
21384         $LCTL set_param fail_loc=0x411
21385         # write a full page at the end of file
21386         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21387
21388         $LCTL set_param fail_loc=0
21389         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21390         $LCTL set_param fail_loc=0x411
21391         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21392
21393         # LU-4201
21394         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21395         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21396 }
21397 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21398
21399 test_220() { #LU-325
21400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21401         remote_ost_nodsh && skip "remote OST with nodsh"
21402         remote_mds_nodsh && skip "remote MDS with nodsh"
21403         remote_mgs_nodsh && skip "remote MGS with nodsh"
21404
21405         local OSTIDX=0
21406
21407         # create on MDT0000 so the last_id and next_id are correct
21408         mkdir_on_mdt0 $DIR/$tdir
21409         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21410         OST=${OST%_UUID}
21411
21412         # on the mdt's osc
21413         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21414         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21415                         osp.$mdtosc_proc1.prealloc_last_id)
21416         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21417                         osp.$mdtosc_proc1.prealloc_next_id)
21418
21419         $LFS df -i
21420
21421         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21422         #define OBD_FAIL_OST_ENOINO              0x229
21423         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21424         create_pool $FSNAME.$TESTNAME || return 1
21425         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21426
21427         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21428
21429         MDSOBJS=$((last_id - next_id))
21430         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21431
21432         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21433         echo "OST still has $count kbytes free"
21434
21435         echo "create $MDSOBJS files @next_id..."
21436         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21437
21438         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21439                         osp.$mdtosc_proc1.prealloc_last_id)
21440         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21441                         osp.$mdtosc_proc1.prealloc_next_id)
21442
21443         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21444         $LFS df -i
21445
21446         echo "cleanup..."
21447
21448         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21449         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21450
21451         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21452                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21453         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21454                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21455         echo "unlink $MDSOBJS files @$next_id..."
21456         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21457 }
21458 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21459
21460 test_221() {
21461         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21462
21463         dd if=`which date` of=$MOUNT/date oflag=sync
21464         chmod +x $MOUNT/date
21465
21466         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21467         $LCTL set_param fail_loc=0x80001401
21468
21469         $MOUNT/date > /dev/null
21470         rm -f $MOUNT/date
21471 }
21472 run_test 221 "make sure fault and truncate race to not cause OOM"
21473
21474 test_222a () {
21475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21476
21477         rm -rf $DIR/$tdir
21478         test_mkdir $DIR/$tdir
21479         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21480         createmany -o $DIR/$tdir/$tfile 10
21481         cancel_lru_locks mdc
21482         cancel_lru_locks osc
21483         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21484         $LCTL set_param fail_loc=0x31a
21485         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21486         $LCTL set_param fail_loc=0
21487         rm -r $DIR/$tdir
21488 }
21489 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21490
21491 test_222b () {
21492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21493
21494         rm -rf $DIR/$tdir
21495         test_mkdir $DIR/$tdir
21496         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21497         createmany -o $DIR/$tdir/$tfile 10
21498         cancel_lru_locks mdc
21499         cancel_lru_locks osc
21500         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21501         $LCTL set_param fail_loc=0x31a
21502         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21503         $LCTL set_param fail_loc=0
21504 }
21505 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21506
21507 test_223 () {
21508         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21509
21510         rm -rf $DIR/$tdir
21511         test_mkdir $DIR/$tdir
21512         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21513         createmany -o $DIR/$tdir/$tfile 10
21514         cancel_lru_locks mdc
21515         cancel_lru_locks osc
21516         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21517         $LCTL set_param fail_loc=0x31b
21518         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21519         $LCTL set_param fail_loc=0
21520         rm -r $DIR/$tdir
21521 }
21522 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21523
21524 test_224a() { # LU-1039, MRP-303
21525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21526         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21527         $LCTL set_param fail_loc=0x508
21528         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21529         $LCTL set_param fail_loc=0
21530         df $DIR
21531 }
21532 run_test 224a "Don't panic on bulk IO failure"
21533
21534 test_224bd_sub() { # LU-1039, MRP-303
21535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21536         local timeout=$1
21537
21538         shift
21539         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21540
21541         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21542
21543         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21544         cancel_lru_locks osc
21545         set_checksums 0
21546         stack_trap "set_checksums $ORIG_CSUM" EXIT
21547         local at_max_saved=0
21548
21549         # adaptive timeouts may prevent seeing the issue
21550         if at_is_enabled; then
21551                 at_max_saved=$(at_max_get mds)
21552                 at_max_set 0 mds client
21553                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21554         fi
21555
21556         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21557         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21558         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21559
21560         do_facet ost1 $LCTL set_param fail_loc=0
21561         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21562         df $DIR
21563 }
21564
21565 test_224b() {
21566         test_224bd_sub 3 error "dd failed"
21567 }
21568 run_test 224b "Don't panic on bulk IO failure"
21569
21570 test_224c() { # LU-6441
21571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21572         remote_mds_nodsh && skip "remote MDS with nodsh"
21573
21574         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21575         save_writethrough $p
21576         set_cache writethrough on
21577
21578         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21579         local at_max=$($LCTL get_param -n at_max)
21580         local timeout=$($LCTL get_param -n timeout)
21581         local test_at="at_max"
21582         local param_at="$FSNAME.sys.at_max"
21583         local test_timeout="timeout"
21584         local param_timeout="$FSNAME.sys.timeout"
21585
21586         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21587
21588         set_persistent_param_and_check client "$test_at" "$param_at" 0
21589         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21590
21591         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21592         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21593         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21594         stack_trap "rm -f $DIR/$tfile"
21595         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21596         sync
21597         do_facet ost1 "$LCTL set_param fail_loc=0"
21598
21599         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21600         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21601                 $timeout
21602
21603         $LCTL set_param -n $pages_per_rpc
21604         restore_lustre_params < $p
21605         rm -f $p
21606 }
21607 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21608
21609 test_224d() { # LU-11169
21610         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21611 }
21612 run_test 224d "Don't corrupt data on bulk IO timeout"
21613
21614 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21615 test_225a () {
21616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21617         if [ -z ${MDSSURVEY} ]; then
21618                 skip_env "mds-survey not found"
21619         fi
21620         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21621                 skip "Need MDS version at least 2.2.51"
21622
21623         local mds=$(facet_host $SINGLEMDS)
21624         local target=$(do_nodes $mds 'lctl dl' |
21625                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21626
21627         local cmd1="file_count=1000 thrhi=4"
21628         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21629         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21630         local cmd="$cmd1 $cmd2 $cmd3"
21631
21632         rm -f ${TMP}/mds_survey*
21633         echo + $cmd
21634         eval $cmd || error "mds-survey with zero-stripe failed"
21635         cat ${TMP}/mds_survey*
21636         rm -f ${TMP}/mds_survey*
21637 }
21638 run_test 225a "Metadata survey sanity with zero-stripe"
21639
21640 test_225b () {
21641         if [ -z ${MDSSURVEY} ]; then
21642                 skip_env "mds-survey not found"
21643         fi
21644         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21645                 skip "Need MDS version at least 2.2.51"
21646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21647         remote_mds_nodsh && skip "remote MDS with nodsh"
21648         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21649                 skip_env "Need to mount OST to test"
21650         fi
21651
21652         local mds=$(facet_host $SINGLEMDS)
21653         local target=$(do_nodes $mds 'lctl dl' |
21654                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21655
21656         local cmd1="file_count=1000 thrhi=4"
21657         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21658         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21659         local cmd="$cmd1 $cmd2 $cmd3"
21660
21661         rm -f ${TMP}/mds_survey*
21662         echo + $cmd
21663         eval $cmd || error "mds-survey with stripe_count failed"
21664         cat ${TMP}/mds_survey*
21665         rm -f ${TMP}/mds_survey*
21666 }
21667 run_test 225b "Metadata survey sanity with stripe_count = 1"
21668
21669 mcreate_path2fid () {
21670         local mode=$1
21671         local major=$2
21672         local minor=$3
21673         local name=$4
21674         local desc=$5
21675         local path=$DIR/$tdir/$name
21676         local fid
21677         local rc
21678         local fid_path
21679
21680         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21681                 error "cannot create $desc"
21682
21683         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21684         rc=$?
21685         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21686
21687         fid_path=$($LFS fid2path $MOUNT $fid)
21688         rc=$?
21689         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21690
21691         [ "$path" == "$fid_path" ] ||
21692                 error "fid2path returned $fid_path, expected $path"
21693
21694         echo "pass with $path and $fid"
21695 }
21696
21697 test_226a () {
21698         rm -rf $DIR/$tdir
21699         mkdir -p $DIR/$tdir
21700
21701         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21702         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21703         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21704         mcreate_path2fid 0040666 0 0 dir "directory"
21705         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21706         mcreate_path2fid 0100666 0 0 file "regular file"
21707         mcreate_path2fid 0120666 0 0 link "symbolic link"
21708         mcreate_path2fid 0140666 0 0 sock "socket"
21709 }
21710 run_test 226a "call path2fid and fid2path on files of all type"
21711
21712 test_226b () {
21713         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21714
21715         local MDTIDX=1
21716
21717         rm -rf $DIR/$tdir
21718         mkdir -p $DIR/$tdir
21719         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21720                 error "create remote directory failed"
21721         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21722         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21723                                 "character special file (null)"
21724         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21725                                 "character special file (no device)"
21726         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21727         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21728                                 "block special file (loop)"
21729         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21730         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21731         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21732 }
21733 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21734
21735 test_226c () {
21736         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21737         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21738                 skip "Need MDS version at least 2.13.55"
21739
21740         local submnt=/mnt/submnt
21741         local srcfile=/etc/passwd
21742         local dstfile=$submnt/passwd
21743         local path
21744         local fid
21745
21746         rm -rf $DIR/$tdir
21747         rm -rf $submnt
21748         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21749                 error "create remote directory failed"
21750         mkdir -p $submnt || error "create $submnt failed"
21751         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21752                 error "mount $submnt failed"
21753         stack_trap "umount $submnt" EXIT
21754
21755         cp $srcfile $dstfile
21756         fid=$($LFS path2fid $dstfile)
21757         path=$($LFS fid2path $submnt "$fid")
21758         [ "$path" = "$dstfile" ] ||
21759                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21760 }
21761 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21762
21763 test_226d () {
21764         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21765                 skip "Need client at least version 2.15.57"
21766
21767         # Define First test dataset
21768         local testdirs_01=$DIR/$tdir
21769         local testdata_01=$testdirs_01/${tdir}_01
21770         local testresult_01=${tdir}_01
21771         # Define Second test dataset
21772         local testdirs_02=$DIR/$tdir/$tdir
21773         local testdata_02=$testdirs_02/${tdir}_02
21774         local testresult_02=${tdir}_02
21775         # Define third test dataset (top level)
21776         local testdata_03=$DIR/${tdir}_03
21777         local testresult_03=${tdir}_03
21778
21779         # Create first test dataset
21780         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21781         touch $testdata_01 || error "cannot create file $testdata_01"
21782
21783         # Create second test dataset
21784         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21785         touch $testdata_02 || error "cannot create file $testdata_02"
21786
21787         # Create third test dataset
21788         touch $testdata_03 || error "cannot create file $testdata_03"
21789
21790         local fid01=$($LFS getstripe -F "$testdata_01") ||
21791                 error "getstripe failed on $testdata_01"
21792         local fid02=$($LFS getstripe -F "$testdata_02") ||
21793                 error "getstripe failed on $testdata_01"
21794         local fid03=$($LFS getstripe -F "$testdata_03") ||
21795                 error "getstripe failed on $testdata_03"
21796
21797         # Verify only -n option
21798         local out1=$($LFS fid2path -n $DIR $fid01) ||
21799                 error "fid2path failed on $fid01"
21800         local out2=$($LFS fid2path -n $DIR $fid02) ||
21801                 error "fid2path failed on $fid02"
21802         local out3=$($LFS fid2path -n $DIR $fid03) ||
21803                 error "fid2path failed on $fid03"
21804
21805         [[ "$out1" == "$testresult_01" ]] ||
21806                 error "fid2path failed: Expected $testresult_01 got $out1"
21807         [[ "$out2" == "$testresult_02" ]] ||
21808                 error "fid2path failed: Expected $testresult_02 got $out2"
21809         [[ "$out3" == "$testresult_03" ]] ||
21810                 error "fid2path failed: Expected $testresult_03 got $out3"
21811
21812         # Verify with option -fn together
21813         out1=$($LFS fid2path -fn $DIR $fid01) ||
21814                 error "fid2path -fn failed on $fid01"
21815         out2=$($LFS fid2path -fn $DIR $fid02) ||
21816                 error "fid2path -fn failed on $fid02"
21817         out3=$($LFS fid2path -fn $DIR $fid03) ||
21818                 error "fid2path -fn failed on $fid03"
21819
21820         local tmpout=$(echo $out1 | cut -d" " -f2)
21821         [[ "$tmpout" == "$testresult_01" ]] ||
21822                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21823
21824         tmpout=$(echo $out2 | cut -d" " -f2)
21825         [[ "$tmpout" == "$testresult_02" ]] ||
21826                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21827
21828         tmpout=$(echo $out3 | cut -d" " -f2)
21829         [[ "$tmpout" == "$testresult_03" ]] ||
21830                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21831 }
21832 run_test 226d "verify fid2path with -n and -fn option"
21833
21834 test_226e () {
21835         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21836                 skip "Need client at least version 2.15.56"
21837
21838         # Define filename with 'newline' and a space
21839         local testfile="Test"$'\n'"file 01"
21840         # Define link name with multiple 'newline' and a space
21841         local linkfile="Link"$'\n'"file "$'\n'"01"
21842         # Remove prior hard link
21843         rm -f $DIR/"$linkfile"
21844
21845         # Create file
21846         touch $DIR/"$testfile"
21847         # Create link
21848         ln $DIR/"$testfile" $DIR/"$linkfile"
21849
21850         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21851                 error "getstripe failed on $DIR/$testfile"
21852
21853         # Call with -0 option
21854         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21855                 echo "FILE:" | grep -c "FILE:")
21856
21857         # With -0 option the output should be exactly 2 lines.
21858         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21859 }
21860 run_test 226e "Verify path2fid -0 option with newline and space"
21861
21862 # LU-1299 Executing or running ldd on a truncated executable does not
21863 # cause an out-of-memory condition.
21864 test_227() {
21865         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21866         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21867
21868         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21869         chmod +x $MOUNT/date
21870
21871         $MOUNT/date > /dev/null
21872         ldd $MOUNT/date > /dev/null
21873         rm -f $MOUNT/date
21874 }
21875 run_test 227 "running truncated executable does not cause OOM"
21876
21877 # LU-1512 try to reuse idle OI blocks
21878 test_228a() {
21879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21880         remote_mds_nodsh && skip "remote MDS with nodsh"
21881         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21882
21883         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21884         local myDIR=$DIR/$tdir
21885
21886         mkdir -p $myDIR
21887         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21888         $LCTL set_param fail_loc=0x80001002
21889         createmany -o $myDIR/t- 10000
21890         $LCTL set_param fail_loc=0
21891         # The guard is current the largest FID holder
21892         touch $myDIR/guard
21893         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21894                     tr -d '[')
21895         local IDX=$(($SEQ % 64))
21896
21897         do_facet $SINGLEMDS sync
21898         # Make sure journal flushed.
21899         sleep 6
21900         local blk1=$(do_facet $SINGLEMDS \
21901                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21902                      grep Blockcount | awk '{print $4}')
21903
21904         # Remove old files, some OI blocks will become idle.
21905         unlinkmany $myDIR/t- 10000
21906         # Create new files, idle OI blocks should be reused.
21907         createmany -o $myDIR/t- 2000
21908         do_facet $SINGLEMDS sync
21909         # Make sure journal flushed.
21910         sleep 6
21911         local blk2=$(do_facet $SINGLEMDS \
21912                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21913                      grep Blockcount | awk '{print $4}')
21914
21915         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21916 }
21917 run_test 228a "try to reuse idle OI blocks"
21918
21919 test_228b() {
21920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21921         remote_mds_nodsh && skip "remote MDS with nodsh"
21922         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21923
21924         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21925         local myDIR=$DIR/$tdir
21926
21927         mkdir -p $myDIR
21928         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21929         $LCTL set_param fail_loc=0x80001002
21930         createmany -o $myDIR/t- 10000
21931         $LCTL set_param fail_loc=0
21932         # The guard is current the largest FID holder
21933         touch $myDIR/guard
21934         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21935                     tr -d '[')
21936         local IDX=$(($SEQ % 64))
21937
21938         do_facet $SINGLEMDS sync
21939         # Make sure journal flushed.
21940         sleep 6
21941         local blk1=$(do_facet $SINGLEMDS \
21942                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21943                      grep Blockcount | awk '{print $4}')
21944
21945         # Remove old files, some OI blocks will become idle.
21946         unlinkmany $myDIR/t- 10000
21947
21948         # stop the MDT
21949         stop $SINGLEMDS || error "Fail to stop MDT."
21950         # remount the MDT
21951         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21952                 error "Fail to start MDT."
21953
21954         client_up || error "Fail to df."
21955         # Create new files, idle OI blocks should be reused.
21956         createmany -o $myDIR/t- 2000
21957         do_facet $SINGLEMDS sync
21958         # Make sure journal flushed.
21959         sleep 6
21960         local blk2=$(do_facet $SINGLEMDS \
21961                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21962                      grep Blockcount | awk '{print $4}')
21963
21964         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21965 }
21966 run_test 228b "idle OI blocks can be reused after MDT restart"
21967
21968 #LU-1881
21969 test_228c() {
21970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21971         remote_mds_nodsh && skip "remote MDS with nodsh"
21972         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21973
21974         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21975         local myDIR=$DIR/$tdir
21976
21977         mkdir -p $myDIR
21978         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21979         $LCTL set_param fail_loc=0x80001002
21980         # 20000 files can guarantee there are index nodes in the OI file
21981         createmany -o $myDIR/t- 20000
21982         $LCTL set_param fail_loc=0
21983         # The guard is current the largest FID holder
21984         touch $myDIR/guard
21985         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21986                     tr -d '[')
21987         local IDX=$(($SEQ % 64))
21988
21989         do_facet $SINGLEMDS sync
21990         # Make sure journal flushed.
21991         sleep 6
21992         local blk1=$(do_facet $SINGLEMDS \
21993                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21994                      grep Blockcount | awk '{print $4}')
21995
21996         # Remove old files, some OI blocks will become idle.
21997         unlinkmany $myDIR/t- 20000
21998         rm -f $myDIR/guard
21999         # The OI file should become empty now
22000
22001         # Create new files, idle OI blocks should be reused.
22002         createmany -o $myDIR/t- 2000
22003         do_facet $SINGLEMDS sync
22004         # Make sure journal flushed.
22005         sleep 6
22006         local blk2=$(do_facet $SINGLEMDS \
22007                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
22008                      grep Blockcount | awk '{print $4}')
22009
22010         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
22011 }
22012 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
22013
22014 test_229() { # LU-2482, LU-3448
22015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22016         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
22017         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
22018                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
22019
22020         rm -f $DIR/$tfile
22021
22022         # Create a file with a released layout and stripe count 2.
22023         $MULTIOP $DIR/$tfile H2c ||
22024                 error "failed to create file with released layout"
22025
22026         $LFS getstripe -v $DIR/$tfile
22027
22028         local pattern=$($LFS getstripe -L $DIR/$tfile)
22029         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
22030
22031         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
22032                 error "getstripe"
22033         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
22034         stat $DIR/$tfile || error "failed to stat released file"
22035
22036         chown $RUNAS_ID $DIR/$tfile ||
22037                 error "chown $RUNAS_ID $DIR/$tfile failed"
22038
22039         chgrp $RUNAS_ID $DIR/$tfile ||
22040                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
22041
22042         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
22043         rm $DIR/$tfile || error "failed to remove released file"
22044 }
22045 run_test 229 "getstripe/stat/rm/attr changes work on released files"
22046
22047 test_230a() {
22048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22049         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22050         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22051                 skip "Need MDS version at least 2.11.52"
22052
22053         local MDTIDX=1
22054
22055         test_mkdir $DIR/$tdir
22056         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22057         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22058         [ $mdt_idx -ne 0 ] &&
22059                 error "create local directory on wrong MDT $mdt_idx"
22060
22061         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22062                         error "create remote directory failed"
22063         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22064         [ $mdt_idx -ne $MDTIDX ] &&
22065                 error "create remote directory on wrong MDT $mdt_idx"
22066
22067         createmany -o $DIR/$tdir/test_230/t- 10 ||
22068                 error "create files on remote directory failed"
22069         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22070         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22071         rm -r $DIR/$tdir || error "unlink remote directory failed"
22072 }
22073 run_test 230a "Create remote directory and files under the remote directory"
22074
22075 test_230b() {
22076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22077         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22078         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22079                 skip "Need MDS version at least 2.11.52"
22080
22081         local MDTIDX=1
22082         local mdt_index
22083         local i
22084         local file
22085         local pid
22086         local stripe_count
22087         local migrate_dir=$DIR/$tdir/migrate_dir
22088         local other_dir=$DIR/$tdir/other_dir
22089
22090         test_mkdir $DIR/$tdir
22091         test_mkdir -i0 -c1 $migrate_dir
22092         test_mkdir -i0 -c1 $other_dir
22093         for ((i=0; i<10; i++)); do
22094                 mkdir -p $migrate_dir/dir_${i}
22095                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22096                         error "create files under remote dir failed $i"
22097         done
22098
22099         cp /etc/passwd $migrate_dir/$tfile
22100         cp /etc/passwd $other_dir/$tfile
22101         chattr +SAD $migrate_dir
22102         chattr +SAD $migrate_dir/$tfile
22103
22104         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22105         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22106         local old_dir_mode=$(stat -c%f $migrate_dir)
22107         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22108
22109         mkdir -p $migrate_dir/dir_default_stripe2
22110         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22111         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22112
22113         mkdir -p $other_dir
22114         ln $migrate_dir/$tfile $other_dir/luna
22115         ln $migrate_dir/$tfile $migrate_dir/sofia
22116         ln $other_dir/$tfile $migrate_dir/david
22117         ln -s $migrate_dir/$tfile $other_dir/zachary
22118         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22119         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22120
22121         local len
22122         local lnktgt
22123
22124         # inline symlink
22125         for len in 58 59 60; do
22126                 lnktgt=$(str_repeat 'l' $len)
22127                 touch $migrate_dir/$lnktgt
22128                 ln -s $lnktgt $migrate_dir/${len}char_ln
22129         done
22130
22131         # PATH_MAX
22132         for len in 4094 4095; do
22133                 lnktgt=$(str_repeat 'l' $len)
22134                 ln -s $lnktgt $migrate_dir/${len}char_ln
22135         done
22136
22137         # NAME_MAX
22138         for len in 254 255; do
22139                 touch $migrate_dir/$(str_repeat 'l' $len)
22140         done
22141
22142         $LFS migrate -m $MDTIDX $migrate_dir ||
22143                 error "fails on migrating remote dir to MDT1"
22144
22145         echo "migratate to MDT1, then checking.."
22146         for ((i = 0; i < 10; i++)); do
22147                 for file in $(find $migrate_dir/dir_${i}); do
22148                         mdt_index=$($LFS getstripe -m $file)
22149                         # broken symlink getstripe will fail
22150                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22151                                 error "$file is not on MDT${MDTIDX}"
22152                 done
22153         done
22154
22155         # the multiple link file should still in MDT0
22156         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22157         [ $mdt_index == 0 ] ||
22158                 error "$file is not on MDT${MDTIDX}"
22159
22160         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22161         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22162                 error " expect $old_dir_flag get $new_dir_flag"
22163
22164         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22165         [ "$old_file_flag" = "$new_file_flag" ] ||
22166                 error " expect $old_file_flag get $new_file_flag"
22167
22168         local new_dir_mode=$(stat -c%f $migrate_dir)
22169         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22170                 error "expect mode $old_dir_mode get $new_dir_mode"
22171
22172         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22173         [ "$old_file_mode" = "$new_file_mode" ] ||
22174                 error "expect mode $old_file_mode get $new_file_mode"
22175
22176         diff /etc/passwd $migrate_dir/$tfile ||
22177                 error "$tfile different after migration"
22178
22179         diff /etc/passwd $other_dir/luna ||
22180                 error "luna different after migration"
22181
22182         diff /etc/passwd $migrate_dir/sofia ||
22183                 error "sofia different after migration"
22184
22185         diff /etc/passwd $migrate_dir/david ||
22186                 error "david different after migration"
22187
22188         diff /etc/passwd $other_dir/zachary ||
22189                 error "zachary different after migration"
22190
22191         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22192                 error "${tfile}_ln different after migration"
22193
22194         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22195                 error "${tfile}_ln_other different after migration"
22196
22197         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22198         [ $stripe_count = 2 ] ||
22199                 error "dir strpe_count $d != 2 after migration."
22200
22201         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22202         [ $stripe_count = 2 ] ||
22203                 error "file strpe_count $d != 2 after migration."
22204
22205         #migrate back to MDT0
22206         MDTIDX=0
22207
22208         $LFS migrate -m $MDTIDX $migrate_dir ||
22209                 error "fails on migrating remote dir to MDT0"
22210
22211         echo "migrate back to MDT0, checking.."
22212         for file in $(find $migrate_dir); do
22213                 mdt_index=$($LFS getstripe -m $file)
22214                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22215                         error "$file is not on MDT${MDTIDX}"
22216         done
22217
22218         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22219         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22220                 error " expect $old_dir_flag get $new_dir_flag"
22221
22222         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22223         [ "$old_file_flag" = "$new_file_flag" ] ||
22224                 error " expect $old_file_flag get $new_file_flag"
22225
22226         local new_dir_mode=$(stat -c%f $migrate_dir)
22227         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22228                 error "expect mode $old_dir_mode get $new_dir_mode"
22229
22230         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22231         [ "$old_file_mode" = "$new_file_mode" ] ||
22232                 error "expect mode $old_file_mode get $new_file_mode"
22233
22234         diff /etc/passwd ${migrate_dir}/$tfile ||
22235                 error "$tfile different after migration"
22236
22237         diff /etc/passwd ${other_dir}/luna ||
22238                 error "luna different after migration"
22239
22240         diff /etc/passwd ${migrate_dir}/sofia ||
22241                 error "sofia different after migration"
22242
22243         diff /etc/passwd ${other_dir}/zachary ||
22244                 error "zachary different after migration"
22245
22246         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22247                 error "${tfile}_ln different after migration"
22248
22249         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22250                 error "${tfile}_ln_other different after migration"
22251
22252         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22253         [ $stripe_count = 2 ] ||
22254                 error "dir strpe_count $d != 2 after migration."
22255
22256         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22257         [ $stripe_count = 2 ] ||
22258                 error "file strpe_count $d != 2 after migration."
22259
22260         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22261 }
22262 run_test 230b "migrate directory"
22263
22264 test_230c() {
22265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22266         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22267         remote_mds_nodsh && skip "remote MDS with nodsh"
22268         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22269                 skip "Need MDS version at least 2.11.52"
22270
22271         local MDTIDX=1
22272         local total=3
22273         local mdt_index
22274         local file
22275         local migrate_dir=$DIR/$tdir/migrate_dir
22276
22277         #If migrating directory fails in the middle, all entries of
22278         #the directory is still accessiable.
22279         test_mkdir $DIR/$tdir
22280         test_mkdir -i0 -c1 $migrate_dir
22281         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22282         stat $migrate_dir
22283         createmany -o $migrate_dir/f $total ||
22284                 error "create files under ${migrate_dir} failed"
22285
22286         # fail after migrating top dir, and this will fail only once, so the
22287         # first sub file migration will fail (currently f3), others succeed.
22288         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22289         do_facet mds1 lctl set_param fail_loc=0x1801
22290         local t=$(ls $migrate_dir | wc -l)
22291         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22292                 error "migrate should fail"
22293         local u=$(ls $migrate_dir | wc -l)
22294         [ "$u" == "$t" ] || error "$u != $t during migration"
22295
22296         # add new dir/file should succeed
22297         mkdir $migrate_dir/dir ||
22298                 error "mkdir failed under migrating directory"
22299         touch $migrate_dir/file ||
22300                 error "create file failed under migrating directory"
22301
22302         # add file with existing name should fail
22303         for file in $migrate_dir/f*; do
22304                 stat $file > /dev/null || error "stat $file failed"
22305                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22306                         error "open(O_CREAT|O_EXCL) $file should fail"
22307                 $MULTIOP $file m && error "create $file should fail"
22308                 touch $DIR/$tdir/remote_dir/$tfile ||
22309                         error "touch $tfile failed"
22310                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22311                         error "link $file should fail"
22312                 mdt_index=$($LFS getstripe -m $file)
22313                 if [ $mdt_index == 0 ]; then
22314                         # file failed to migrate is not allowed to rename to
22315                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22316                                 error "rename to $file should fail"
22317                 else
22318                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22319                                 error "rename to $file failed"
22320                 fi
22321                 echo hello >> $file || error "write $file failed"
22322         done
22323
22324         # resume migration with different options should fail
22325         $LFS migrate -m 0 $migrate_dir &&
22326                 error "migrate -m 0 $migrate_dir should fail"
22327
22328         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22329                 error "migrate -c 2 $migrate_dir should fail"
22330
22331         # resume migration should succeed
22332         $LFS migrate -m $MDTIDX $migrate_dir ||
22333                 error "migrate $migrate_dir failed"
22334
22335         echo "Finish migration, then checking.."
22336         for file in $(find $migrate_dir); do
22337                 mdt_index=$($LFS getstripe -m $file)
22338                 [ $mdt_index == $MDTIDX ] ||
22339                         error "$file is not on MDT${MDTIDX}"
22340         done
22341
22342         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22343 }
22344 run_test 230c "check directory accessiblity if migration failed"
22345
22346 test_230d() {
22347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22348         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22349         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22350                 skip "Need MDS version at least 2.11.52"
22351         # LU-11235
22352         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22353
22354         local migrate_dir=$DIR/$tdir/migrate_dir
22355         local old_index
22356         local new_index
22357         local old_count
22358         local new_count
22359         local new_hash
22360         local mdt_index
22361         local i
22362         local j
22363
22364         old_index=$((RANDOM % MDSCOUNT))
22365         old_count=$((MDSCOUNT - old_index))
22366         new_index=$((RANDOM % MDSCOUNT))
22367         new_count=$((MDSCOUNT - new_index))
22368         new_hash=1 # for all_char
22369
22370         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22371         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22372
22373         test_mkdir $DIR/$tdir
22374         test_mkdir -i $old_index -c $old_count $migrate_dir
22375
22376         for ((i=0; i<100; i++)); do
22377                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22378                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22379                         error "create files under remote dir failed $i"
22380         done
22381
22382         echo -n "Migrate from MDT$old_index "
22383         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22384         echo -n "to MDT$new_index"
22385         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22386         echo
22387
22388         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22389         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22390                 error "migrate remote dir error"
22391
22392         echo "Finish migration, then checking.."
22393         for file in $(find $migrate_dir -maxdepth 1); do
22394                 mdt_index=$($LFS getstripe -m $file)
22395                 if [ $mdt_index -lt $new_index ] ||
22396                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22397                         error "$file is on MDT$mdt_index"
22398                 fi
22399         done
22400
22401         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22402 }
22403 run_test 230d "check migrate big directory"
22404
22405 test_230e() {
22406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22407         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22408         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22409                 skip "Need MDS version at least 2.11.52"
22410
22411         local i
22412         local j
22413         local a_fid
22414         local b_fid
22415
22416         mkdir_on_mdt0 $DIR/$tdir
22417         mkdir $DIR/$tdir/migrate_dir
22418         mkdir $DIR/$tdir/other_dir
22419         touch $DIR/$tdir/migrate_dir/a
22420         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22421         ls $DIR/$tdir/other_dir
22422
22423         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22424                 error "migrate dir fails"
22425
22426         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22427         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22428
22429         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22430         [ $mdt_index == 0 ] || error "a is not on MDT0"
22431
22432         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22433                 error "migrate dir fails"
22434
22435         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22436         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22437
22438         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22439         [ $mdt_index == 1 ] || error "a is not on MDT1"
22440
22441         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22442         [ $mdt_index == 1 ] || error "b is not on MDT1"
22443
22444         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22445         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22446
22447         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22448
22449         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22450 }
22451 run_test 230e "migrate mulitple local link files"
22452
22453 test_230f() {
22454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22455         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22456         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22457                 skip "Need MDS version at least 2.11.52"
22458
22459         local a_fid
22460         local ln_fid
22461
22462         mkdir -p $DIR/$tdir
22463         mkdir $DIR/$tdir/migrate_dir
22464         $LFS mkdir -i1 $DIR/$tdir/other_dir
22465         touch $DIR/$tdir/migrate_dir/a
22466         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22467         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22468         ls $DIR/$tdir/other_dir
22469
22470         # a should be migrated to MDT1, since no other links on MDT0
22471         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22472                 error "#1 migrate dir fails"
22473         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22474         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22475         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22476         [ $mdt_index == 1 ] || error "a is not on MDT1"
22477
22478         # a should stay on MDT1, because it is a mulitple link file
22479         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22480                 error "#2 migrate dir fails"
22481         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22482         [ $mdt_index == 1 ] || error "a is not on MDT1"
22483
22484         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22485                 error "#3 migrate dir fails"
22486
22487         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22488         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22489         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22490
22491         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22492         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22493
22494         # a should be migrated to MDT0, since no other links on MDT1
22495         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22496                 error "#4 migrate dir fails"
22497         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22498         [ $mdt_index == 0 ] || error "a is not on MDT0"
22499
22500         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22501 }
22502 run_test 230f "migrate mulitple remote link files"
22503
22504 test_230g() {
22505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22506         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22507         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22508                 skip "Need MDS version at least 2.11.52"
22509
22510         mkdir -p $DIR/$tdir/migrate_dir
22511
22512         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22513                 error "migrating dir to non-exist MDT succeeds"
22514         true
22515 }
22516 run_test 230g "migrate dir to non-exist MDT"
22517
22518 test_230h() {
22519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22521         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22522                 skip "Need MDS version at least 2.11.52"
22523
22524         local mdt_index
22525
22526         mkdir -p $DIR/$tdir/migrate_dir
22527
22528         $LFS migrate -m1 $DIR &&
22529                 error "migrating mountpoint1 should fail"
22530
22531         $LFS migrate -m1 $DIR/$tdir/.. &&
22532                 error "migrating mountpoint2 should fail"
22533
22534         # same as mv
22535         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22536                 error "migrating $tdir/migrate_dir/.. should fail"
22537
22538         true
22539 }
22540 run_test 230h "migrate .. and root"
22541
22542 test_230i() {
22543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22544         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22545         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22546                 skip "Need MDS version at least 2.11.52"
22547
22548         mkdir -p $DIR/$tdir/migrate_dir
22549
22550         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22551                 error "migration fails with a tailing slash"
22552
22553         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22554                 error "migration fails with two tailing slashes"
22555 }
22556 run_test 230i "lfs migrate -m tolerates trailing slashes"
22557
22558 test_230j() {
22559         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22560         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22561                 skip "Need MDS version at least 2.11.52"
22562
22563         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22564         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22565                 error "create $tfile failed"
22566         cat /etc/passwd > $DIR/$tdir/$tfile
22567
22568         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22569
22570         cmp /etc/passwd $DIR/$tdir/$tfile ||
22571                 error "DoM file mismatch after migration"
22572 }
22573 run_test 230j "DoM file data not changed after dir migration"
22574
22575 test_230k() {
22576         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22577         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22578                 skip "Need MDS version at least 2.11.56"
22579
22580         local total=20
22581         local files_on_starting_mdt=0
22582
22583         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22584         $LFS getdirstripe $DIR/$tdir
22585         for i in $(seq $total); do
22586                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22587                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22588                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22589         done
22590
22591         echo "$files_on_starting_mdt files on MDT0"
22592
22593         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22594         $LFS getdirstripe $DIR/$tdir
22595
22596         files_on_starting_mdt=0
22597         for i in $(seq $total); do
22598                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22599                         error "file $tfile.$i mismatch after migration"
22600                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22601                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22602         done
22603
22604         echo "$files_on_starting_mdt files on MDT1 after migration"
22605         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22606
22607         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22608         $LFS getdirstripe $DIR/$tdir
22609
22610         files_on_starting_mdt=0
22611         for i in $(seq $total); do
22612                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22613                         error "file $tfile.$i mismatch after 2nd migration"
22614                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22615                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22616         done
22617
22618         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22619         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22620
22621         true
22622 }
22623 run_test 230k "file data not changed after dir migration"
22624
22625 test_230l() {
22626         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22627         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22628                 skip "Need MDS version at least 2.11.56"
22629
22630         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22631         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22632                 error "create files under remote dir failed $i"
22633         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22634 }
22635 run_test 230l "readdir between MDTs won't crash"
22636
22637 test_230m() {
22638         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22639         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22640                 skip "Need MDS version at least 2.11.56"
22641
22642         local MDTIDX=1
22643         local mig_dir=$DIR/$tdir/migrate_dir
22644         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22645         local shortstr="b"
22646         local val
22647
22648         echo "Creating files and dirs with xattrs"
22649         test_mkdir $DIR/$tdir
22650         test_mkdir -i0 -c1 $mig_dir
22651         mkdir $mig_dir/dir
22652         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22653                 error "cannot set xattr attr1 on dir"
22654         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22655                 error "cannot set xattr attr2 on dir"
22656         touch $mig_dir/dir/f0
22657         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22658                 error "cannot set xattr attr1 on file"
22659         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22660                 error "cannot set xattr attr2 on file"
22661         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22662         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22663         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22664         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22665         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22666         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22667         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22668         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22669         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22670
22671         echo "Migrating to MDT1"
22672         $LFS migrate -m $MDTIDX $mig_dir ||
22673                 error "fails on migrating dir to MDT1"
22674
22675         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22676         echo "Checking xattrs"
22677         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22678         [ "$val" = $longstr ] ||
22679                 error "expecting xattr1 $longstr on dir, found $val"
22680         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22681         [ "$val" = $shortstr ] ||
22682                 error "expecting xattr2 $shortstr on dir, found $val"
22683         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22684         [ "$val" = $longstr ] ||
22685                 error "expecting xattr1 $longstr on file, found $val"
22686         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22687         [ "$val" = $shortstr ] ||
22688                 error "expecting xattr2 $shortstr on file, found $val"
22689 }
22690 run_test 230m "xattrs not changed after dir migration"
22691
22692 test_230n() {
22693         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22694         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22695                 skip "Need MDS version at least 2.13.53"
22696
22697         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22698         cat /etc/hosts > $DIR/$tdir/$tfile
22699         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22700         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22701
22702         cmp /etc/hosts $DIR/$tdir/$tfile ||
22703                 error "File data mismatch after migration"
22704 }
22705 run_test 230n "Dir migration with mirrored file"
22706
22707 test_230o() {
22708         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22709         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22710                 skip "Need MDS version at least 2.13.52"
22711
22712         local mdts=$(comma_list $(mdts_nodes))
22713         local timeout=100
22714         local restripe_status
22715         local delta
22716         local i
22717
22718         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22719
22720         # in case "crush" hash type is not set
22721         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22722
22723         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22724                            mdt.*MDT0000.enable_dir_restripe)
22725         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22726         stack_trap "do_nodes $mdts $LCTL set_param \
22727                     mdt.*.enable_dir_restripe=$restripe_status"
22728
22729         mkdir $DIR/$tdir
22730         createmany -m $DIR/$tdir/f 100 ||
22731                 error "create files under remote dir failed $i"
22732         createmany -d $DIR/$tdir/d 100 ||
22733                 error "create dirs under remote dir failed $i"
22734
22735         for i in $(seq 2 $MDSCOUNT); do
22736                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22737                 $LFS setdirstripe -c $i $DIR/$tdir ||
22738                         error "split -c $i $tdir failed"
22739                 wait_update $HOSTNAME \
22740                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22741                         error "dir split not finished"
22742                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22743                         awk '/migrate/ {sum += $2} END { print sum }')
22744                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22745                 # delta is around total_files/stripe_count
22746                 (( $delta < 200 / (i - 1) + 4 )) ||
22747                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22748         done
22749 }
22750 run_test 230o "dir split"
22751
22752 test_230p() {
22753         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22754         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22755                 skip "Need MDS version at least 2.13.52"
22756
22757         local mdts=$(comma_list $(mdts_nodes))
22758         local timeout=100
22759         local restripe_status
22760         local delta
22761         local c
22762
22763         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22764
22765         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22766
22767         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22768                            mdt.*MDT0000.enable_dir_restripe)
22769         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22770         stack_trap "do_nodes $mdts $LCTL set_param \
22771                     mdt.*.enable_dir_restripe=$restripe_status"
22772
22773         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22774         createmany -m $DIR/$tdir/f 100 ||
22775                 error "create files under remote dir failed"
22776         createmany -d $DIR/$tdir/d 100 ||
22777                 error "create dirs under remote dir failed"
22778
22779         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22780                 local mdt_hash="crush"
22781
22782                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22783                 $LFS setdirstripe -c $c $DIR/$tdir ||
22784                         error "split -c $c $tdir failed"
22785                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22786                         mdt_hash="$mdt_hash,fixed"
22787                 elif [ $c -eq 1 ]; then
22788                         mdt_hash="none"
22789                 fi
22790                 wait_update $HOSTNAME \
22791                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22792                         error "dir merge not finished"
22793                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22794                         awk '/migrate/ {sum += $2} END { print sum }')
22795                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22796                 # delta is around total_files/stripe_count
22797                 (( delta < 200 / c + 4 )) ||
22798                         error "$delta files migrated >= $((200 / c + 4))"
22799         done
22800 }
22801 run_test 230p "dir merge"
22802
22803 test_230q() {
22804         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22805         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22806                 skip "Need MDS version at least 2.13.52"
22807
22808         local mdts=$(comma_list $(mdts_nodes))
22809         local saved_threshold=$(do_facet mds1 \
22810                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22811         local saved_delta=$(do_facet mds1 \
22812                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22813         local threshold=100
22814         local delta=2
22815         local total=0
22816         local stripe_count=0
22817         local stripe_index
22818         local nr_files
22819         local create
22820
22821         # test with fewer files on ZFS
22822         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22823
22824         stack_trap "do_nodes $mdts $LCTL set_param \
22825                     mdt.*.dir_split_count=$saved_threshold"
22826         stack_trap "do_nodes $mdts $LCTL set_param \
22827                     mdt.*.dir_split_delta=$saved_delta"
22828         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22829         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22830         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22831         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22832         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22833         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22834
22835         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22836         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22837
22838         create=$((threshold * 3 / 2))
22839         while [ $stripe_count -lt $MDSCOUNT ]; do
22840                 createmany -m $DIR/$tdir/f $total $create ||
22841                         error "create sub files failed"
22842                 stat $DIR/$tdir > /dev/null
22843                 total=$((total + create))
22844                 stripe_count=$((stripe_count + delta))
22845                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22846
22847                 wait_update $HOSTNAME \
22848                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22849                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22850
22851                 wait_update $HOSTNAME \
22852                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22853                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22854
22855                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22856                 echo "$nr_files/$total files on MDT$stripe_index after split"
22857                 # allow 10% margin of imbalance with crush hash
22858                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22859                         error "$nr_files files on MDT$stripe_index after split"
22860
22861                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22862                 [ $nr_files -eq $total ] ||
22863                         error "total sub files $nr_files != $total"
22864         done
22865
22866         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22867
22868         echo "fixed layout directory won't auto split"
22869         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22870         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22871                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22872         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22873                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22874 }
22875 run_test 230q "dir auto split"
22876
22877 test_230r() {
22878         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22879         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22880         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22881                 skip "Need MDS version at least 2.13.54"
22882
22883         # maximum amount of local locks:
22884         # parent striped dir - 2 locks
22885         # new stripe in parent to migrate to - 1 lock
22886         # source and target - 2 locks
22887         # Total 5 locks for regular file
22888         mkdir -p $DIR/$tdir
22889         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22890         touch $DIR/$tdir/dir1/eee
22891
22892         # create 4 hardlink for 4 more locks
22893         # Total: 9 locks > RS_MAX_LOCKS (8)
22894         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22895         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22896         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22897         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22898         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22899         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22900         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22901         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22902
22903         cancel_lru_locks mdc
22904
22905         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22906                 error "migrate dir fails"
22907
22908         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22909 }
22910 run_test 230r "migrate with too many local locks"
22911
22912 test_230s() {
22913         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22914                 skip "Need MDS version at least 2.14.52"
22915
22916         local mdts=$(comma_list $(mdts_nodes))
22917         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22918                                 mdt.*MDT0000.enable_dir_restripe)
22919
22920         stack_trap "do_nodes $mdts $LCTL set_param \
22921                     mdt.*.enable_dir_restripe=$restripe_status"
22922
22923         local st
22924         for st in 0 1; do
22925                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22926                 test_mkdir $DIR/$tdir
22927                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22928                         error "$LFS mkdir should return EEXIST if target exists"
22929                 rmdir $DIR/$tdir
22930         done
22931 }
22932 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22933
22934 test_230t()
22935 {
22936         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22937         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22938                 skip "Need MDS version at least 2.14.50"
22939
22940         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22941         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22942         $LFS project -p 1 -s $DIR/$tdir ||
22943                 error "set $tdir project id failed"
22944         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22945                 error "set subdir project id failed"
22946         local pbefore="$($LFS project -d $DIR/$tdir)"
22947         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22948         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22949
22950         local pafter="$($LFS project -d $DIR/$tdir)"
22951         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22952         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22953         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22954
22955         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22956                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22957
22958         # check rename works, even if source parent projid differs (LU-17016)
22959         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22960         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22961
22962         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22963         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22964                 error "subdir failed rename for different source parent projid"
22965         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22966
22967         [[ "$fid_before" == "$fid_after" ]] ||
22968                 error "fid before '$fid_before' != after '$fid_after'"
22969 }
22970 run_test 230t "migrate directory with project ID set"
22971
22972 test_230u()
22973 {
22974         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22975         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22976                 skip "Need MDS version at least 2.14.53"
22977
22978         local count
22979
22980         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22981         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22982         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22983         for i in $(seq 0 $((MDSCOUNT - 1))); do
22984                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22985                 echo "$count dirs migrated to MDT$i"
22986         done
22987         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22988         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22989 }
22990 run_test 230u "migrate directory by QOS"
22991
22992 test_230v()
22993 {
22994         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22995         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22996                 skip "Need MDS version at least 2.14.53"
22997
22998         local count
22999
23000         mkdir $DIR/$tdir || error "mkdir $tdir failed"
23001         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
23002         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
23003         for i in $(seq 0 $((MDSCOUNT - 1))); do
23004                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
23005                 echo "$count subdirs migrated to MDT$i"
23006                 (( i == 3 )) && (( count > 0 )) &&
23007                         error "subdir shouldn't be migrated to MDT3"
23008         done
23009         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
23010         (( count == 3 )) || error "dirs migrated to $count MDTs"
23011 }
23012 run_test 230v "subdir migrated to the MDT where its parent is located"
23013
23014 test_230w() {
23015         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23016         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23017                 skip "Need MDS version at least 2.15.0"
23018
23019         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
23020         createmany -o $DIR/$tdir/f 10 || error "create files failed"
23021         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
23022
23023         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
23024                 error "migrate failed"
23025
23026         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
23027                 error "$tdir stripe count mismatch"
23028
23029         for i in $(seq 0 9); do
23030                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
23031                         error "d$i is striped"
23032         done
23033 }
23034 run_test 230w "non-recursive mode dir migration"
23035
23036 test_230x() {
23037         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23038         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
23039                 skip "Need MDS version at least 2.15.0"
23040
23041         mkdir -p $DIR/$tdir || error "mkdir failed"
23042         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
23043
23044         local mdt_name=$(mdtname_from_index 0)
23045         local low=$(do_facet mds2 $LCTL get_param -n \
23046                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
23047         local high=$(do_facet mds2 $LCTL get_param -n \
23048                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
23049         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
23050         local maxage=$(do_facet mds2 $LCTL get_param -n \
23051                 osp.*$mdt_name-osp-MDT0001.maxage)
23052
23053         stack_trap "do_facet mds2 $LCTL set_param -n \
23054                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
23055                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
23056         stack_trap "do_facet mds2 $LCTL set_param -n \
23057                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23058
23059         do_facet mds2 $LCTL set_param -n \
23060                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23061         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23062         sleep 4
23063         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23064                 error "migrate $tdir should fail"
23065
23066         do_facet mds2 $LCTL set_param -n \
23067                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23068         do_facet mds2 $LCTL set_param -n \
23069                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23070         sleep 4
23071         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23072                 error "migrate failed"
23073         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23074                 error "$tdir stripe count mismatch"
23075 }
23076 run_test 230x "dir migration check space"
23077
23078 test_230y() {
23079         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23080         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23081                 skip "Need MDS version at least 2.15.55.45"
23082
23083         local pid
23084
23085         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23086         $LFS getdirstripe $DIR/$tdir
23087         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23088         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23089         pid=$!
23090         sleep 1
23091
23092         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23093         do_facet mds2 lctl set_param fail_loc=0x1802
23094
23095         wait $pid
23096         do_facet mds2 lctl set_param fail_loc=0
23097         $LFS getdirstripe $DIR/$tdir
23098         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23099         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23100 }
23101 run_test 230y "unlink dir with bad hash type"
23102
23103 test_230z() {
23104         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23105         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23106                 skip "Need MDS version at least 2.15.55.45"
23107
23108         local pid
23109
23110         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23111         $LFS getdirstripe $DIR/$tdir
23112         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23113         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23114         pid=$!
23115         sleep 1
23116
23117         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23118         do_facet mds2 lctl set_param fail_loc=0x1802
23119
23120         wait $pid
23121         do_facet mds2 lctl set_param fail_loc=0
23122         $LFS getdirstripe $DIR/$tdir
23123
23124         # resume migration
23125         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23126                 error "resume migration failed"
23127         $LFS getdirstripe $DIR/$tdir
23128         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23129                 error "migration is not finished"
23130 }
23131 run_test 230z "resume dir migration with bad hash type"
23132
23133 test_231a()
23134 {
23135         # For simplicity this test assumes that max_pages_per_rpc
23136         # is the same across all OSCs
23137         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23138         local bulk_size=$((max_pages * PAGE_SIZE))
23139         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23140                                        head -n 1)
23141
23142         mkdir -p $DIR/$tdir
23143         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23144                 error "failed to set stripe with -S ${brw_size}M option"
23145         stack_trap "rm -rf $DIR/$tdir"
23146
23147         # clear the OSC stats
23148         $LCTL set_param osc.*.stats=0 &>/dev/null
23149         stop_writeback
23150
23151         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23152         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23153                 oflag=direct &>/dev/null || error "dd failed"
23154
23155         sync; sleep 1; sync # just to be safe
23156         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23157         if [ x$nrpcs != "x1" ]; then
23158                 $LCTL get_param osc.*.stats
23159                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23160         fi
23161
23162         start_writeback
23163         # Drop the OSC cache, otherwise we will read from it
23164         cancel_lru_locks osc
23165
23166         # clear the OSC stats
23167         $LCTL set_param osc.*.stats=0 &>/dev/null
23168
23169         # Client reads $bulk_size.
23170         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23171                 iflag=direct &>/dev/null || error "dd failed"
23172
23173         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23174         if [ x$nrpcs != "x1" ]; then
23175                 $LCTL get_param osc.*.stats
23176                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23177         fi
23178 }
23179 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23180
23181 test_231b() {
23182         mkdir -p $DIR/$tdir
23183         stack_trap "rm -rf $DIR/$tdir"
23184         local i
23185         for i in {0..1023}; do
23186                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23187                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23188                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23189         done
23190         sync
23191 }
23192 run_test 231b "must not assert on fully utilized OST request buffer"
23193
23194 test_232a() {
23195         mkdir -p $DIR/$tdir
23196         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23197
23198         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23199         do_facet ost1 $LCTL set_param fail_loc=0x31c
23200
23201         # ignore dd failure
23202         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23203         stack_trap "rm -f $DIR/$tdir/$tfile"
23204
23205         do_facet ost1 $LCTL set_param fail_loc=0
23206         umount_client $MOUNT || error "umount failed"
23207         mount_client $MOUNT || error "mount failed"
23208         stop ost1 || error "cannot stop ost1"
23209         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23210 }
23211 run_test 232a "failed lock should not block umount"
23212
23213 test_232b() {
23214         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23215                 skip "Need MDS version at least 2.10.58"
23216
23217         mkdir -p $DIR/$tdir
23218         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23219         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23220         stack_trap "rm -f $DIR/$tdir/$tfile"
23221         sync
23222         cancel_lru_locks osc
23223
23224         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23225         do_facet ost1 $LCTL set_param fail_loc=0x31c
23226
23227         # ignore failure
23228         $LFS data_version $DIR/$tdir/$tfile || true
23229
23230         do_facet ost1 $LCTL set_param fail_loc=0
23231         umount_client $MOUNT || error "umount failed"
23232         mount_client $MOUNT || error "mount failed"
23233         stop ost1 || error "cannot stop ost1"
23234         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23235 }
23236 run_test 232b "failed data version lock should not block umount"
23237
23238 test_233a() {
23239         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23240                 skip "Need MDS version at least 2.3.64"
23241         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23242
23243         local fid=$($LFS path2fid $MOUNT)
23244
23245         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23246                 error "cannot access $MOUNT using its FID '$fid'"
23247 }
23248 run_test 233a "checking that OBF of the FS root succeeds"
23249
23250 test_233b() {
23251         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23252                 skip "Need MDS version at least 2.5.90"
23253         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23254
23255         local fid=$($LFS path2fid $MOUNT/.lustre)
23256
23257         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23258                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23259
23260         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23261         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23262                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23263 }
23264 run_test 233b "checking that OBF of the FS .lustre succeeds"
23265
23266 test_234() {
23267         local p="$TMP/sanityN-$TESTNAME.parameters"
23268         save_lustre_params client "llite.*.xattr_cache" > $p
23269         lctl set_param llite.*.xattr_cache 1 ||
23270                 skip_env "xattr cache is not supported"
23271
23272         mkdir -p $DIR/$tdir || error "mkdir failed"
23273         touch $DIR/$tdir/$tfile || error "touch failed"
23274         # OBD_FAIL_LLITE_XATTR_ENOMEM
23275         $LCTL set_param fail_loc=0x1405
23276         getfattr -n user.attr $DIR/$tdir/$tfile &&
23277                 error "getfattr should have failed with ENOMEM"
23278         $LCTL set_param fail_loc=0x0
23279         rm -rf $DIR/$tdir
23280
23281         restore_lustre_params < $p
23282         rm -f $p
23283 }
23284 run_test 234 "xattr cache should not crash on ENOMEM"
23285
23286 test_235() {
23287         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23288                 skip "Need MDS version at least 2.4.52"
23289
23290         flock_deadlock $DIR/$tfile
23291         local RC=$?
23292         case $RC in
23293                 0)
23294                 ;;
23295                 124) error "process hangs on a deadlock"
23296                 ;;
23297                 *) error "error executing flock_deadlock $DIR/$tfile"
23298                 ;;
23299         esac
23300 }
23301 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23302
23303 #LU-2935
23304 test_236() {
23305         check_swap_layouts_support
23306
23307         local ref1=/etc/passwd
23308         local ref2=/etc/group
23309         local file1=$DIR/$tdir/f1
23310         local file2=$DIR/$tdir/f2
23311
23312         test_mkdir -c1 $DIR/$tdir
23313         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23314         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23315         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23316         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23317         local fd=$(free_fd)
23318         local cmd="exec $fd<>$file2"
23319         eval $cmd
23320         rm $file2
23321         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23322                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23323         cmd="exec $fd>&-"
23324         eval $cmd
23325         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23326
23327         #cleanup
23328         rm -rf $DIR/$tdir
23329 }
23330 run_test 236 "Layout swap on open unlinked file"
23331
23332 # LU-4659 linkea consistency
23333 test_238() {
23334         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23335                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23336                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23337                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23338
23339         touch $DIR/$tfile
23340         ln $DIR/$tfile $DIR/$tfile.lnk
23341         touch $DIR/$tfile.new
23342         mv $DIR/$tfile.new $DIR/$tfile
23343         local fid1=$($LFS path2fid $DIR/$tfile)
23344         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23345         local path1=$($LFS fid2path $FSNAME "$fid1")
23346         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23347         local path2=$($LFS fid2path $FSNAME "$fid2")
23348         [ $tfile.lnk == $path2 ] ||
23349                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23350         rm -f $DIR/$tfile*
23351 }
23352 run_test 238 "Verify linkea consistency"
23353
23354 test_239A() { # was test_239
23355         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23356                 skip "Need MDS version at least 2.5.60"
23357
23358         local list=$(comma_list $(mdts_nodes))
23359
23360         mkdir -p $DIR/$tdir
23361         createmany -o $DIR/$tdir/f- 5000
23362         unlinkmany $DIR/$tdir/f- 5000
23363         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23364                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23365         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23366                         osp.*MDT*.sync_in_flight" | calc_sum)
23367         [ "$changes" -eq 0 ] || error "$changes not synced"
23368 }
23369 run_test 239A "osp_sync test"
23370
23371 test_239a() { #LU-5297
23372         remote_mds_nodsh && skip "remote MDS with nodsh"
23373
23374         touch $DIR/$tfile
23375         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23376         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23377         chgrp $RUNAS_GID $DIR/$tfile
23378         wait_delete_completed
23379 }
23380 run_test 239a "process invalid osp sync record correctly"
23381
23382 test_239b() { #LU-5297
23383         remote_mds_nodsh && skip "remote MDS with nodsh"
23384
23385         touch $DIR/$tfile1
23386         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23387         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23388         chgrp $RUNAS_GID $DIR/$tfile1
23389         wait_delete_completed
23390         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23391         touch $DIR/$tfile2
23392         chgrp $RUNAS_GID $DIR/$tfile2
23393         wait_delete_completed
23394 }
23395 run_test 239b "process osp sync record with ENOMEM error correctly"
23396
23397 test_240() {
23398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23399         remote_mds_nodsh && skip "remote MDS with nodsh"
23400
23401         mkdir -p $DIR/$tdir
23402
23403         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23404                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23405         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23406                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23407
23408         umount_client $MOUNT || error "umount failed"
23409         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23410         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23411         mount_client $MOUNT || error "failed to mount client"
23412
23413         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23414         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23415 }
23416 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23417
23418 test_241_bio() {
23419         local count=$1
23420         local bsize=$2
23421
23422         for LOOP in $(seq $count); do
23423                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23424                 cancel_lru_locks $OSC || true
23425         done
23426 }
23427
23428 test_241_dio() {
23429         local count=$1
23430         local bsize=$2
23431
23432         for LOOP in $(seq $1); do
23433                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23434                         2>/dev/null
23435         done
23436 }
23437
23438 test_241a() { # was test_241
23439         local bsize=$PAGE_SIZE
23440
23441         (( bsize < 40960 )) && bsize=40960
23442         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23443         ls -la $DIR/$tfile
23444         cancel_lru_locks $OSC
23445         test_241_bio 1000 $bsize &
23446         PID=$!
23447         test_241_dio 1000 $bsize
23448         wait $PID
23449 }
23450 run_test 241a "bio vs dio"
23451
23452 test_241b() {
23453         local bsize=$PAGE_SIZE
23454
23455         (( bsize < 40960 )) && bsize=40960
23456         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23457         ls -la $DIR/$tfile
23458         test_241_dio 1000 $bsize &
23459         PID=$!
23460         test_241_dio 1000 $bsize
23461         wait $PID
23462 }
23463 run_test 241b "dio vs dio"
23464
23465 test_242() {
23466         remote_mds_nodsh && skip "remote MDS with nodsh"
23467
23468         mkdir_on_mdt0 $DIR/$tdir
23469         touch $DIR/$tdir/$tfile
23470
23471         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23472         do_facet mds1 lctl set_param fail_loc=0x105
23473         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23474
23475         do_facet mds1 lctl set_param fail_loc=0
23476         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23477 }
23478 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23479
23480 test_243()
23481 {
23482         test_mkdir $DIR/$tdir
23483         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23484 }
23485 run_test 243 "various group lock tests"
23486
23487 test_244a()
23488 {
23489         test_mkdir $DIR/$tdir
23490         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23491         sendfile_grouplock $DIR/$tdir/$tfile || \
23492                 error "sendfile+grouplock failed"
23493         rm -rf $DIR/$tdir
23494 }
23495 run_test 244a "sendfile with group lock tests"
23496
23497 test_244b()
23498 {
23499         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23500
23501         local threads=50
23502         local size=$((1024*1024))
23503
23504         test_mkdir $DIR/$tdir
23505         for i in $(seq 1 $threads); do
23506                 local file=$DIR/$tdir/file_$((i / 10))
23507                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23508                 local pids[$i]=$!
23509         done
23510         for i in $(seq 1 $threads); do
23511                 wait ${pids[$i]}
23512         done
23513 }
23514 run_test 244b "multi-threaded write with group lock"
23515
23516 test_245a() {
23517         local flagname="multi_mod_rpcs"
23518         local connect_data_name="max_mod_rpcs"
23519         local out
23520
23521         # check if multiple modify RPCs flag is set
23522         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23523                 grep "connect_flags:")
23524         echo "$out"
23525
23526         echo "$out" | grep -qw $flagname
23527         if [ $? -ne 0 ]; then
23528                 echo "connect flag $flagname is not set"
23529                 return
23530         fi
23531
23532         # check if multiple modify RPCs data is set
23533         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23534         echo "$out"
23535
23536         echo "$out" | grep -qw $connect_data_name ||
23537                 error "import should have connect data $connect_data_name"
23538 }
23539 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23540
23541 test_245b() {
23542         local flagname="multi_mod_rpcs"
23543         local connect_data_name="max_mod_rpcs"
23544         local out
23545
23546         remote_mds_nodsh && skip "remote MDS with nodsh"
23547         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23548
23549         # check if multiple modify RPCs flag is set
23550         out=$(do_facet mds1 \
23551               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23552               grep "connect_flags:")
23553         echo "$out"
23554
23555         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23556
23557         # check if multiple modify RPCs data is set
23558         out=$(do_facet mds1 \
23559               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23560
23561         [[ "$out" =~ $connect_data_name ]] ||
23562                 {
23563                         echo "$out"
23564                         error "missing connect data $connect_data_name"
23565                 }
23566 }
23567 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23568
23569 cleanup_247() {
23570         local submount=$1
23571
23572         trap 0
23573         umount_client $submount
23574         rmdir $submount
23575 }
23576
23577 test_247a() {
23578         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23579                 grep -q subtree ||
23580                 skip_env "Fileset feature is not supported"
23581
23582         local submount=${MOUNT}_$tdir
23583
23584         mkdir $MOUNT/$tdir
23585         mkdir -p $submount || error "mkdir $submount failed"
23586         FILESET="$FILESET/$tdir" mount_client $submount ||
23587                 error "mount $submount failed"
23588         trap "cleanup_247 $submount" EXIT
23589         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23590         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23591                 error "read $MOUNT/$tdir/$tfile failed"
23592         cleanup_247 $submount
23593 }
23594 run_test 247a "mount subdir as fileset"
23595
23596 test_247b() {
23597         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23598                 skip_env "Fileset feature is not supported"
23599
23600         local submount=${MOUNT}_$tdir
23601
23602         rm -rf $MOUNT/$tdir
23603         mkdir -p $submount || error "mkdir $submount failed"
23604         SKIP_FILESET=1
23605         FILESET="$FILESET/$tdir" mount_client $submount &&
23606                 error "mount $submount should fail"
23607         rmdir $submount
23608 }
23609 run_test 247b "mount subdir that dose not exist"
23610
23611 test_247c() {
23612         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23613                 skip_env "Fileset feature is not supported"
23614
23615         local submount=${MOUNT}_$tdir
23616
23617         mkdir -p $MOUNT/$tdir/dir1
23618         mkdir -p $submount || error "mkdir $submount failed"
23619         trap "cleanup_247 $submount" EXIT
23620         FILESET="$FILESET/$tdir" mount_client $submount ||
23621                 error "mount $submount failed"
23622         local fid=$($LFS path2fid $MOUNT/)
23623         $LFS fid2path $submount $fid && error "fid2path should fail"
23624         cleanup_247 $submount
23625 }
23626 run_test 247c "running fid2path outside subdirectory root"
23627
23628 test_247d() {
23629         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23630                 skip "Fileset feature is not supported"
23631
23632         local submount=${MOUNT}_$tdir
23633
23634         mkdir -p $MOUNT/$tdir/dir1
23635         mkdir -p $submount || error "mkdir $submount failed"
23636         FILESET="$FILESET/$tdir" mount_client $submount ||
23637                 error "mount $submount failed"
23638         trap "cleanup_247 $submount" EXIT
23639
23640         local td=$submount/dir1
23641         local fid=$($LFS path2fid $td)
23642         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23643
23644         # check that we get the same pathname back
23645         local rootpath
23646         local found
23647         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23648                 echo "$rootpath $fid"
23649                 found=$($LFS fid2path $rootpath "$fid")
23650                 [ -n "$found" ] || error "fid2path should succeed"
23651                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23652         done
23653         # check wrong root path format
23654         rootpath=$submount"_wrong"
23655         found=$($LFS fid2path $rootpath "$fid")
23656         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23657
23658         cleanup_247 $submount
23659 }
23660 run_test 247d "running fid2path inside subdirectory root"
23661
23662 # LU-8037
23663 test_247e() {
23664         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23665                 grep -q subtree ||
23666                 skip "Fileset feature is not supported"
23667
23668         local submount=${MOUNT}_$tdir
23669
23670         mkdir $MOUNT/$tdir
23671         mkdir -p $submount || error "mkdir $submount failed"
23672         FILESET="$FILESET/.." mount_client $submount &&
23673                 error "mount $submount should fail"
23674         rmdir $submount
23675 }
23676 run_test 247e "mount .. as fileset"
23677
23678 test_247f() {
23679         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23680         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23681                 skip "Need at least version 2.14.50.162"
23682         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23683                 skip "Fileset feature is not supported"
23684
23685         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23686         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23687                 error "mkdir remote failed"
23688         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23689                 error "mkdir remote/subdir failed"
23690         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23691                 error "mkdir striped failed"
23692         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23693
23694         local submount=${MOUNT}_$tdir
23695
23696         mkdir -p $submount || error "mkdir $submount failed"
23697         stack_trap "rmdir $submount"
23698
23699         local dir
23700         local fileset=$FILESET
23701         local mdts=$(comma_list $(mdts_nodes))
23702
23703         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23704         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23705                 $tdir/striped/subdir $tdir/striped/.; do
23706                 FILESET="$fileset/$dir" mount_client $submount ||
23707                         error "mount $dir failed"
23708                 umount_client $submount
23709         done
23710 }
23711 run_test 247f "mount striped or remote directory as fileset"
23712
23713 test_subdir_mount_lock()
23714 {
23715         local testdir=$1
23716         local submount=${MOUNT}_$(basename $testdir)
23717
23718         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23719
23720         mkdir -p $submount || error "mkdir $submount failed"
23721         stack_trap "rmdir $submount"
23722
23723         FILESET="$fileset/$testdir" mount_client $submount ||
23724                 error "mount $FILESET failed"
23725         stack_trap "umount $submount"
23726
23727         local mdts=$(comma_list $(mdts_nodes))
23728
23729         local nrpcs
23730
23731         stat $submount > /dev/null || error "stat $submount failed"
23732         cancel_lru_locks $MDC
23733         stat $submount > /dev/null || error "stat $submount failed"
23734         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23735         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23736         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23737         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23738                 awk '/getattr/ {sum += $2} END {print sum}')
23739
23740         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23741 }
23742
23743 test_247g() {
23744         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23745
23746         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23747                 error "mkdir $tdir failed"
23748         test_subdir_mount_lock $tdir
23749 }
23750 run_test 247g "striped directory submount revalidate ROOT from cache"
23751
23752 test_247h() {
23753         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23754         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23755                 skip "Need MDS version at least 2.15.51"
23756
23757         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23758         test_subdir_mount_lock $tdir
23759         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23760         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23761                 error "mkdir $tdir.1 failed"
23762         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23763 }
23764 run_test 247h "remote directory submount revalidate ROOT from cache"
23765
23766 test_248a() {
23767         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23768         [ -z "$fast_read_sav" ] && skip "no fast read support"
23769
23770         # create a large file for fast read verification
23771         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23772
23773         # make sure the file is created correctly
23774         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23775                 { rm -f $DIR/$tfile; skip "file creation error"; }
23776
23777         echo "Test 1: verify that fast read is 4 times faster on cache read"
23778
23779         # small read with fast read enabled
23780         $LCTL set_param -n llite.*.fast_read=1
23781         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23782                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23783                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23784         # small read with fast read disabled
23785         $LCTL set_param -n llite.*.fast_read=0
23786         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23787                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23788                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23789
23790         # verify that fast read is 4 times faster for cache read
23791         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23792                 error_not_in_vm "fast read was not 4 times faster: " \
23793                            "$t_fast vs $t_slow"
23794
23795         echo "Test 2: verify the performance between big and small read"
23796         $LCTL set_param -n llite.*.fast_read=1
23797
23798         # 1k non-cache read
23799         cancel_lru_locks osc
23800         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23801                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23802                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23803
23804         # 1M non-cache read
23805         cancel_lru_locks osc
23806         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23807                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23808                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23809
23810         # verify that big IO is not 4 times faster than small IO
23811         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23812                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23813
23814         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23815         rm -f $DIR/$tfile
23816 }
23817 run_test 248a "fast read verification"
23818
23819 test_248b() {
23820         # Default short_io_bytes=16384, try both smaller and larger sizes.
23821         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23822         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23823         echo "bs=53248 count=113 normal buffered write"
23824         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23825                 error "dd of initial data file failed"
23826         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23827
23828         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23829         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23830                 error "dd with sync normal writes failed"
23831         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23832
23833         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23834         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23835                 error "dd with sync small writes failed"
23836         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23837
23838         cancel_lru_locks osc
23839
23840         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23841         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23842         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23843         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23844                 iflag=direct || error "dd with O_DIRECT small read failed"
23845         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23846         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23847                 error "compare $TMP/$tfile.1 failed"
23848
23849         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23850         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23851
23852         # just to see what the maximum tunable value is, and test parsing
23853         echo "test invalid parameter 2MB"
23854         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23855                 error "too-large short_io_bytes allowed"
23856         echo "test maximum parameter 512KB"
23857         # if we can set a larger short_io_bytes, run test regardless of version
23858         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23859                 # older clients may not allow setting it this large, that's OK
23860                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23861                         skip "Need at least client version 2.13.50"
23862                 error "medium short_io_bytes failed"
23863         fi
23864         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23865         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23866
23867         echo "test large parameter 64KB"
23868         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23869         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23870
23871         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23872         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23873                 error "dd with sync large writes failed"
23874         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23875
23876         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23877         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23878         num=$((113 * 4096 / PAGE_SIZE))
23879         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23880         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23881                 error "dd with O_DIRECT large writes failed"
23882         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23883                 error "compare $DIR/$tfile.3 failed"
23884
23885         cancel_lru_locks osc
23886
23887         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23888         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23889                 error "dd with O_DIRECT large read failed"
23890         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23891                 error "compare $TMP/$tfile.2 failed"
23892
23893         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23894         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23895                 error "dd with O_DIRECT large read failed"
23896         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23897                 error "compare $TMP/$tfile.3 failed"
23898 }
23899 run_test 248b "test short_io read and write for both small and large sizes"
23900
23901 test_248c() {
23902         $LCTL set_param llite.*.read_ahead_stats=c
23903         # This test compares whole file readahead to non-whole file readahead
23904         # The performance should be consistently slightly faster for whole file,
23905         # and the bug caused whole file readahead to be 80-100x slower, but to
23906         # account for possible test system lag, we require whole file to be
23907         # <= 1.5xnon-whole file, and require 3 failures in a row to fail the
23908         # test
23909         local time1
23910         local time2
23911         local whole_mb=$($LCTL get_param -n llite.*.max_read_ahead_whole_mb)
23912         stack_trap "$LCTL set_param llite.*.max_read_ahead_whole_mb=$whole_mb" EXIT
23913         counter=0
23914
23915         while [ $counter -lt 3 ]; do
23916                 # Increment the counter
23917                 ((counter++))
23918
23919                 $LCTL set_param llite.*.max_read_ahead_whole_mb=64
23920                 rm -f $DIR/$tfile
23921                 touch $DIR/$tfile || error "(0) failed to create file"
23922                 # 64 MiB
23923                 $TRUNCATE $DIR/$tfile 67108864 || error "(1) failed to truncate file"
23924                 time1=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23925                 echo "whole file readahead of 64 MiB took $time1 seconds"
23926                 $LCTL get_param llite.*.read_ahead_stats
23927
23928                 $LCTL set_param llite.*.read_ahead_stats=c
23929                 $LCTL set_param llite.*.max_read_ahead_whole_mb=8
23930                 rm -f $DIR/$tfile
23931                 touch $DIR/$tfile || error "(2) failed to create file"
23932                 # 64 MiB
23933                 $TRUNCATE $DIR/$tfile 67108864 || error "(3) failed to create file"
23934                 time2=$(dd if=$DIR/$tfile bs=4K of=/dev/null 2>&1 | awk '/bytes/ {print $8}')
23935                 echo "non-whole file readahead of 64 MiB took $time2 seconds"
23936                 $LCTL get_param llite.*.read_ahead_stats
23937
23938                 # Check if time1 is not more than 1.5 times2
23939                 timecheck=$(echo "$time1 <= (1.5 * $time2)" | bc -l)
23940
23941                 if [[ $timecheck -eq 1 ]]; then
23942                         echo "Test passed on attempt $counter"
23943                         # Exit the loop
23944                         counter=4
23945                 else
23946                         echo "Attempt $counter failed: whole file readahead took: $time1, greater than non: $time2"
23947                 fi
23948         done
23949         if [ $counter -eq 3 ]; then
23950                 error "whole file readahead check failed 3 times in a row, probably not just VM lag"
23951         fi
23952
23953 }
23954 run_test 248c "verify whole file read behavior"
23955
23956 test_249() { # LU-7890
23957         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23958                 skip "Need at least version 2.8.54"
23959
23960         rm -f $DIR/$tfile
23961         $LFS setstripe -c 1 $DIR/$tfile
23962         # Offset 2T == 4k * 512M
23963         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23964                 error "dd to 2T offset failed"
23965 }
23966 run_test 249 "Write above 2T file size"
23967
23968 test_250() {
23969         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23970          && skip "no 16TB file size limit on ZFS"
23971
23972         $LFS setstripe -c 1 $DIR/$tfile
23973         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23974         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23975         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23976         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23977                 conv=notrunc,fsync && error "append succeeded"
23978         return 0
23979 }
23980 run_test 250 "Write above 16T limit"
23981
23982 test_251a() {
23983         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23984
23985         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23986         #Skip once - writing the first stripe will succeed
23987         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23988         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23989                 error "short write happened"
23990
23991         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23992         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23993                 error "short read happened"
23994
23995         rm -f $DIR/$tfile
23996 }
23997 run_test 251a "Handling short read and write correctly"
23998
23999 test_251b() {
24000         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
24001                 error "write $tfile failed"
24002
24003         sleep 2 && echo 12345 >> $DIR/$tfile &
24004
24005         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
24006         $LCTL set_param fail_loc=0x1431 fail_val=5
24007         # seek to 4096, 2 seconds later, file size expand to 4102, and after
24008         # 5 seconds, read 10 bytes, the short read should
24009         # report:
24010         #                start ->+ read_len -> offset_after_read read_count
24011         #     short read: 4096 ->+ 10 -> 4096 0
24012         # not:
24013         #     short read: 4096 ->+ 10 -> 4102 0
24014         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
24015                         awk '/short read/ { print $7 }')
24016         (( off == 4096 )) ||
24017                 error "short read should set offset at 4096, not $off"
24018 }
24019 run_test 251b "short read restore offset correctly"
24020
24021 test_252() {
24022         remote_mds_nodsh && skip "remote MDS with nodsh"
24023         remote_ost_nodsh && skip "remote OST with nodsh"
24024         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
24025                 skip_env "ldiskfs only test"
24026         fi
24027
24028         local tgt
24029         local dev
24030         local out
24031         local uuid
24032         local num
24033         local gen
24034
24035         # check lr_reader on OST0000
24036         tgt=ost1
24037         dev=$(facet_device $tgt)
24038         out=$(do_facet $tgt $LR_READER $dev)
24039         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24040         echo "$out"
24041         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
24042         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
24043                 error "Invalid uuid returned by $LR_READER on target $tgt"
24044         echo -e "uuid returned by $LR_READER is '$uuid'\n"
24045
24046         # check lr_reader -c on MDT0000
24047         tgt=mds1
24048         dev=$(facet_device $tgt)
24049         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
24050                 skip "$LR_READER does not support additional options"
24051         fi
24052         out=$(do_facet $tgt $LR_READER -c $dev)
24053         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24054         echo "$out"
24055         num=$(echo "$out" | grep -c "mdtlov")
24056         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
24057                 error "Invalid number of mdtlov clients returned by $LR_READER"
24058         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
24059
24060         # check lr_reader -cr on MDT0000
24061         out=$(do_facet $tgt $LR_READER -cr $dev)
24062         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
24063         echo "$out"
24064         echo "$out" | grep -q "^reply_data:$" ||
24065                 error "$LR_READER should have returned 'reply_data' section"
24066         num=$(echo "$out" | grep -c "client_generation")
24067         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
24068 }
24069 run_test 252 "check lr_reader tool"
24070
24071 test_253() {
24072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24073         remote_mds_nodsh && skip "remote MDS with nodsh"
24074         remote_mgs_nodsh && skip "remote MGS with nodsh"
24075         check_set_fallocate_or_skip
24076
24077         local ostidx=0
24078         local rc=0
24079         local ost_name=$(ostname_from_index $ostidx)
24080
24081         # on the mdt's osc
24082         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
24083         do_facet $SINGLEMDS $LCTL get_param -n \
24084                 osp.$mdtosc_proc1.reserved_mb_high ||
24085                 skip  "remote MDS does not support reserved_mb_high"
24086
24087         rm -rf $DIR/$tdir
24088         wait_mds_ost_sync
24089         wait_delete_completed
24090         mkdir $DIR/$tdir
24091         stack_trap "rm -rf $DIR/$tdir"
24092
24093         pool_add $TESTNAME || error "Pool creation failed"
24094         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
24095
24096         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
24097                 error "Setstripe failed"
24098
24099         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
24100
24101         local wms=$(ost_watermarks_get $ostidx)
24102
24103         ost_watermarks_set $ostidx 60 50
24104         stack_trap "ost_watermarks_set $ostidx $wms"
24105
24106         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
24107         local size=$((free_kb * 1024))
24108
24109         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
24110                 error "fallocate failed"
24111         sleep_maxage
24112
24113         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24114                         osp.$mdtosc_proc1.prealloc_status)
24115         echo "prealloc_status $oa_status"
24116
24117         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24118                 error "File creation should fail"
24119
24120         #object allocation was stopped, but we still able to append files
24121         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24122                 oflag=append || error "Append failed"
24123
24124         rm -f $DIR/$tdir/$tfile.0
24125         rm -f $DIR/$tdir/fill_ost$ostidx
24126
24127         wait_delete_completed
24128         sleep_maxage
24129
24130         for i in $(seq 10 12); do
24131                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24132                         2>/dev/null || error "File creation failed after rm"
24133         done
24134
24135         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24136                         osp.$mdtosc_proc1.prealloc_status)
24137         echo "prealloc_status $oa_status"
24138
24139         if (( oa_status != 0 )); then
24140                 error "Object allocation still disable after rm"
24141         fi
24142 }
24143 run_test 253 "Check object allocation limit"
24144
24145 test_254() {
24146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24147         remote_mds_nodsh && skip "remote MDS with nodsh"
24148
24149         local mdt=$(facet_svc $SINGLEMDS)
24150
24151         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24152                 skip "MDS does not support changelog_size"
24153
24154         local cl_user
24155
24156         changelog_register || error "changelog_register failed"
24157
24158         changelog_clear 0 || error "changelog_clear failed"
24159
24160         local size1=$(do_facet $SINGLEMDS \
24161                       $LCTL get_param -n mdd.$mdt.changelog_size)
24162         echo "Changelog size $size1"
24163
24164         rm -rf $DIR/$tdir
24165         $LFS mkdir -i 0 $DIR/$tdir
24166         # change something
24167         mkdir -p $DIR/$tdir/pics/2008/zachy
24168         touch $DIR/$tdir/pics/2008/zachy/timestamp
24169         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24170         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24171         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24172         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24173         rm $DIR/$tdir/pics/desktop.jpg
24174
24175         local size2=$(do_facet $SINGLEMDS \
24176                       $LCTL get_param -n mdd.$mdt.changelog_size)
24177         echo "Changelog size after work $size2"
24178
24179         (( $size2 > $size1 )) ||
24180                 error "new Changelog size=$size2 less than old size=$size1"
24181 }
24182 run_test 254 "Check changelog size"
24183
24184 ladvise_no_type()
24185 {
24186         local type=$1
24187         local file=$2
24188
24189         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24190                 awk -F: '{print $2}' | grep $type > /dev/null
24191         if [ $? -ne 0 ]; then
24192                 return 0
24193         fi
24194         return 1
24195 }
24196
24197 ladvise_no_ioctl()
24198 {
24199         local file=$1
24200
24201         lfs ladvise -a willread $file > /dev/null 2>&1
24202         if [ $? -eq 0 ]; then
24203                 return 1
24204         fi
24205
24206         lfs ladvise -a willread $file 2>&1 |
24207                 grep "Inappropriate ioctl for device" > /dev/null
24208         if [ $? -eq 0 ]; then
24209                 return 0
24210         fi
24211         return 1
24212 }
24213
24214 percent() {
24215         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24216 }
24217
24218 # run a random read IO workload
24219 # usage: random_read_iops <filename> <filesize> <iosize>
24220 random_read_iops() {
24221         local file=$1
24222         local fsize=$2
24223         local iosize=${3:-4096}
24224
24225         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24226                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24227 }
24228
24229 drop_file_oss_cache() {
24230         local file="$1"
24231         local nodes="$2"
24232
24233         $LFS ladvise -a dontneed $file 2>/dev/null ||
24234                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24235 }
24236
24237 ladvise_willread_performance()
24238 {
24239         local repeat=10
24240         local average_origin=0
24241         local average_cache=0
24242         local average_ladvise=0
24243
24244         for ((i = 1; i <= $repeat; i++)); do
24245                 echo "Iter $i/$repeat: reading without willread hint"
24246                 cancel_lru_locks osc
24247                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24248                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24249                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24250                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24251
24252                 cancel_lru_locks osc
24253                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24254                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24255                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24256
24257                 cancel_lru_locks osc
24258                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24259                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24260                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24261                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24262                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24263         done
24264         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24265         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24266         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24267
24268         speedup_cache=$(percent $average_cache $average_origin)
24269         speedup_ladvise=$(percent $average_ladvise $average_origin)
24270
24271         echo "Average uncached read: $average_origin"
24272         echo "Average speedup with OSS cached read:" \
24273                 "$average_cache = +$speedup_cache%"
24274         echo "Average speedup with ladvise willread:" \
24275                 "$average_ladvise = +$speedup_ladvise%"
24276
24277         local lowest_speedup=20
24278         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24279                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24280                      "got $speedup_cache%. Skipping ladvise willread check."
24281                 return 0
24282         fi
24283
24284         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24285         # it is still good to run until then to exercise 'ladvise willread'
24286         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24287                 [ "$ost1_FSTYPE" = "zfs" ] &&
24288                 echo "osd-zfs does not support dontneed or drop_caches" &&
24289                 return 0
24290
24291         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24292         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24293                 error_not_in_vm "Speedup with willread is less than " \
24294                         "$lowest_speedup%, got $speedup_ladvise%"
24295 }
24296
24297 test_255a() {
24298         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24299                 skip "lustre < 2.8.54 does not support ladvise "
24300         remote_ost_nodsh && skip "remote OST with nodsh"
24301
24302         stack_trap "rm -f $DIR/$tfile"
24303         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24304
24305         ladvise_no_type willread $DIR/$tfile &&
24306                 skip "willread ladvise is not supported"
24307
24308         ladvise_no_ioctl $DIR/$tfile &&
24309                 skip "ladvise ioctl is not supported"
24310
24311         local size_mb=100
24312         local size=$((size_mb * 1048576))
24313         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24314                 error "dd to $DIR/$tfile failed"
24315
24316         lfs ladvise -a willread $DIR/$tfile ||
24317                 error "Ladvise failed with no range argument"
24318
24319         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24320                 error "Ladvise failed with no -l or -e argument"
24321
24322         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24323                 error "Ladvise failed with only -e argument"
24324
24325         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24326                 error "Ladvise failed with only -l argument"
24327
24328         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24329                 error "End offset should not be smaller than start offset"
24330
24331         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24332                 error "End offset should not be equal to start offset"
24333
24334         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24335                 error "Ladvise failed with overflowing -s argument"
24336
24337         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24338                 error "Ladvise failed with overflowing -e argument"
24339
24340         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24341                 error "Ladvise failed with overflowing -l argument"
24342
24343         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24344                 error "Ladvise succeeded with conflicting -l and -e arguments"
24345
24346         echo "Synchronous ladvise should wait"
24347         local delay=8
24348 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24349         do_nodes $(comma_list $(osts_nodes)) \
24350                 $LCTL set_param fail_val=$delay fail_loc=0x237
24351         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24352                 $LCTL set_param fail_loc=0"
24353
24354         local start_ts=$SECONDS
24355         lfs ladvise -a willread $DIR/$tfile ||
24356                 error "Ladvise failed with no range argument"
24357         local end_ts=$SECONDS
24358         local inteval_ts=$((end_ts - start_ts))
24359
24360         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24361                 error "Synchronous advice didn't wait reply"
24362         fi
24363
24364         echo "Asynchronous ladvise shouldn't wait"
24365         local start_ts=$SECONDS
24366         lfs ladvise -a willread -b $DIR/$tfile ||
24367                 error "Ladvise failed with no range argument"
24368         local end_ts=$SECONDS
24369         local inteval_ts=$((end_ts - start_ts))
24370
24371         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24372                 error "Asynchronous advice blocked"
24373         fi
24374
24375         ladvise_willread_performance
24376 }
24377 run_test 255a "check 'lfs ladvise -a willread'"
24378
24379 facet_meminfo() {
24380         local facet=$1
24381         local info=$2
24382
24383         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24384 }
24385
24386 test_255b() {
24387         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24388                 skip "lustre < 2.8.54 does not support ladvise "
24389         remote_ost_nodsh && skip "remote OST with nodsh"
24390
24391         stack_trap "rm -f $DIR/$tfile"
24392         lfs setstripe -c 1 -i 0 $DIR/$tfile
24393
24394         ladvise_no_type dontneed $DIR/$tfile &&
24395                 skip "dontneed ladvise is not supported"
24396
24397         ladvise_no_ioctl $DIR/$tfile &&
24398                 skip "ladvise ioctl is not supported"
24399
24400         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24401                 [ "$ost1_FSTYPE" = "zfs" ] &&
24402                 skip "zfs-osd does not support 'ladvise dontneed'"
24403
24404         local size_mb=100
24405         local size=$((size_mb * 1048576))
24406         # In order to prevent disturbance of other processes, only check 3/4
24407         # of the memory usage
24408         local kibibytes=$((size_mb * 1024 * 3 / 4))
24409
24410         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24411                 error "dd to $DIR/$tfile failed"
24412
24413         #force write to complete before dropping OST cache & checking memory
24414         sync
24415
24416         local total=$(facet_meminfo ost1 MemTotal)
24417         echo "Total memory: $total KiB"
24418
24419         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24420         local before_read=$(facet_meminfo ost1 Cached)
24421         echo "Cache used before read: $before_read KiB"
24422
24423         lfs ladvise -a willread $DIR/$tfile ||
24424                 error "Ladvise willread failed"
24425         local after_read=$(facet_meminfo ost1 Cached)
24426         echo "Cache used after read: $after_read KiB"
24427
24428         lfs ladvise -a dontneed $DIR/$tfile ||
24429                 error "Ladvise dontneed again failed"
24430         local no_read=$(facet_meminfo ost1 Cached)
24431         echo "Cache used after dontneed ladvise: $no_read KiB"
24432
24433         if [ $total -lt $((before_read + kibibytes)) ]; then
24434                 echo "Memory is too small, abort checking"
24435                 return 0
24436         fi
24437
24438         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24439                 error "Ladvise willread should use more memory" \
24440                         "than $kibibytes KiB"
24441         fi
24442
24443         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24444                 error "Ladvise dontneed should release more memory" \
24445                         "than $kibibytes KiB"
24446         fi
24447 }
24448 run_test 255b "check 'lfs ladvise -a dontneed'"
24449
24450 test_255c() {
24451         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24452                 skip "lustre < 2.10.50 does not support lockahead"
24453
24454         local ost1_imp=$(get_osc_import_name client ost1)
24455         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24456                          cut -d'.' -f2)
24457         local count
24458         local new_count
24459         local difference
24460         local i
24461         local rc
24462
24463         test_mkdir -p $DIR/$tdir
24464         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24465
24466         #test 10 returns only success/failure
24467         i=10
24468         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24469         rc=$?
24470         if [ $rc -eq 255 ]; then
24471                 error "Ladvise test${i} failed, ${rc}"
24472         fi
24473
24474         #test 11 counts lock enqueue requests, all others count new locks
24475         i=11
24476         count=$(do_facet ost1 \
24477                 $LCTL get_param -n ost.OSS.ost.stats)
24478         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24479
24480         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24481         rc=$?
24482         if [ $rc -eq 255 ]; then
24483                 error "Ladvise test${i} failed, ${rc}"
24484         fi
24485
24486         new_count=$(do_facet ost1 \
24487                 $LCTL get_param -n ost.OSS.ost.stats)
24488         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24489                    awk '{ print $2 }')
24490
24491         difference="$((new_count - count))"
24492         if [ $difference -ne $rc ]; then
24493                 error "Ladvise test${i}, bad enqueue count, returned " \
24494                       "${rc}, actual ${difference}"
24495         fi
24496
24497         for i in $(seq 12 21); do
24498                 # If we do not do this, we run the risk of having too many
24499                 # locks and starting lock cancellation while we are checking
24500                 # lock counts.
24501                 cancel_lru_locks osc
24502
24503                 count=$($LCTL get_param -n \
24504                        ldlm.namespaces.$imp_name.lock_unused_count)
24505
24506                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24507                 rc=$?
24508                 if [ $rc -eq 255 ]; then
24509                         error "Ladvise test ${i} failed, ${rc}"
24510                 fi
24511
24512                 new_count=$($LCTL get_param -n \
24513                        ldlm.namespaces.$imp_name.lock_unused_count)
24514                 difference="$((new_count - count))"
24515
24516                 # Test 15 output is divided by 100 to map down to valid return
24517                 if [ $i -eq 15 ]; then
24518                         rc="$((rc * 100))"
24519                 fi
24520
24521                 if [ $difference -ne $rc ]; then
24522                         error "Ladvise test ${i}, bad lock count, returned " \
24523                               "${rc}, actual ${difference}"
24524                 fi
24525         done
24526
24527         #test 22 returns only success/failure
24528         i=22
24529         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24530         rc=$?
24531         if [ $rc -eq 255 ]; then
24532                 error "Ladvise test${i} failed, ${rc}"
24533         fi
24534 }
24535 run_test 255c "suite of ladvise lockahead tests"
24536
24537 test_256() {
24538         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24539         remote_mds_nodsh && skip "remote MDS with nodsh"
24540         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24541         changelog_users $SINGLEMDS | grep "^cl" &&
24542                 skip "active changelog user"
24543
24544         local cl_user
24545         local cat_sl
24546         local mdt_dev
24547
24548         mdt_dev=$(facet_device $SINGLEMDS)
24549         echo $mdt_dev
24550
24551         changelog_register || error "changelog_register failed"
24552
24553         rm -rf $DIR/$tdir
24554         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24555
24556         changelog_clear 0 || error "changelog_clear failed"
24557
24558         # change something
24559         touch $DIR/$tdir/{1..10}
24560
24561         # stop the MDT
24562         stop $SINGLEMDS || error "Fail to stop MDT"
24563
24564         # remount the MDT
24565         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24566                 error "Fail to start MDT"
24567
24568         #after mount new plainllog is used
24569         touch $DIR/$tdir/{11..19}
24570         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24571         stack_trap "rm -f $tmpfile"
24572         cat_sl=$(do_facet $SINGLEMDS "sync; \
24573                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24574                  llog_reader $tmpfile | grep -c type=1064553b")
24575         do_facet $SINGLEMDS llog_reader $tmpfile
24576
24577         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24578
24579         changelog_clear 0 || error "changelog_clear failed"
24580
24581         cat_sl=$(do_facet $SINGLEMDS "sync; \
24582                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24583                  llog_reader $tmpfile | grep -c type=1064553b")
24584
24585         if (( cat_sl == 2 )); then
24586                 error "Empty plain llog was not deleted from changelog catalog"
24587         elif (( cat_sl != 1 )); then
24588                 error "Active plain llog shouldn't be deleted from catalog"
24589         fi
24590 }
24591 run_test 256 "Check llog delete for empty and not full state"
24592
24593 test_257() {
24594         remote_mds_nodsh && skip "remote MDS with nodsh"
24595         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24596                 skip "Need MDS version at least 2.8.55"
24597
24598         test_mkdir $DIR/$tdir
24599
24600         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24601                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24602         stat $DIR/$tdir
24603
24604 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24605         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24606         local facet=mds$((mdtidx + 1))
24607         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24608         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24609
24610         stop $facet || error "stop MDS failed"
24611         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24612                 error "start MDS fail"
24613         wait_recovery_complete $facet
24614 }
24615 run_test 257 "xattr locks are not lost"
24616
24617 # Verify we take the i_mutex when security requires it
24618 test_258a() {
24619 #define OBD_FAIL_IMUTEX_SEC 0x141c
24620         $LCTL set_param fail_loc=0x141c
24621         touch $DIR/$tfile
24622         chmod u+s $DIR/$tfile
24623         chmod a+rwx $DIR/$tfile
24624         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24625         RC=$?
24626         if [ $RC -ne 0 ]; then
24627                 error "error, failed to take i_mutex, rc=$?"
24628         fi
24629         rm -f $DIR/$tfile
24630 }
24631 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24632
24633 # Verify we do NOT take the i_mutex in the normal case
24634 test_258b() {
24635 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24636         $LCTL set_param fail_loc=0x141d
24637         touch $DIR/$tfile
24638         chmod a+rwx $DIR
24639         chmod a+rw $DIR/$tfile
24640         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24641         RC=$?
24642         if [ $RC -ne 0 ]; then
24643                 error "error, took i_mutex unnecessarily, rc=$?"
24644         fi
24645         rm -f $DIR/$tfile
24646
24647 }
24648 run_test 258b "verify i_mutex security behavior"
24649
24650 test_259() {
24651         local file=$DIR/$tfile
24652         local before
24653         local after
24654
24655         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24656
24657         stack_trap "rm -f $file" EXIT
24658
24659         wait_delete_completed
24660         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24661         echo "before: $before"
24662
24663         $LFS setstripe -i 0 -c 1 $file
24664         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24665         sync_all_data
24666         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24667         echo "after write: $after"
24668
24669 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24670         do_facet ost1 $LCTL set_param fail_loc=0x2301
24671         $TRUNCATE $file 0
24672         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24673         echo "after truncate: $after"
24674
24675         stop ost1
24676         do_facet ost1 $LCTL set_param fail_loc=0
24677         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24678         sleep 2
24679         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24680         echo "after restart: $after"
24681         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24682                 error "missing truncate?"
24683
24684         return 0
24685 }
24686 run_test 259 "crash at delayed truncate"
24687
24688 test_260() {
24689 #define OBD_FAIL_MDC_CLOSE               0x806
24690         $LCTL set_param fail_loc=0x80000806
24691         touch $DIR/$tfile
24692
24693 }
24694 run_test 260 "Check mdc_close fail"
24695
24696 ### Data-on-MDT sanity tests ###
24697 test_270a() {
24698         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24699                 skip "Need MDS version at least 2.10.55 for DoM"
24700
24701         # create DoM file
24702         local dom=$DIR/$tdir/dom_file
24703         local tmp=$DIR/$tdir/tmp_file
24704
24705         mkdir_on_mdt0 $DIR/$tdir
24706
24707         # basic checks for DoM component creation
24708         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24709                 error "Can set MDT layout to non-first entry"
24710
24711         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24712                 error "Can define multiple entries as MDT layout"
24713
24714         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24715
24716         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24717         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24718         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24719
24720         local mdtidx=$($LFS getstripe -m $dom)
24721         local mdtname=MDT$(printf %04x $mdtidx)
24722         local facet=mds$((mdtidx + 1))
24723         local space_check=1
24724
24725         # Skip free space checks with ZFS
24726         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24727
24728         # write
24729         sync
24730         local size_tmp=$((65536 * 3))
24731         local mdtfree1=$(do_facet $facet \
24732                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24733
24734         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24735         # check also direct IO along write
24736         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24737         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24738         sync
24739         cmp $tmp $dom || error "file data is different"
24740         [ $(stat -c%s $dom) == $size_tmp ] ||
24741                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24742         if [ $space_check == 1 ]; then
24743                 local mdtfree2=$(do_facet $facet \
24744                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24745
24746                 # increase in usage from by $size_tmp
24747                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24748                         error "MDT free space wrong after write: " \
24749                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24750         fi
24751
24752         # truncate
24753         local size_dom=10000
24754
24755         $TRUNCATE $dom $size_dom
24756         [ $(stat -c%s $dom) == $size_dom ] ||
24757                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24758         if [ $space_check == 1 ]; then
24759                 mdtfree1=$(do_facet $facet \
24760                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24761                 # decrease in usage from $size_tmp to new $size_dom
24762                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24763                   $(((size_tmp - size_dom) / 1024)) ] ||
24764                         error "MDT free space is wrong after truncate: " \
24765                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24766         fi
24767
24768         # append
24769         cat $tmp >> $dom
24770         sync
24771         size_dom=$((size_dom + size_tmp))
24772         [ $(stat -c%s $dom) == $size_dom ] ||
24773                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24774         if [ $space_check == 1 ]; then
24775                 mdtfree2=$(do_facet $facet \
24776                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24777                 # increase in usage by $size_tmp from previous
24778                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24779                         error "MDT free space is wrong after append: " \
24780                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24781         fi
24782
24783         # delete
24784         rm $dom
24785         if [ $space_check == 1 ]; then
24786                 mdtfree1=$(do_facet $facet \
24787                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24788                 # decrease in usage by $size_dom from previous
24789                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24790                         error "MDT free space is wrong after removal: " \
24791                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24792         fi
24793
24794         # combined striping
24795         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24796                 error "Can't create DoM + OST striping"
24797
24798         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24799         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24800         # check also direct IO along write
24801         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24802         sync
24803         cmp $tmp $dom || error "file data is different"
24804         [ $(stat -c%s $dom) == $size_tmp ] ||
24805                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24806         rm $dom $tmp
24807
24808         return 0
24809 }
24810 run_test 270a "DoM: basic functionality tests"
24811
24812 test_270b() {
24813         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24814                 skip "Need MDS version at least 2.10.55"
24815
24816         local dom=$DIR/$tdir/dom_file
24817         local max_size=1048576
24818
24819         mkdir -p $DIR/$tdir
24820         $LFS setstripe -E $max_size -L mdt $dom
24821
24822         # truncate over the limit
24823         $TRUNCATE $dom $(($max_size + 1)) &&
24824                 error "successful truncate over the maximum size"
24825         # write over the limit
24826         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24827                 error "successful write over the maximum size"
24828         # append over the limit
24829         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24830         echo "12345" >> $dom && error "successful append over the maximum size"
24831         rm $dom
24832
24833         return 0
24834 }
24835 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24836
24837 test_270c() {
24838         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24839                 skip "Need MDS version at least 2.10.55"
24840
24841         mkdir -p $DIR/$tdir
24842         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24843
24844         # check files inherit DoM EA
24845         touch $DIR/$tdir/first
24846         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24847                 error "bad pattern"
24848         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24849                 error "bad stripe count"
24850         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24851                 error "bad stripe size"
24852
24853         # check directory inherits DoM EA and uses it as default
24854         mkdir $DIR/$tdir/subdir
24855         touch $DIR/$tdir/subdir/second
24856         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24857                 error "bad pattern in sub-directory"
24858         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24859                 error "bad stripe count in sub-directory"
24860         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24861                 error "bad stripe size in sub-directory"
24862         return 0
24863 }
24864 run_test 270c "DoM: DoM EA inheritance tests"
24865
24866 test_270d() {
24867         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24868                 skip "Need MDS version at least 2.10.55"
24869
24870         mkdir -p $DIR/$tdir
24871         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24872
24873         # inherit default DoM striping
24874         mkdir $DIR/$tdir/subdir
24875         touch $DIR/$tdir/subdir/f1
24876
24877         # change default directory striping
24878         $LFS setstripe -c 1 $DIR/$tdir/subdir
24879         touch $DIR/$tdir/subdir/f2
24880         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24881                 error "wrong default striping in file 2"
24882         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24883                 error "bad pattern in file 2"
24884         return 0
24885 }
24886 run_test 270d "DoM: change striping from DoM to RAID0"
24887
24888 test_270e() {
24889         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24890                 skip "Need MDS version at least 2.10.55"
24891
24892         mkdir -p $DIR/$tdir/dom
24893         mkdir -p $DIR/$tdir/norm
24894         DOMFILES=20
24895         NORMFILES=10
24896         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24897         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24898
24899         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24900         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24901
24902         # find DoM files by layout
24903         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24904         [ $NUM -eq  $DOMFILES ] ||
24905                 error "lfs find -L: found $NUM, expected $DOMFILES"
24906         echo "Test 1: lfs find 20 DOM files by layout: OK"
24907
24908         # there should be 1 dir with default DOM striping
24909         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24910         [ $NUM -eq  1 ] ||
24911                 error "lfs find -L: found $NUM, expected 1 dir"
24912         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24913
24914         # find DoM files by stripe size
24915         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24916         [ $NUM -eq  $DOMFILES ] ||
24917                 error "lfs find -S: found $NUM, expected $DOMFILES"
24918         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24919
24920         # find files by stripe offset except DoM files
24921         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24922         [ $NUM -eq  $NORMFILES ] ||
24923                 error "lfs find -i: found $NUM, expected $NORMFILES"
24924         echo "Test 5: lfs find no DOM files by stripe index: OK"
24925         return 0
24926 }
24927 run_test 270e "DoM: lfs find with DoM files test"
24928
24929 test_270f() {
24930         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24931                 skip "Need MDS version at least 2.10.55"
24932
24933         local mdtname=${FSNAME}-MDT0000-mdtlov
24934         local dom=$DIR/$tdir/dom_file
24935         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24936                                                 lod.$mdtname.dom_stripesize)
24937         local dom_limit=131072
24938
24939         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24940         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24941                                                 lod.$mdtname.dom_stripesize)
24942         [ ${dom_limit} -eq ${dom_current} ] ||
24943                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24944
24945         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24946         $LFS setstripe -d $DIR/$tdir
24947         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24948                 error "Can't set directory default striping"
24949
24950         # exceed maximum stripe size
24951         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24952                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24953         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24954                 error "Able to create DoM component size more than LOD limit"
24955
24956         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24957         dom_current=$(do_facet mds1 $LCTL get_param -n \
24958                                                 lod.$mdtname.dom_stripesize)
24959         [ 0 -eq ${dom_current} ] ||
24960                 error "Can't set zero DoM stripe limit"
24961         rm $dom
24962
24963         # attempt to create DoM file on server with disabled DoM should
24964         # remove DoM entry from layout and be succeed
24965         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24966                 error "Can't create DoM file (DoM is disabled)"
24967         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24968                 error "File has DoM component while DoM is disabled"
24969         rm $dom
24970
24971         # attempt to create DoM file with only DoM stripe should return error
24972         $LFS setstripe -E $dom_limit -L mdt $dom &&
24973                 error "Able to create DoM-only file while DoM is disabled"
24974
24975         # too low values to be aligned with smallest stripe size 64K
24976         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24977         dom_current=$(do_facet mds1 $LCTL get_param -n \
24978                                                 lod.$mdtname.dom_stripesize)
24979         [ 30000 -eq ${dom_current} ] &&
24980                 error "Can set too small DoM stripe limit"
24981
24982         # 64K is a minimal stripe size in Lustre, expect limit of that size
24983         [ 65536 -eq ${dom_current} ] ||
24984                 error "Limit is not set to 64K but ${dom_current}"
24985
24986         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24987         dom_current=$(do_facet mds1 $LCTL get_param -n \
24988                                                 lod.$mdtname.dom_stripesize)
24989         echo $dom_current
24990         [ 2147483648 -eq ${dom_current} ] &&
24991                 error "Can set too large DoM stripe limit"
24992
24993         do_facet mds1 $LCTL set_param -n \
24994                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24995         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24996                 error "Can't create DoM component size after limit change"
24997         do_facet mds1 $LCTL set_param -n \
24998                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24999         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
25000                 error "Can't create DoM file after limit decrease"
25001         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
25002                 error "Can create big DoM component after limit decrease"
25003         touch ${dom}_def ||
25004                 error "Can't create file with old default layout"
25005
25006         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
25007         return 0
25008 }
25009 run_test 270f "DoM: maximum DoM stripe size checks"
25010
25011 test_270g() {
25012         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
25013                 skip "Need MDS version at least 2.13.52"
25014         local dom=$DIR/$tdir/$tfile
25015
25016         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25017         local lodname=${FSNAME}-MDT0000-mdtlov
25018
25019         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25020         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
25021         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
25022         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25023
25024         local dom_limit=1024
25025         local dom_threshold="50%"
25026
25027         $LFS setstripe -d $DIR/$tdir
25028         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
25029                 error "Can't set directory default striping"
25030
25031         do_facet mds1 $LCTL set_param -n \
25032                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
25033         # set 0 threshold and create DOM file to change tunable stripesize
25034         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
25035         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25036                 error "Failed to create $dom file"
25037         # now tunable dom_cur_stripesize should reach maximum
25038         local dom_current=$(do_facet mds1 $LCTL get_param -n \
25039                                         lod.${lodname}.dom_stripesize_cur_kb)
25040         [[ $dom_current == $dom_limit ]] ||
25041                 error "Current DOM stripesize is not maximum"
25042         rm $dom
25043
25044         # set threshold for further tests
25045         do_facet mds1 $LCTL set_param -n \
25046                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
25047         echo "DOM threshold is $dom_threshold free space"
25048         local dom_def
25049         local dom_set
25050         # Spoof bfree to exceed threshold
25051         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
25052         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
25053         for spfree in 40 20 0 15 30 55; do
25054                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
25055                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
25056                         error "Failed to create $dom file"
25057                 dom_def=$(do_facet mds1 $LCTL get_param -n \
25058                                         lod.${lodname}.dom_stripesize_cur_kb)
25059                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
25060                 [[ $dom_def != $dom_current ]] ||
25061                         error "Default stripe size was not changed"
25062                 if (( spfree > 0 )) ; then
25063                         dom_set=$($LFS getstripe -S $dom)
25064                         (( dom_set == dom_def * 1024 )) ||
25065                                 error "DOM component size is still old"
25066                 else
25067                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25068                                 error "DoM component is set with no free space"
25069                 fi
25070                 rm $dom
25071                 dom_current=$dom_def
25072         done
25073 }
25074 run_test 270g "DoM: default DoM stripe size depends on free space"
25075
25076 test_270h() {
25077         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
25078                 skip "Need MDS version at least 2.13.53"
25079
25080         local mdtname=${FSNAME}-MDT0000-mdtlov
25081         local dom=$DIR/$tdir/$tfile
25082         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
25083
25084         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
25085         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
25086
25087         $LFS mkdir -i 0 -c 1 $DIR/$tdir
25088         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
25089                 error "can't create OST file"
25090         # mirrored file with DOM entry in the second mirror
25091         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
25092                 error "can't create mirror with DoM component"
25093
25094         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
25095
25096         # DOM component in the middle and has other enries in the same mirror,
25097         # should succeed but lost DoM component
25098         $LFS setstripe --copy=${dom}_1 $dom ||
25099                 error "Can't create file from OST|DOM mirror layout"
25100         # check new file has no DoM layout after all
25101         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
25102                 error "File has DoM component while DoM is disabled"
25103 }
25104 run_test 270h "DoM: DoM stripe removal when disabled on server"
25105
25106 test_270i() {
25107         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
25108                 skip "Need MDS version at least 2.14.54"
25109
25110         mkdir $DIR/$tdir
25111         # DoM with plain layout
25112         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25113                 error "default plain layout with DoM must fail"
25114         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25115                 error "setstripe plain file layout with DoM must fail"
25116         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25117                 error "default DoM layout with bad striping must fail"
25118         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25119                 error "setstripe to DoM layout with bad striping must fail"
25120         return 0
25121 }
25122 run_test 270i "DoM: setting invalid DoM striping should fail"
25123
25124 test_270j() {
25125         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25126                 skip "Need MDS version at least 2.15.55.203"
25127
25128         local dom=$DIR/$tdir/$tfile
25129         local odv
25130         local ndv
25131
25132         mkdir -p $DIR/$tdir
25133
25134         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25135
25136         odv=$($LFS data_version $dom)
25137         chmod 666 $dom
25138         mv $dom ${dom}_moved
25139         link ${dom}_moved $dom
25140         setfattr -n user.attrx -v "some_attr" $dom
25141         ndv=$($LFS data_version $dom)
25142         (( $ndv == $odv )) ||
25143                 error "data version was changed by metadata operations"
25144
25145         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25146                 error "failed to write data into $dom"
25147         cancel_lru_locks mdc
25148         ndv=$($LFS data_version $dom)
25149         (( $ndv != $odv )) ||
25150                 error "data version wasn't changed on write"
25151
25152         odv=$ndv
25153         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25154         ndv=$($LFS data_version $dom)
25155         (( $ndv != $odv )) ||
25156                 error "data version wasn't changed on truncate down"
25157
25158         odv=$ndv
25159         $TRUNCATE $dom 25000
25160         ndv=$($LFS data_version $dom)
25161         (( $ndv != $odv )) ||
25162                 error "data version wasn't changed on truncate up"
25163
25164         # check also fallocate for ldiskfs
25165         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25166                 odv=$ndv
25167                 fallocate -l 1048576 $dom
25168                 ndv=$($LFS data_version $dom)
25169                 (( $ndv != $odv )) ||
25170                         error "data version wasn't changed on fallocate"
25171
25172                 odv=$ndv
25173                 fallocate -p --offset 4096 -l 4096 $dom
25174                 ndv=$($LFS data_version $dom)
25175                 (( $ndv != $odv )) ||
25176                         error "data version wasn't changed on fallocate punch"
25177         fi
25178 }
25179 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25180
25181 test_271a() {
25182         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25183                 skip "Need MDS version at least 2.10.55"
25184
25185         local dom=$DIR/$tdir/dom
25186
25187         mkdir -p $DIR/$tdir
25188
25189         $LFS setstripe -E 1024K -L mdt $dom
25190
25191         lctl set_param -n mdc.*.stats=clear
25192         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25193         cat $dom > /dev/null
25194         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25195         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25196         ls $dom
25197         rm -f $dom
25198 }
25199 run_test 271a "DoM: data is cached for read after write"
25200
25201 test_271b() {
25202         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25203                 skip "Need MDS version at least 2.10.55"
25204
25205         local dom=$DIR/$tdir/dom
25206
25207         mkdir -p $DIR/$tdir
25208
25209         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25210
25211         lctl set_param -n mdc.*.stats=clear
25212         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25213         cancel_lru_locks mdc
25214         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25215         # second stat to check size is cached on client
25216         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25217         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25218         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25219         rm -f $dom
25220 }
25221 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25222
25223 test_271ba() {
25224         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25225                 skip "Need MDS version at least 2.10.55"
25226
25227         local dom=$DIR/$tdir/dom
25228
25229         mkdir -p $DIR/$tdir
25230
25231         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25232
25233         lctl set_param -n mdc.*.stats=clear
25234         lctl set_param -n osc.*.stats=clear
25235         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25236         cancel_lru_locks mdc
25237         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25238         # second stat to check size is cached on client
25239         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25240         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25241         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25242         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25243         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25244         rm -f $dom
25245 }
25246 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25247
25248
25249 get_mdc_stats() {
25250         local mdtidx=$1
25251         local param=$2
25252         local mdt=MDT$(printf %04x $mdtidx)
25253
25254         if [ -z $param ]; then
25255                 lctl get_param -n mdc.*$mdt*.stats
25256         else
25257                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25258         fi
25259 }
25260
25261 test_271c() {
25262         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25263                 skip "Need MDS version at least 2.10.55"
25264
25265         local dom=$DIR/$tdir/dom
25266
25267         mkdir -p $DIR/$tdir
25268
25269         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25270
25271         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25272         local facet=mds$((mdtidx + 1))
25273
25274         cancel_lru_locks mdc
25275         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25276         createmany -o $dom 1000
25277         lctl set_param -n mdc.*.stats=clear
25278         smalliomany -w $dom 1000 200
25279         get_mdc_stats $mdtidx
25280         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25281         # Each file has 1 open, 1 IO enqueues, total 2000
25282         # but now we have also +1 getxattr for security.capability, total 3000
25283         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25284         unlinkmany $dom 1000
25285
25286         cancel_lru_locks mdc
25287         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25288         createmany -o $dom 1000
25289         lctl set_param -n mdc.*.stats=clear
25290         smalliomany -w $dom 1000 200
25291         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25292         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25293         # for OPEN and IO lock.
25294         [ $((enq - enq_2)) -ge 1000 ] ||
25295                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25296         unlinkmany $dom 1000
25297         return 0
25298 }
25299 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25300
25301 cleanup_271def_tests() {
25302         trap 0
25303         rm -f $1
25304 }
25305
25306 test_271d() {
25307         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25308                 skip "Need MDS version at least 2.10.57"
25309
25310         local dom=$DIR/$tdir/dom
25311         local tmp=$TMP/$tfile
25312         trap "cleanup_271def_tests $tmp" EXIT
25313
25314         mkdir -p $DIR/$tdir
25315
25316         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25317
25318         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25319
25320         cancel_lru_locks mdc
25321         dd if=/dev/urandom of=$tmp bs=1000 count=1
25322         dd if=$tmp of=$dom bs=1000 count=1
25323         cancel_lru_locks mdc
25324
25325         cat /etc/hosts >> $tmp
25326         lctl set_param -n mdc.*.stats=clear
25327
25328         # append data to the same file it should update local page
25329         echo "Append to the same page"
25330         cat /etc/hosts >> $dom
25331         local num=$(get_mdc_stats $mdtidx ost_read)
25332         local ra=$(get_mdc_stats $mdtidx req_active)
25333         local rw=$(get_mdc_stats $mdtidx req_waittime)
25334
25335         [ -z $num ] || error "$num READ RPC occured"
25336         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25337         echo "... DONE"
25338
25339         # compare content
25340         cmp $tmp $dom || error "file miscompare"
25341
25342         cancel_lru_locks mdc
25343         lctl set_param -n mdc.*.stats=clear
25344
25345         echo "Open and read file"
25346         cat $dom > /dev/null
25347         local num=$(get_mdc_stats $mdtidx ost_read)
25348         local ra=$(get_mdc_stats $mdtidx req_active)
25349         local rw=$(get_mdc_stats $mdtidx req_waittime)
25350
25351         [ -z $num ] || error "$num READ RPC occured"
25352         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25353         echo "... DONE"
25354
25355         # compare content
25356         cmp $tmp $dom || error "file miscompare"
25357
25358         return 0
25359 }
25360 run_test 271d "DoM: read on open (1K file in reply buffer)"
25361
25362 test_271f() {
25363         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25364                 skip "Need MDS version at least 2.10.57"
25365
25366         local dom=$DIR/$tdir/dom
25367         local tmp=$TMP/$tfile
25368         trap "cleanup_271def_tests $tmp" EXIT
25369
25370         mkdir -p $DIR/$tdir
25371
25372         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25373
25374         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25375
25376         cancel_lru_locks mdc
25377         dd if=/dev/urandom of=$tmp bs=265000 count=1
25378         dd if=$tmp of=$dom bs=265000 count=1
25379         cancel_lru_locks mdc
25380         cat /etc/hosts >> $tmp
25381         lctl set_param -n mdc.*.stats=clear
25382
25383         echo "Append to the same page"
25384         cat /etc/hosts >> $dom
25385         local num=$(get_mdc_stats $mdtidx ost_read)
25386         local ra=$(get_mdc_stats $mdtidx req_active)
25387         local rw=$(get_mdc_stats $mdtidx req_waittime)
25388
25389         [ -z $num ] || error "$num READ RPC occured"
25390         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25391         echo "... DONE"
25392
25393         # compare content
25394         cmp $tmp $dom || error "file miscompare"
25395
25396         cancel_lru_locks mdc
25397         lctl set_param -n mdc.*.stats=clear
25398
25399         echo "Open and read file"
25400         cat $dom > /dev/null
25401         local num=$(get_mdc_stats $mdtidx ost_read)
25402         local ra=$(get_mdc_stats $mdtidx req_active)
25403         local rw=$(get_mdc_stats $mdtidx req_waittime)
25404
25405         [ -z $num ] && num=0
25406         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25407         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25408         echo "... DONE"
25409
25410         # compare content
25411         cmp $tmp $dom || error "file miscompare"
25412
25413         return 0
25414 }
25415 run_test 271f "DoM: read on open (200K file and read tail)"
25416
25417 test_271g() {
25418         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25419                 skip "Skipping due to old client or server version"
25420
25421         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25422         # to get layout
25423         $CHECKSTAT -t file $DIR1/$tfile
25424
25425         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25426         MULTIOP_PID=$!
25427         sleep 1
25428         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25429         $LCTL set_param fail_loc=0x80000314
25430         rm $DIR1/$tfile || error "Unlink fails"
25431         RC=$?
25432         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25433         [ $RC -eq 0 ] || error "Failed write to stale object"
25434 }
25435 run_test 271g "Discard DoM data vs client flush race"
25436
25437 test_272a() {
25438         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25439                 skip "Need MDS version at least 2.11.50"
25440
25441         local dom=$DIR/$tdir/dom
25442         mkdir -p $DIR/$tdir
25443
25444         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25445         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25446                 error "failed to write data into $dom"
25447         local old_md5=$(md5sum $dom)
25448
25449         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25450                 error "failed to migrate to the same DoM component"
25451
25452         local new_md5=$(md5sum $dom)
25453
25454         [ "$old_md5" == "$new_md5" ] ||
25455                 error "md5sum differ: $old_md5, $new_md5"
25456
25457         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25458                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25459 }
25460 run_test 272a "DoM migration: new layout with the same DOM component"
25461
25462 test_272b() {
25463         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25464                 skip "Need MDS version at least 2.11.50"
25465
25466         local dom=$DIR/$tdir/dom
25467         mkdir -p $DIR/$tdir
25468         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25469         stack_trap "rm -rf $DIR/$tdir"
25470
25471         local mdtidx=$($LFS getstripe -m $dom)
25472         local mdtname=MDT$(printf %04x $mdtidx)
25473         local facet=mds$((mdtidx + 1))
25474
25475         local mdtfree1=$(do_facet $facet \
25476                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25477         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25478                 error "failed to write data into $dom"
25479         local old_md5=$(md5sum $dom)
25480         cancel_lru_locks mdc
25481         local mdtfree1=$(do_facet $facet \
25482                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25483
25484         $LFS migrate -c2 $dom ||
25485                 error "failed to migrate to the new composite layout"
25486         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25487                 error "MDT stripe was not removed"
25488         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25489                 error "$dir1 shouldn't have DATAVER EA"
25490
25491         cancel_lru_locks mdc
25492         local new_md5=$(md5sum $dom)
25493         [ "$old_md5" == "$new_md5" ] ||
25494                 error "$old_md5 != $new_md5"
25495
25496         # Skip free space checks with ZFS
25497         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25498                 local mdtfree2=$(do_facet $facet \
25499                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25500                 [ $mdtfree2 -gt $mdtfree1 ] ||
25501                         error "MDT space is not freed after migration"
25502         fi
25503         return 0
25504 }
25505 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25506
25507 test_272c() {
25508         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25509                 skip "Need MDS version at least 2.11.50"
25510
25511         local dom=$DIR/$tdir/$tfile
25512         mkdir -p $DIR/$tdir
25513         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25514         stack_trap "rm -rf $DIR/$tdir"
25515
25516         local mdtidx=$($LFS getstripe -m $dom)
25517         local mdtname=MDT$(printf %04x $mdtidx)
25518         local facet=mds$((mdtidx + 1))
25519
25520         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25521                 error "failed to write data into $dom"
25522         local old_md5=$(md5sum $dom)
25523         cancel_lru_locks mdc
25524         local mdtfree1=$(do_facet $facet \
25525                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25526
25527         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25528                 error "failed to migrate to the new composite layout"
25529         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25530                 error "MDT stripe was not removed"
25531
25532         cancel_lru_locks mdc
25533         local new_md5=$(md5sum $dom)
25534         [ "$old_md5" == "$new_md5" ] ||
25535                 error "$old_md5 != $new_md5"
25536
25537         # Skip free space checks with ZFS
25538         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25539                 local mdtfree2=$(do_facet $facet \
25540                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25541                 [ $mdtfree2 -gt $mdtfree1 ] ||
25542                         error "MDS space is not freed after migration"
25543         fi
25544         return 0
25545 }
25546 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25547
25548 test_272d() {
25549         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25550                 skip "Need MDS version at least 2.12.55"
25551
25552         local dom=$DIR/$tdir/$tfile
25553         mkdir -p $DIR/$tdir
25554         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25555
25556         local mdtidx=$($LFS getstripe -m $dom)
25557         local mdtname=MDT$(printf %04x $mdtidx)
25558         local facet=mds$((mdtidx + 1))
25559
25560         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25561                 error "failed to write data into $dom"
25562         local old_md5=$(md5sum $dom)
25563         cancel_lru_locks mdc
25564         local mdtfree1=$(do_facet $facet \
25565                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25566
25567         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25568                 error "failed mirroring to the new composite layout"
25569         $LFS mirror resync $dom ||
25570                 error "failed mirror resync"
25571         $LFS mirror split --mirror-id 1 -d $dom ||
25572                 error "failed mirror split"
25573
25574         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25575                 error "MDT stripe was not removed"
25576
25577         cancel_lru_locks mdc
25578         local new_md5=$(md5sum $dom)
25579         [ "$old_md5" == "$new_md5" ] ||
25580                 error "$old_md5 != $new_md5"
25581
25582         # Skip free space checks with ZFS
25583         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25584                 local mdtfree2=$(do_facet $facet \
25585                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25586                 [ $mdtfree2 -gt $mdtfree1 ] ||
25587                         error "MDS space is not freed after DOM mirror deletion"
25588         fi
25589         return 0
25590 }
25591 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25592
25593 test_272e() {
25594         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25595                 skip "Need MDS version at least 2.12.55"
25596
25597         local dom=$DIR/$tdir/$tfile
25598         mkdir -p $DIR/$tdir
25599         $LFS setstripe -c 2 $dom
25600
25601         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25602                 error "failed to write data into $dom"
25603         local old_md5=$(md5sum $dom)
25604         cancel_lru_locks
25605
25606         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25607                 error "failed mirroring to the DOM layout"
25608         $LFS mirror resync $dom ||
25609                 error "failed mirror resync"
25610         $LFS mirror split --mirror-id 1 -d $dom ||
25611                 error "failed mirror split"
25612
25613         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25614                 error "MDT stripe wasn't set"
25615
25616         cancel_lru_locks
25617         local new_md5=$(md5sum $dom)
25618         [ "$old_md5" == "$new_md5" ] ||
25619                 error "$old_md5 != $new_md5"
25620
25621         return 0
25622 }
25623 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25624
25625 test_272f() {
25626         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25627                 skip "Need MDS version at least 2.12.55"
25628
25629         local dom=$DIR/$tdir/$tfile
25630         mkdir -p $DIR/$tdir
25631         $LFS setstripe -c 2 $dom
25632
25633         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25634                 error "failed to write data into $dom"
25635         local old_md5=$(md5sum $dom)
25636         cancel_lru_locks
25637
25638         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25639                 error "failed migrating to the DOM file"
25640
25641         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25642                 error "MDT stripe wasn't set"
25643
25644         cancel_lru_locks
25645         local new_md5=$(md5sum $dom)
25646         [ "$old_md5" != "$new_md5" ] &&
25647                 error "$old_md5 != $new_md5"
25648
25649         return 0
25650 }
25651 run_test 272f "DoM migration: OST-striped file to DOM file"
25652
25653 test_273a() {
25654         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25655                 skip "Need MDS version at least 2.11.50"
25656
25657         # Layout swap cannot be done if either file has DOM component,
25658         # this will never be supported, migration should be used instead
25659
25660         local dom=$DIR/$tdir/$tfile
25661         mkdir -p $DIR/$tdir
25662
25663         $LFS setstripe -c2 ${dom}_plain
25664         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25665         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25666                 error "can swap layout with DoM component"
25667         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25668                 error "can swap layout with DoM component"
25669
25670         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25671         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25672                 error "can swap layout with DoM component"
25673         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25674                 error "can swap layout with DoM component"
25675         return 0
25676 }
25677 run_test 273a "DoM: layout swapping should fail with DOM"
25678
25679 test_273b() {
25680         mkdir -p $DIR/$tdir
25681         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25682
25683 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25684         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25685
25686         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25687 }
25688 run_test 273b "DoM: race writeback and object destroy"
25689
25690 test_273c() {
25691         mkdir -p $DIR/$tdir
25692         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25693
25694         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25695         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25696
25697         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25698 }
25699 run_test 273c "race writeback and object destroy"
25700
25701 test_275() {
25702         remote_ost_nodsh && skip "remote OST with nodsh"
25703         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25704                 skip "Need OST version >= 2.10.57"
25705
25706         local file=$DIR/$tfile
25707         local oss
25708
25709         oss=$(comma_list $(osts_nodes))
25710
25711         dd if=/dev/urandom of=$file bs=1M count=2 ||
25712                 error "failed to create a file"
25713         stack_trap "rm -f $file"
25714         cancel_lru_locks osc
25715
25716         #lock 1
25717         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25718                 error "failed to read a file"
25719
25720 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25721         $LCTL set_param fail_loc=0x8000031f
25722
25723         cancel_lru_locks osc &
25724         sleep 1
25725
25726 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25727         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25728         #IO takes another lock, but matches the PENDING one
25729         #and places it to the IO RPC
25730         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25731                 error "failed to read a file with PENDING lock"
25732 }
25733 run_test 275 "Read on a canceled duplicate lock"
25734
25735 test_276() {
25736         remote_ost_nodsh && skip "remote OST with nodsh"
25737         local pid
25738
25739         do_facet ost1 "(while true; do \
25740                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25741                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25742         pid=$!
25743
25744         for LOOP in $(seq 20); do
25745                 stop ost1
25746                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25747         done
25748         kill -9 $pid
25749         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25750                 rm $TMP/sanity_276_pid"
25751 }
25752 run_test 276 "Race between mount and obd_statfs"
25753
25754 test_277() {
25755         $LCTL set_param ldlm.namespaces.*.lru_size=0
25756         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25757         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25758                           awk '/^used_mb/ { print $2 }')
25759         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25760         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25761                 oflag=direct conv=notrunc
25762         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25763                     awk '/^used_mb/ { print $2 }')
25764         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25765 }
25766 run_test 277 "Direct IO shall drop page cache"
25767
25768 test_278() {
25769         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25770         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25771         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25772                 skip "needs the same host for mdt1 mdt2" && return
25773
25774         local pid1
25775         local pid2
25776
25777 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25778         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25779         stop mds2 &
25780         pid2=$!
25781
25782         stop mds1
25783
25784         echo "Starting MDTs"
25785         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25786         wait $pid2
25787 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25788 #will return NULL
25789         do_facet mds2 $LCTL set_param fail_loc=0
25790
25791         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25792         wait_recovery_complete mds2
25793 }
25794 run_test 278 "Race starting MDS between MDTs stop/start"
25795
25796 test_280() {
25797         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25798                 skip "Need MGS version at least 2.13.52"
25799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25800         combined_mgs_mds || skip "needs combined MGS/MDT"
25801
25802         umount_client $MOUNT
25803 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25804         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25805
25806         mount_client $MOUNT &
25807         sleep 1
25808         stop mgs || error "stop mgs failed"
25809         #for a race mgs would crash
25810         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25811         # make sure we unmount client before remounting
25812         wait
25813         umount_client $MOUNT
25814         mount_client $MOUNT || error "mount client failed"
25815 }
25816 run_test 280 "Race between MGS umount and client llog processing"
25817
25818 cleanup_test_300() {
25819         trap 0
25820         umask $SAVE_UMASK
25821 }
25822
25823 test_striped_dir() {
25824         local mdt_index=$1
25825         local stripe_count=$2
25826         local overstriping=$3
25827         local stripe_index
25828         local getstripe_count
25829
25830         mkdir -p $DIR/$tdir
25831
25832         SAVE_UMASK=$(umask)
25833         trap cleanup_test_300 RETURN EXIT
25834
25835         if [ -z $overstriping ]; then
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         else
25840                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25841                                         -o 755 $DIR/$tdir/striped_dir ||
25842                         error "set striped dir error"
25843         fi
25844
25845         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25846         [ "$mode" = "755" ] || error "expect 755 got $mode"
25847
25848         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25849                 error "getdirstripe failed"
25850         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25851         if [ "$getstripe_count" != "$stripe_count" ]; then
25852                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25853         fi
25854         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25855         if [ "$getstripe_count" != "$stripe_count" ]; then
25856                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25857         fi
25858
25859         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25860         if [ "$stripe_index" != "$mdt_index" ]; then
25861                 error "stripe_index is $stripe_index, expect $mdt_index"
25862         fi
25863
25864         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25865                 error "nlink error after create striped dir"
25866
25867         mkdir $DIR/$tdir/striped_dir/a
25868         mkdir $DIR/$tdir/striped_dir/b
25869
25870         stat $DIR/$tdir/striped_dir/a ||
25871                 error "create dir under striped dir failed"
25872         stat $DIR/$tdir/striped_dir/b ||
25873                 error "create dir under striped dir failed"
25874
25875         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25876                 error "nlink error after mkdir"
25877
25878         rmdir $DIR/$tdir/striped_dir/a
25879         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25880                 error "nlink error after rmdir"
25881
25882         rmdir $DIR/$tdir/striped_dir/b
25883         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25884                 error "nlink error after rmdir"
25885
25886         chattr +i $DIR/$tdir/striped_dir
25887         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25888                 error "immutable flags not working under striped dir!"
25889         chattr -i $DIR/$tdir/striped_dir
25890
25891         rmdir $DIR/$tdir/striped_dir ||
25892                 error "rmdir striped dir error"
25893
25894         cleanup_test_300
25895
25896         true
25897 }
25898
25899 test_300a() {
25900         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25901                 skip "skipped for lustre < 2.7.0"
25902         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25903         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25904
25905         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25906         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25907 }
25908 run_test 300a "basic striped dir sanity test"
25909
25910 test_300b() {
25911         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25912                 skip "skipped for lustre < 2.7.0"
25913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25914         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25915
25916         local i
25917         local mtime1
25918         local mtime2
25919         local mtime3
25920
25921         test_mkdir $DIR/$tdir || error "mkdir fail"
25922         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25923                 error "set striped dir error"
25924         for i in {0..9}; do
25925                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25926                 sleep 1
25927                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25928                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25929                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25930                 sleep 1
25931                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25932                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25933                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25934         done
25935         true
25936 }
25937 run_test 300b "check ctime/mtime for striped dir"
25938
25939 test_300c() {
25940         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25941                 skip "skipped for lustre < 2.7.0"
25942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25943         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25944
25945         local file_count
25946
25947         mkdir_on_mdt0 $DIR/$tdir
25948         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25949                 error "set striped dir error"
25950
25951         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25952                 error "chown striped dir failed"
25953
25954         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25955                 error "create 5k files failed"
25956
25957         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25958
25959         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25960
25961         rm -rf $DIR/$tdir
25962 }
25963 run_test 300c "chown && check ls under striped directory"
25964
25965 test_300d() {
25966         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25967                 skip "skipped for lustre < 2.7.0"
25968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25969         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25970
25971         local stripe_count
25972         local file
25973
25974         mkdir -p $DIR/$tdir
25975         $LFS setstripe -c 2 $DIR/$tdir
25976
25977         #local striped directory
25978         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25979                 error "set striped dir error"
25980         #look at the directories for debug purposes
25981         ls -l $DIR/$tdir
25982         $LFS getdirstripe $DIR/$tdir
25983         ls -l $DIR/$tdir/striped_dir
25984         $LFS getdirstripe $DIR/$tdir/striped_dir
25985         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25986                 error "create 10 files failed"
25987
25988         #remote striped directory
25989         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25990                 error "set striped dir error"
25991         #look at the directories for debug purposes
25992         ls -l $DIR/$tdir
25993         $LFS getdirstripe $DIR/$tdir
25994         ls -l $DIR/$tdir/remote_striped_dir
25995         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25996         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25997                 error "create 10 files failed"
25998
25999         for file in $(find $DIR/$tdir); do
26000                 stripe_count=$($LFS getstripe -c $file)
26001                 [ $stripe_count -eq 2 ] ||
26002                         error "wrong stripe $stripe_count for $file"
26003         done
26004
26005         rm -rf $DIR/$tdir
26006 }
26007 run_test 300d "check default stripe under striped directory"
26008
26009 test_300e() {
26010         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26011                 skip "Need MDS version at least 2.7.55"
26012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26013         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26014
26015         local stripe_count
26016         local file
26017
26018         mkdir -p $DIR/$tdir
26019
26020         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26021                 error "set striped dir error"
26022
26023         touch $DIR/$tdir/striped_dir/a
26024         touch $DIR/$tdir/striped_dir/b
26025         touch $DIR/$tdir/striped_dir/c
26026
26027         mkdir $DIR/$tdir/striped_dir/dir_a
26028         mkdir $DIR/$tdir/striped_dir/dir_b
26029         mkdir $DIR/$tdir/striped_dir/dir_c
26030
26031         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
26032                 error "set striped adir under striped dir error"
26033
26034         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
26035                 error "set striped bdir under striped dir error"
26036
26037         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
26038                 error "set striped cdir under striped dir error"
26039
26040         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
26041                 error "rename dir under striped dir fails"
26042
26043         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
26044                 error "rename dir under different stripes fails"
26045
26046         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
26047                 error "rename file under striped dir should succeed"
26048
26049         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
26050                 error "rename dir under striped dir should succeed"
26051
26052         rm -rf $DIR/$tdir
26053 }
26054 run_test 300e "check rename under striped directory"
26055
26056 test_300f() {
26057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26058         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26059         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26060                 skip "Need MDS version at least 2.7.55"
26061
26062         local stripe_count
26063         local file
26064
26065         rm -rf $DIR/$tdir
26066         mkdir -p $DIR/$tdir
26067
26068         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
26069                 error "set striped dir error"
26070
26071         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
26072                 error "set striped dir error"
26073
26074         touch $DIR/$tdir/striped_dir/a
26075         mkdir $DIR/$tdir/striped_dir/dir_a
26076         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
26077                 error "create striped dir under striped dir fails"
26078
26079         touch $DIR/$tdir/striped_dir1/b
26080         mkdir $DIR/$tdir/striped_dir1/dir_b
26081         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
26082                 error "create striped dir under striped dir fails"
26083
26084         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
26085                 error "rename dir under different striped dir should fail"
26086
26087         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
26088                 error "rename striped dir under diff striped dir should fail"
26089
26090         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
26091                 error "rename file under diff striped dirs fails"
26092
26093         rm -rf $DIR/$tdir
26094 }
26095 run_test 300f "check rename cross striped directory"
26096
26097 test_300_check_default_striped_dir()
26098 {
26099         local dirname=$1
26100         local default_count=$2
26101         local default_index=$3
26102         local stripe_count
26103         local stripe_index
26104         local dir_stripe_index
26105         local dir
26106
26107         echo "checking $dirname $default_count $default_index"
26108         $LFS setdirstripe -D -c $default_count -i $default_index \
26109                                 -H all_char $DIR/$tdir/$dirname ||
26110                 error "set default stripe on striped dir error"
26111         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26112         [ $stripe_count -eq $default_count ] ||
26113                 error "expect $default_count get $stripe_count for $dirname"
26114
26115         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26116         [ $stripe_index -eq $default_index ] ||
26117                 error "expect $default_index get $stripe_index for $dirname"
26118
26119         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26120                                                 error "create dirs failed"
26121
26122         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26123         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26124         for dir in $(find $DIR/$tdir/$dirname/*); do
26125                 stripe_count=$($LFS getdirstripe -c $dir)
26126                 (( $stripe_count == $default_count )) ||
26127                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26128                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26129                 error "stripe count $default_count != $stripe_count for $dir"
26130
26131                 stripe_index=$($LFS getdirstripe -i $dir)
26132                 [ $default_index -eq -1 ] ||
26133                         [ $stripe_index -eq $default_index ] ||
26134                         error "$stripe_index != $default_index for $dir"
26135
26136                 #check default stripe
26137                 stripe_count=$($LFS getdirstripe -D -c $dir)
26138                 [ $stripe_count -eq $default_count ] ||
26139                 error "default count $default_count != $stripe_count for $dir"
26140
26141                 stripe_index=$($LFS getdirstripe -D -i $dir)
26142                 [ $stripe_index -eq $default_index ] ||
26143                 error "default index $default_index != $stripe_index for $dir"
26144         done
26145         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26146 }
26147
26148 test_300g() {
26149         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26150         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26151                 skip "Need MDS version at least 2.7.55"
26152
26153         local dir
26154         local stripe_count
26155         local stripe_index
26156
26157         mkdir_on_mdt0 $DIR/$tdir
26158         mkdir $DIR/$tdir/normal_dir
26159
26160         #Checking when client cache stripe index
26161         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26162         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26163                 error "create striped_dir failed"
26164
26165         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26166                 error "create dir0 fails"
26167         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26168         [ $stripe_index -eq 0 ] ||
26169                 error "dir0 expect index 0 got $stripe_index"
26170
26171         mkdir $DIR/$tdir/striped_dir/dir1 ||
26172                 error "create dir1 fails"
26173         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26174         [ $stripe_index -eq 1 ] ||
26175                 error "dir1 expect index 1 got $stripe_index"
26176
26177         #check default stripe count/stripe index
26178         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26179         test_300_check_default_striped_dir normal_dir 1 0
26180         test_300_check_default_striped_dir normal_dir -1 1
26181         test_300_check_default_striped_dir normal_dir 2 -1
26182
26183         #delete default stripe information
26184         echo "delete default stripeEA"
26185         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26186                 error "set default stripe on striped dir error"
26187
26188         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26189         for dir in $(find $DIR/$tdir/normal_dir/*); do
26190                 stripe_count=$($LFS getdirstripe -c $dir)
26191                 [ $stripe_count -eq 0 ] ||
26192                         error "expect 1 get $stripe_count for $dir"
26193         done
26194 }
26195 run_test 300g "check default striped directory for normal directory"
26196
26197 test_300h() {
26198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26199         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26200                 skip "Need MDS version at least 2.7.55"
26201
26202         local dir
26203         local stripe_count
26204
26205         mkdir $DIR/$tdir
26206         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26207                 error "set striped dir error"
26208
26209         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26210         test_300_check_default_striped_dir striped_dir 1 0
26211         test_300_check_default_striped_dir striped_dir -1 1
26212         test_300_check_default_striped_dir striped_dir 2 -1
26213
26214         #delete default stripe information
26215         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26216                 error "set default stripe on striped dir error"
26217
26218         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26219         for dir in $(find $DIR/$tdir/striped_dir/*); do
26220                 stripe_count=$($LFS getdirstripe -c $dir)
26221                 [ $stripe_count -eq 0 ] ||
26222                         error "expect 1 get $stripe_count for $dir"
26223         done
26224 }
26225 run_test 300h "check default striped directory for striped directory"
26226
26227 test_300i() {
26228         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26229         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26230         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26231                 skip "Need MDS version at least 2.7.55"
26232
26233         local stripe_count
26234         local file
26235
26236         mkdir $DIR/$tdir
26237
26238         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26239                 error "set striped dir error"
26240
26241         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26242                 error "create files under striped dir failed"
26243
26244         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26245                 error "set striped hashdir error"
26246
26247         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26248                 error "create dir0 under hash dir failed"
26249         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26250                 error "create dir1 under hash dir failed"
26251         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26252                 error "create dir2 under hash dir failed"
26253
26254         # unfortunately, we need to umount to clear dir layout cache for now
26255         # once we fully implement dir layout, we can drop this
26256         umount_client $MOUNT || error "umount failed"
26257         mount_client $MOUNT || error "mount failed"
26258
26259         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26260         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26261         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26262
26263         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26264                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26265                         error "create crush2 dir $tdir/hashdir/d3 failed"
26266                 $LFS find -H crush2 $DIR/$tdir/hashdir
26267                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26268                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26269
26270                 # mkdir with an invalid hash type (hash=fail_val) from client
26271                 # should be replaced on MDS with a valid (default) hash type
26272                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26273                 $LCTL set_param fail_loc=0x1901 fail_val=99
26274                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26275
26276                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26277                 local expect=$(do_facet mds1 \
26278                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26279                 [[ $hash == $expect ]] ||
26280                         error "d99 hash '$hash' != expected hash '$expect'"
26281         fi
26282
26283         #set the stripe to be unknown hash type on read
26284         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26285         $LCTL set_param fail_loc=0x1901 fail_val=99
26286         for ((i = 0; i < 10; i++)); do
26287                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26288                         error "stat f-$i failed"
26289                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26290         done
26291
26292         touch $DIR/$tdir/striped_dir/f0 &&
26293                 error "create under striped dir with unknown hash should fail"
26294
26295         $LCTL set_param fail_loc=0
26296
26297         umount_client $MOUNT || error "umount failed"
26298         mount_client $MOUNT || error "mount failed"
26299
26300         return 0
26301 }
26302 run_test 300i "client handle unknown hash type striped directory"
26303
26304 test_300j() {
26305         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26307         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26308                 skip "Need MDS version at least 2.7.55"
26309
26310         local stripe_count
26311         local file
26312
26313         mkdir $DIR/$tdir
26314
26315         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26316         $LCTL set_param fail_loc=0x1702
26317         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26318                 error "set striped dir error"
26319
26320         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26321                 error "create files under striped dir failed"
26322
26323         $LCTL set_param fail_loc=0
26324
26325         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26326
26327         return 0
26328 }
26329 run_test 300j "test large update record"
26330
26331 test_300k() {
26332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26334         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26335                 skip "Need MDS version at least 2.7.55"
26336
26337         # this test needs a huge transaction
26338         local kb
26339         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26340              osd*.$FSNAME-MDT0000.kbytestotal")
26341         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26342
26343         local stripe_count
26344         local file
26345
26346         mkdir $DIR/$tdir
26347
26348         #define OBD_FAIL_LARGE_STRIPE   0x1703
26349         $LCTL set_param fail_loc=0x1703
26350         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26351                 error "set striped dir error"
26352         $LCTL set_param fail_loc=0
26353
26354         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26355                 error "getstripeddir fails"
26356         rm -rf $DIR/$tdir/striped_dir ||
26357                 error "unlink striped dir fails"
26358
26359         return 0
26360 }
26361 run_test 300k "test large striped directory"
26362
26363 test_300l() {
26364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26365         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26366         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26367                 skip "Need MDS version at least 2.7.55"
26368
26369         local stripe_index
26370
26371         test_mkdir -p $DIR/$tdir/striped_dir
26372         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26373                         error "chown $RUNAS_ID failed"
26374         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26375                 error "set default striped dir failed"
26376
26377         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26378         $LCTL set_param fail_loc=0x80000158
26379         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26380
26381         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26382         [ $stripe_index -eq 1 ] ||
26383                 error "expect 1 get $stripe_index for $dir"
26384 }
26385 run_test 300l "non-root user to create dir under striped dir with stale layout"
26386
26387 test_300m() {
26388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26389         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26390         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26391                 skip "Need MDS version at least 2.7.55"
26392
26393         mkdir -p $DIR/$tdir/striped_dir
26394         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26395                 error "set default stripes dir error"
26396
26397         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26398
26399         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26400         [ $stripe_count -eq 0 ] ||
26401                         error "expect 0 get $stripe_count for a"
26402
26403         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26404                 error "set default stripes dir error"
26405
26406         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26407
26408         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26409         [ $stripe_count -eq 0 ] ||
26410                         error "expect 0 get $stripe_count for b"
26411
26412         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26413                 error "set default stripes dir error"
26414
26415         mkdir $DIR/$tdir/striped_dir/c &&
26416                 error "default stripe_index is invalid, mkdir c should fails"
26417
26418         rm -rf $DIR/$tdir || error "rmdir fails"
26419 }
26420 run_test 300m "setstriped directory on single MDT FS"
26421
26422 cleanup_300n() {
26423         local list=$(comma_list $(mdts_nodes))
26424
26425         trap 0
26426         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26427 }
26428
26429 test_300n() {
26430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26432         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26433                 skip "Need MDS version at least 2.7.55"
26434         remote_mds_nodsh && skip "remote MDS with nodsh"
26435
26436         local stripe_index
26437         local list=$(comma_list $(mdts_nodes))
26438
26439         trap cleanup_300n RETURN EXIT
26440         mkdir -p $DIR/$tdir
26441         chmod 777 $DIR/$tdir
26442         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26443                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26444                 error "create striped dir succeeds with gid=0"
26445
26446         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26447         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26448                 error "create striped dir fails with gid=-1"
26449
26450         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26451         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26452                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26453                 error "set default striped dir succeeds with gid=0"
26454
26455
26456         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26457         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26458                 error "set default striped dir fails with gid=-1"
26459
26460
26461         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26462         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26463                                         error "create test_dir fails"
26464         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26465                                         error "create test_dir1 fails"
26466         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26467                                         error "create test_dir2 fails"
26468         cleanup_300n
26469 }
26470 run_test 300n "non-root user to create dir under striped dir with default EA"
26471
26472 test_300o() {
26473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26474         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26475         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26476                 skip "Need MDS version at least 2.7.55"
26477
26478         local numfree1
26479         local numfree2
26480
26481         mkdir -p $DIR/$tdir
26482
26483         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26484         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26485         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26486                 skip "not enough free inodes $numfree1 $numfree2"
26487         fi
26488
26489         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26490         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26491         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26492                 skip "not enough free space $numfree1 $numfree2"
26493         fi
26494
26495         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26496                 error "setdirstripe fails"
26497
26498         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26499                 error "create dirs fails"
26500
26501         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26502         ls $DIR/$tdir/striped_dir > /dev/null ||
26503                 error "ls striped dir fails"
26504         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26505                 error "unlink big striped dir fails"
26506 }
26507 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26508
26509 test_300p() {
26510         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26511         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26512         remote_mds_nodsh && skip "remote MDS with nodsh"
26513
26514         mkdir_on_mdt0 $DIR/$tdir
26515
26516         #define OBD_FAIL_OUT_ENOSPC     0x1704
26517         do_facet mds2 lctl set_param fail_loc=0x80001704
26518         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26519                  && error "create striped directory should fail"
26520
26521         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26522
26523         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26524         true
26525 }
26526 run_test 300p "create striped directory without space"
26527
26528 test_300q() {
26529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26530         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26531
26532         local fd=$(free_fd)
26533         local cmd="exec $fd<$tdir"
26534         cd $DIR
26535         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26536         eval $cmd
26537         cmd="exec $fd<&-"
26538         trap "eval $cmd" EXIT
26539         cd $tdir || error "cd $tdir fails"
26540         rmdir  ../$tdir || error "rmdir $tdir fails"
26541         mkdir local_dir && error "create dir succeeds"
26542         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26543         eval $cmd
26544         return 0
26545 }
26546 run_test 300q "create remote directory under orphan directory"
26547
26548 test_300r() {
26549         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26550                 skip "Need MDS version at least 2.7.55" && return
26551         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26552
26553         mkdir $DIR/$tdir
26554
26555         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26556                 error "set striped dir error"
26557
26558         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26559                 error "getstripeddir fails"
26560
26561         local stripe_count
26562         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26563                       awk '/lmv_stripe_count:/ { print $2 }')
26564
26565         [ $MDSCOUNT -ne $stripe_count ] &&
26566                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26567
26568         rm -rf $DIR/$tdir/striped_dir ||
26569                 error "unlink striped dir fails"
26570 }
26571 run_test 300r "test -1 striped directory"
26572
26573 test_300s_helper() {
26574         local count=$1
26575
26576         local stripe_dir=$DIR/$tdir/striped_dir.$count
26577
26578         $LFS mkdir -c $count $stripe_dir ||
26579                 error "lfs mkdir -c error"
26580
26581         $LFS getdirstripe $stripe_dir ||
26582                 error "lfs getdirstripe fails"
26583
26584         local stripe_count
26585         stripe_count=$($LFS getdirstripe $stripe_dir |
26586                       awk '/lmv_stripe_count:/ { print $2 }')
26587
26588         [ $count -ne $stripe_count ] &&
26589                 error_noexit "bad stripe count $stripe_count expected $count"
26590
26591         local dupe_stripes
26592         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26593                 awk '/0x/ {count[$1] += 1}; END {
26594                         for (idx in count) {
26595                                 if (count[idx]>1) {
26596                                         print "index " idx " count " count[idx]
26597                                 }
26598                         }
26599                 }')
26600
26601         if [[ -n "$dupe_stripes" ]] ; then
26602                 lfs getdirstripe $stripe_dir
26603                 error_noexit "Dupe MDT above: $dupe_stripes "
26604         fi
26605
26606         rm -rf $stripe_dir ||
26607                 error_noexit "unlink $stripe_dir fails"
26608 }
26609
26610 test_300s() {
26611         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26612                 skip "Need MDS version at least 2.7.55" && return
26613         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26614
26615         mkdir $DIR/$tdir
26616         for count in $(seq 2 $MDSCOUNT); do
26617                 test_300s_helper $count
26618         done
26619 }
26620 run_test 300s "test lfs mkdir -c without -i"
26621
26622 test_300t() {
26623         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26624                 skip "need MDS 2.14.55 or later"
26625         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26626
26627         local testdir="$DIR/$tdir/striped_dir"
26628         local dir1=$testdir/dir1
26629         local dir2=$testdir/dir2
26630
26631         mkdir -p $testdir
26632
26633         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26634                 error "failed to set default stripe count for $testdir"
26635
26636         mkdir $dir1
26637         local stripe_count=$($LFS getdirstripe -c $dir1)
26638
26639         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26640
26641         local max_count=$((MDSCOUNT - 1))
26642         local mdts=$(comma_list $(mdts_nodes))
26643
26644         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26645         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26646
26647         mkdir $dir2
26648         stripe_count=$($LFS getdirstripe -c $dir2)
26649
26650         (( $stripe_count == $max_count )) || error "wrong stripe count"
26651 }
26652 run_test 300t "test max_mdt_stripecount"
26653
26654 MDT_OVSTRP_VER="2.15.60"
26655 # 300u family tests MDT overstriping
26656 test_300ua() {
26657         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26658
26659         local setcount=$((MDSCOUNT * 2))
26660
26661         local expected_count
26662
26663         mkdir $DIR/$tdir
26664         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26665                 error "(0) failed basic overstriped dir creation test"
26666         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26667
26668         # This does a basic interop test - if the MDS does not support mdt
26669         # overstriping, we should get stripes == number of MDTs
26670         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26671                 expected_count=$MDSCOUNT
26672         else
26673                 expected_count=$setcount
26674         fi
26675         (( getstripe_count == expected_count )) ||
26676                 error "(1) incorrect stripe count for simple overstriped dir"
26677
26678         rm -rf $DIR/$tdir/${tdir}.0 ||
26679                 error "(2) unable to rm overstriped dir"
26680
26681         # Tests after this require overstriping support
26682         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26683                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26684
26685         test_striped_dir 0 $setcount true ||
26686                 error "(3)failed on overstriped dir"
26687         test_striped_dir 1 $setcount true ||
26688                 error "(4)failed on overstriped dir"
26689
26690         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26691
26692         test_striped_dir 0 $setcount true ||
26693                 error "(5)failed on overstriped dir"
26694 }
26695 run_test 300ua "basic overstriped dir sanity test"
26696
26697 test_300ub() {
26698         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26699                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26700         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26701
26702         mkdir $DIR/$tdir
26703
26704         echo "Testing invalid stripe count, failure expected"
26705         local setcount=$((MDSCOUNT * 2))
26706
26707         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26708         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26709
26710         (( getstripe_count <= MDSCOUNT )) ||
26711                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26712
26713         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26714         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26715         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26716
26717         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26718
26719         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26720         (( getstripe_count == maxcount )) ||
26721                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26722
26723         # Test specific striping with -i
26724         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26725
26726         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26727         (( getstripe_count == 4 )) ||
26728                 error "(2)stripe_count is $getstripe_count, expect 4"
26729
26730         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26731                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26732
26733         [[ -n "$nonzeroindices" ]] ||
26734                 error "(3) stripes indices not all 0: $nonzeroindices"
26735
26736         # Test specific striping with too many stripes on one MDT
26737         echo "Testing invalid striping, failure expected"
26738         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26739         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26740         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26741                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26742         echo "stripes on MDT0: $getstripe_count"
26743         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26744                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26745
26746         setcount=$((MDSCOUNT * 2))
26747         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26748                 error "(5) can't setdirstripe with manually set hash function"
26749
26750         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26751         (( getstripe_count == setcount )) ||
26752                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26753
26754         setcount=$((MDSCOUNT * 2))
26755         mkdir $DIR/${tdir}.5
26756         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26757                 error "(7) can't setdirstripe with manually set hash function"
26758         mkdir $DIR/${tdir}.5/${tdir}.6
26759
26760         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26761         (( getstripe_count == setcount )) ||
26762                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26763 }
26764 run_test 300ub "test MDT overstriping interface & limits"
26765
26766 test_300uc() {
26767         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26768                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26769         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26770
26771         mkdir $DIR/$tdir
26772
26773         local setcount=$((MDSCOUNT * 2))
26774
26775         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26776
26777         mkdir $DIR/$tdir/${tdir}.1
26778
26779         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26780
26781         (( getstripe_count == setcount )) ||
26782                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26783
26784         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26785
26786         local getstripe_count=$($LFS getdirstripe -c \
26787                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26788
26789         (( getstripe_count == setcount )) ||
26790                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26791 }
26792 run_test 300uc "test MDT overstriping as default & inheritance"
26793
26794 test_300ud() {
26795         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26796                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26797         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26798
26799         local mdts=$(comma_list $(mdts_nodes))
26800         local timeout=100
26801
26802         local restripe_status
26803         local delta
26804         local i
26805
26806         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26807
26808         # in case "crush" hash type is not set
26809         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26810
26811         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26812                            mdt.*MDT0000.enable_dir_restripe)
26813         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26814         stack_trap "do_nodes $mdts $LCTL set_param \
26815                     mdt.*.enable_dir_restripe=$restripe_status"
26816
26817         mkdir $DIR/$tdir
26818         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26819                 error "create files under remote dir failed $i"
26820         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26821                 error "create dirs under remote dir failed $i"
26822
26823         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26824
26825         (( setcount < 13 )) || setcount=12
26826         for i in $(seq 2 $setcount); do
26827                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26828                 $LFS setdirstripe -C $i $DIR/$tdir ||
26829                         error "split -C $i $tdir failed"
26830                 wait_update $HOSTNAME \
26831                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26832                         error "dir split not finished"
26833                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26834                         awk '/migrate/ {sum += $2} END { print sum }')
26835                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26836                 # delta is around total_files/stripe_count, deviation 3%
26837                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26838                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26839         done
26840 }
26841 run_test 300ud "dir split"
26842
26843 test_300ue() {
26844         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26845                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26846         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26847
26848         local mdts=$(comma_list $(mdts_nodes))
26849         local timeout=100
26850
26851         local restripe_status
26852         local delta
26853         local c
26854
26855         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26856
26857         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26858
26859         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26860                            mdt.*MDT0000.enable_dir_restripe)
26861         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26862         stack_trap "do_nodes $mdts $LCTL set_param \
26863                     mdt.*.enable_dir_restripe=$restripe_status"
26864
26865         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26866
26867         (( setcount < 13 )) || setcount=12
26868         test_mkdir -C $setcount -H crush $DIR/$tdir
26869         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26870                 error "create files under remote dir failed"
26871         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26872                 error "create dirs under remote dir failed"
26873
26874         for c in $(seq $((setcount - 1)) -1 1); do
26875                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26876                 $LFS setdirstripe -C $c $DIR/$tdir ||
26877                         error "split -C $c $tdir failed"
26878                 wait_update $HOSTNAME \
26879                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26880                         error "dir merge not finished"
26881                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26882                         awk '/migrate/ {sum += $2} END { print sum }')
26883                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26884                 # delta is around total_files/stripe_count, deviation 3%
26885                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26886                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26887         done
26888 }
26889 run_test 300ue "dir merge"
26890
26891 test_300uf() {
26892         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26893                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26894         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26895
26896         # maximum amount of local locks:
26897         # parent striped dir - 2 locks
26898         # new stripe in parent to migrate to - 1 lock
26899         # source and target - 2 locks
26900         # Total 5 locks for regular file
26901         #
26902         # NB: Overstriping should add several extra local locks
26903         # FIXME: Remove this once understood
26904         #lctl set_param *debug=-1 debug_mb=10000
26905         lctl clear
26906         lctl mark "touch/create"
26907         mkdir -p $DIR/$tdir
26908         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26909         local setcount=$((MDSCOUNT * 5))
26910
26911         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26912         touch $DIR/$tdir/dir1/eee
26913
26914         lctl mark "hardlinks"
26915         # create 4 hardlink for 4 more locks
26916         # Total: 9 locks > RS_MAX_LOCKS (8)
26917         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26918         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26919         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26920         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26921         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26922         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26923         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26924         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26925
26926         lctl mark "cancel lru"
26927         cancel_lru_locks mdc
26928
26929         lctl mark "migrate"
26930         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26931                 error "migrate dir fails"
26932
26933         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26934 }
26935 run_test 300uf "migrate with too many local locks"
26936
26937 test_300ug() {
26938         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26939                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26940         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26941
26942         mkdir -p $DIR/$tdir
26943         local migrate_dir=$DIR/$tdir/migrate_dir
26944         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26945         local setcount2=$((setcount - 2))
26946
26947         $LFS setdirstripe -c 2 $migrate_dir ||
26948                 error "(0) failed to create striped directory"
26949
26950         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26951                 error "(1)failed to migrate to overstriped directory"
26952         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26953
26954         (( getstripe_count == setcount )) ||
26955                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26956         touch $DIR/$tdir/migrate_dir/$tfile ||
26957                 error "(3)failed to create file in overstriped directory"
26958         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26959                 error "(4)failed to migrate overstriped directory"
26960         # Check stripe count after migration
26961         $LFS getdirstripe $migrate_dir
26962         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26963         (( getstripe_count == setcount2 )) ||
26964                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26965
26966         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
26967 }
26968 run_test 300ug "migrate overstriped dirs"
26969
26970 prepare_remote_file() {
26971         mkdir $DIR/$tdir/src_dir ||
26972                 error "create remote source failed"
26973
26974         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26975                  error "cp to remote source failed"
26976         touch $DIR/$tdir/src_dir/a
26977
26978         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26979                 error "create remote target dir failed"
26980
26981         touch $DIR/$tdir/tgt_dir/b
26982
26983         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26984                 error "rename dir cross MDT failed!"
26985
26986         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26987                 error "src_child still exists after rename"
26988
26989         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26990                 error "missing file(a) after rename"
26991
26992         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26993                 error "diff after rename"
26994 }
26995
26996 test_310a() {
26997         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26999
27000         local remote_file=$DIR/$tdir/tgt_dir/b
27001
27002         mkdir -p $DIR/$tdir
27003
27004         prepare_remote_file || error "prepare remote file failed"
27005
27006         #open-unlink file
27007         $OPENUNLINK $remote_file $remote_file ||
27008                 error "openunlink $remote_file failed"
27009         $CHECKSTAT -a $remote_file || error "$remote_file exists"
27010 }
27011 run_test 310a "open unlink remote file"
27012
27013 test_310b() {
27014         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
27015         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27016
27017         local remote_file=$DIR/$tdir/tgt_dir/b
27018
27019         mkdir -p $DIR/$tdir
27020
27021         prepare_remote_file || error "prepare remote file failed"
27022
27023         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27024         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
27025         $CHECKSTAT -t file $remote_file || error "check file failed"
27026 }
27027 run_test 310b "unlink remote file with multiple links while open"
27028
27029 test_310c() {
27030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27031         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
27032
27033         local remote_file=$DIR/$tdir/tgt_dir/b
27034
27035         mkdir -p $DIR/$tdir
27036
27037         prepare_remote_file || error "prepare remote file failed"
27038
27039         ln $remote_file $DIR/$tfile || error "link failed for remote file"
27040         multiop_bg_pause $remote_file O_uc ||
27041                         error "mulitop failed for remote file"
27042         MULTIPID=$!
27043         $MULTIOP $DIR/$tfile Ouc
27044         kill -USR1 $MULTIPID
27045         wait $MULTIPID
27046 }
27047 run_test 310c "open-unlink remote file with multiple links"
27048
27049 #LU-4825
27050 test_311() {
27051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27052         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27053         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
27054                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
27055         remote_mds_nodsh && skip "remote MDS with nodsh"
27056
27057         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27058         local mdts=$(comma_list $(mdts_nodes))
27059
27060         mkdir -p $DIR/$tdir
27061         $LFS setstripe -i 0 -c 1 $DIR/$tdir
27062         createmany -o $DIR/$tdir/$tfile. 1000
27063
27064         # statfs data is not real time, let's just calculate it
27065         old_iused=$((old_iused + 1000))
27066
27067         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27068                         osp.*OST0000*MDT0000.create_count")
27069         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
27070                                 osp.*OST0000*MDT0000.max_create_count")
27071         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
27072
27073         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
27074         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
27075         [ $index -ne 0 ] || error "$tfile stripe index is 0"
27076
27077         unlinkmany $DIR/$tdir/$tfile. 1000
27078
27079         do_nodes $mdts "$LCTL set_param -n \
27080                         osp.*OST0000*.max_create_count=$max_count"
27081         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
27082                 do_nodes $mdts "$LCTL set_param -n \
27083                                 osp.*OST0000*.create_count=$count"
27084         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
27085                         grep "=0" && error "create_count is zero"
27086
27087         local new_iused
27088         for i in $(seq 120); do
27089                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
27090                 # system may be too busy to destroy all objs in time, use
27091                 # a somewhat small value to not fail autotest
27092                 [ $((old_iused - new_iused)) -gt 400 ] && break
27093                 sleep 1
27094         done
27095
27096         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
27097         [ $((old_iused - new_iused)) -gt 400 ] ||
27098                 error "objs not destroyed after unlink"
27099 }
27100 run_test 311 "disable OSP precreate, and unlink should destroy objs"
27101
27102 zfs_get_objid()
27103 {
27104         local ost=$1
27105         local tf=$2
27106         local fid=($($LFS getstripe $tf | grep 0x))
27107         local seq=${fid[3]#0x}
27108         local objid=${fid[1]}
27109
27110         local vdevdir=$(dirname $(facet_vdevice $ost))
27111         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27112         local zfs_zapid=$(do_facet $ost $cmd |
27113                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27114                           awk '/Object/{getline; print $1}')
27115         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27116                           awk "/$objid = /"'{printf $3}')
27117
27118         echo $zfs_objid
27119 }
27120
27121 zfs_object_blksz() {
27122         local ost=$1
27123         local objid=$2
27124
27125         local vdevdir=$(dirname $(facet_vdevice $ost))
27126         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27127         local blksz=$(do_facet $ost $cmd $objid |
27128                       awk '/dblk/{getline; printf $4}')
27129
27130         case "${blksz: -1}" in
27131                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27132                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27133                 *) ;;
27134         esac
27135
27136         echo $blksz
27137 }
27138
27139 test_312() { # LU-4856
27140         remote_ost_nodsh && skip "remote OST with nodsh"
27141         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27142
27143         local max_blksz=$(do_facet ost1 \
27144                           $ZFS get -p recordsize $(facet_device ost1) |
27145                           awk '!/VALUE/{print $3}')
27146         local tf=$DIR/$tfile
27147
27148         $LFS setstripe -c1 $tf
27149         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27150
27151         # Get ZFS object id
27152         local zfs_objid=$(zfs_get_objid $facet $tf)
27153         # block size change by sequential overwrite
27154         local bs
27155
27156         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27157                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27158
27159                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27160                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27161         done
27162         rm -f $tf
27163
27164         $LFS setstripe -c1 $tf
27165         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27166
27167         # block size change by sequential append write
27168         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27169         zfs_objid=$(zfs_get_objid $facet $tf)
27170         local count
27171
27172         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27173                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27174                         oflag=sync conv=notrunc
27175
27176                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27177                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27178                         error "blksz error, actual $blksz, " \
27179                                 "expected: 2 * $count * $PAGE_SIZE"
27180         done
27181         rm -f $tf
27182
27183         # random write
27184         $LFS setstripe -c1 $tf
27185         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27186         zfs_objid=$(zfs_get_objid $facet $tf)
27187
27188         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27189         blksz=$(zfs_object_blksz $facet $zfs_objid)
27190         (( blksz == PAGE_SIZE )) ||
27191                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27192
27193         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27194         blksz=$(zfs_object_blksz $facet $zfs_objid)
27195         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27196
27197         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27198         blksz=$(zfs_object_blksz $facet $zfs_objid)
27199         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27200 }
27201 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27202
27203 test_313() {
27204         remote_ost_nodsh && skip "remote OST with nodsh"
27205
27206         local file=$DIR/$tfile
27207
27208         rm -f $file
27209         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27210
27211         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27212         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27213         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27214                 error "write should failed"
27215         do_facet ost1 "$LCTL set_param fail_loc=0"
27216         rm -f $file
27217 }
27218 run_test 313 "io should fail after last_rcvd update fail"
27219
27220 test_314() {
27221         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27222
27223         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27224         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27225         rm -f $DIR/$tfile
27226         wait_delete_completed
27227         do_facet ost1 "$LCTL set_param fail_loc=0"
27228 }
27229 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27230
27231 test_315() { # LU-618
27232         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27233
27234         local file=$DIR/$tfile
27235         rm -f $file
27236
27237         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27238                 error "multiop file write failed"
27239         $MULTIOP $file oO_RDONLY:r4063232_c &
27240         PID=$!
27241
27242         sleep 2
27243
27244         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27245         kill -USR1 $PID
27246
27247         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27248         rm -f $file
27249 }
27250 run_test 315 "read should be accounted"
27251
27252 test_316() {
27253         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27254         large_xattr_enabled || skip "ea_inode feature disabled"
27255
27256         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27257         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27258         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27259         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27260
27261         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27262 }
27263 run_test 316 "lfs migrate of file with large_xattr enabled"
27264
27265 test_317() {
27266         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27267                 skip "Need MDS version at least 2.11.53"
27268         if [ "$ost1_FSTYPE" == "zfs" ]; then
27269                 skip "LU-10370: no implementation for ZFS"
27270         fi
27271
27272         local trunc_sz
27273         local grant_blk_size
27274
27275         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27276                         awk '/grant_block_size:/ { print $2; exit; }')
27277         #
27278         # Create File of size 5M. Truncate it to below size's and verify
27279         # blocks count.
27280         #
27281         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27282                 error "Create file $DIR/$tfile failed"
27283         stack_trap "rm -f $DIR/$tfile" EXIT
27284
27285         for trunc_sz in 2097152 4097 4000 509 0; do
27286                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27287                         error "truncate $tfile to $trunc_sz failed"
27288                 local sz=$(stat --format=%s $DIR/$tfile)
27289                 local blk=$(stat --format=%b $DIR/$tfile)
27290                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27291                                      grant_blk_size) * 8))
27292
27293                 if [[ $blk -ne $trunc_blk ]]; then
27294                         $(which stat) $DIR/$tfile
27295                         error "Expected Block $trunc_blk got $blk for $tfile"
27296                 fi
27297
27298                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27299                         error "Expected Size $trunc_sz got $sz for $tfile"
27300         done
27301
27302         #
27303         # sparse file test
27304         # Create file with a hole and write actual 65536 bytes which aligned
27305         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27306         #
27307         local bs=65536
27308         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27309                 error "Create file : $DIR/$tfile"
27310
27311         #
27312         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27313         # blocks. The block count must drop to 8.
27314         #
27315         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27316                 ((bs - grant_blk_size) + 1)))
27317         $TRUNCATE $DIR/$tfile $trunc_sz ||
27318                 error "truncate $tfile to $trunc_sz failed"
27319
27320         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27321         sz=$(stat --format=%s $DIR/$tfile)
27322         blk=$(stat --format=%b $DIR/$tfile)
27323
27324         if [[ $blk -ne $trunc_bsz ]]; then
27325                 $(which stat) $DIR/$tfile
27326                 error "Expected Block $trunc_bsz got $blk for $tfile"
27327         fi
27328
27329         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27330                 error "Expected Size $trunc_sz got $sz for $tfile"
27331 }
27332 run_test 317 "Verify blocks get correctly update after truncate"
27333
27334 test_318() {
27335         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27336         local old_max_active=$($LCTL get_param -n \
27337                             ${llite_name}.max_read_ahead_async_active \
27338                             2>/dev/null)
27339
27340         $LCTL set_param llite.*.max_read_ahead_async_active=256
27341         local max_active=$($LCTL get_param -n \
27342                            ${llite_name}.max_read_ahead_async_active \
27343                            2>/dev/null)
27344         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27345
27346         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27347                 error "set max_read_ahead_async_active should succeed"
27348
27349         $LCTL set_param llite.*.max_read_ahead_async_active=512
27350         max_active=$($LCTL get_param -n \
27351                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27352         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27353
27354         # restore @max_active
27355         [ $old_max_active -ne 0 ] && $LCTL set_param \
27356                 llite.*.max_read_ahead_async_active=$old_max_active
27357
27358         local old_threshold=$($LCTL get_param -n \
27359                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27360         local max_per_file_mb=$($LCTL get_param -n \
27361                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27362
27363         local invalid=$(($max_per_file_mb + 1))
27364         $LCTL set_param \
27365                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27366                         && error "set $invalid should fail"
27367
27368         local valid=$(($invalid - 1))
27369         $LCTL set_param \
27370                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27371                         error "set $valid should succeed"
27372         local threshold=$($LCTL get_param -n \
27373                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27374         [ $threshold -eq $valid ] || error \
27375                 "expect threshold $valid got $threshold"
27376         $LCTL set_param \
27377                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27378 }
27379 run_test 318 "Verify async readahead tunables"
27380
27381 test_319() {
27382         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27383
27384         local before=$(date +%s)
27385         local evict
27386         local mdir=$DIR/$tdir
27387         local file=$mdir/xxx
27388
27389         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27390         touch $file
27391
27392 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27393         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27394         $LFS migrate -m1 $mdir &
27395
27396         sleep 1
27397         dd if=$file of=/dev/null
27398         wait
27399         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27400           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27401
27402         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27403 }
27404 run_test 319 "lost lease lock on migrate error"
27405
27406 test_350() {
27407         local mdts=$(comma_list $(mdts_nodes))
27408
27409         mkdir $DIR/$tdir || error "mkdir $DIR/$tdir failed"
27410         stack_trap "rm -r $DIR/$tdir"
27411
27412         #force 1/100 of replies to take "NID mismatch" codepath
27413         #define CFS_FAIL_MATCH_MD_NID 0xe001  CFS_FAIL_SOME 0x10000000
27414         do_nodes $mdts $LCTL set_param fail_loc=0x1000e001 fail_val=100
27415
27416         while ls -lR $DIR/$tdir > /dev/null; do :; done &
27417         stack_trap "killall -9 ls || killall -9 ls"
27418
27419         cp -a /etc $DIR/$tdir || error "cp failed"
27420 }
27421 run_test 350 "force NID mismatch path to be exercised"
27422
27423 test_360() {
27424         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27425                 skip "Need OST version at least 2.15.58.96"
27426         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27427
27428         check_set_fallocate_or_skip
27429         local param="osd-ldiskfs.delayed_unlink_mb"
27430         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27431
27432         do_facet ost1 "$LCTL set_param $param=1MiB"
27433         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27434
27435         mkdir $DIR/$tdir/
27436         do_facet ost1 $LCTL set_param debug=+inode
27437         do_facet ost1 $LCTL clear
27438         local files=100
27439
27440         for ((i = 0; i < $files; i++)); do
27441                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27442                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27443         done
27444         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27445
27446         for ((i = 0; i < $files; i++)); do
27447                 unlink $DIR/$tdir/$tfile.$i ||
27448                         error "unlink $DIR/$tdir/$tfile.$i failed"
27449         done
27450
27451         local count=0
27452         local loop
27453
27454         for (( loop = 0; loop < 30 && count < min; loop++)); do
27455                 sleep 1
27456                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27457                 echo "Count[$loop]: $count"
27458         done
27459         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27460 }
27461 run_test 360 "ldiskfs unlink in a separate thread"
27462
27463 test_398a() { # LU-4198
27464         local ost1_imp=$(get_osc_import_name client ost1)
27465         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27466                          cut -d'.' -f2)
27467
27468         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27469         stack_trap "rm -f $DIR/$tfile"
27470         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27471
27472         # request a new lock on client
27473         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27474
27475         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27476         local lock_count=$($LCTL get_param -n \
27477                            ldlm.namespaces.$imp_name.lru_size)
27478         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27479
27480         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27481
27482         # no lock cached, should use lockless DIO and not enqueue new lock
27483         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27484         lock_count=$($LCTL get_param -n \
27485                      ldlm.namespaces.$imp_name.lru_size)
27486         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27487
27488         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27489
27490         # no lock cached, should use locked DIO append
27491         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27492                 conv=notrunc || error "DIO append failed"
27493         lock_count=$($LCTL get_param -n \
27494                      ldlm.namespaces.$imp_name.lru_size)
27495         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27496 }
27497 run_test 398a "direct IO should cancel lock otherwise lockless"
27498
27499 test_398b() { # LU-4198
27500         local before=$(date +%s)
27501         local njobs=4
27502         local size=48
27503
27504         which fio || skip_env "no fio installed"
27505         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27506         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27507
27508         # Single page, multiple pages, stripe size, 4*stripe size
27509         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27510                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27511                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27512                         --numjobs=$njobs --fallocate=none \
27513                         --iodepth=16 --allow_file_create=0 \
27514                         --size=$((size/njobs))M \
27515                         --filename=$DIR/$tfile &
27516                 bg_pid=$!
27517
27518                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27519                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27520                         --numjobs=$njobs --fallocate=none \
27521                         --iodepth=16 --allow_file_create=0 \
27522                         --size=$((size/njobs))M \
27523                         --filename=$DIR/$tfile || true
27524                 wait $bg_pid
27525         done
27526
27527         evict=$(do_facet client $LCTL get_param \
27528                 osc.$FSNAME-OST*-osc-*/state |
27529             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27530
27531         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27532                 (do_facet client $LCTL get_param \
27533                         osc.$FSNAME-OST*-osc-*/state;
27534                     error "eviction happened: $evict before:$before")
27535
27536         rm -f $DIR/$tfile
27537 }
27538 run_test 398b "DIO and buffer IO race"
27539
27540 test_398c() { # LU-4198
27541         local ost1_imp=$(get_osc_import_name client ost1)
27542         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27543                          cut -d'.' -f2)
27544
27545         which fio || skip_env "no fio installed"
27546
27547         saved_debug=$($LCTL get_param -n debug)
27548         $LCTL set_param debug=0
27549
27550         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27551         ((size /= 1024)) # by megabytes
27552         ((size /= 2)) # write half of the OST at most
27553         [ $size -gt 40 ] && size=40 #reduce test time anyway
27554
27555         $LFS setstripe -c 1 $DIR/$tfile
27556
27557         # it seems like ldiskfs reserves more space than necessary if the
27558         # writing blocks are not mapped, so it extends the file firstly
27559         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27560         cancel_lru_locks osc
27561
27562         # clear and verify rpc_stats later
27563         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27564
27565         local njobs=4
27566         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27567         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27568                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27569                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27570                 --filename=$DIR/$tfile
27571         [ $? -eq 0 ] || error "fio write error"
27572
27573         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27574                 error "Locks were requested while doing AIO"
27575
27576         # get the percentage of 1-page I/O
27577         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27578                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27579                 awk '{print $7}')
27580         (( $pct <= 50 )) || {
27581                 $LCTL get_param osc.${imp_name}.rpc_stats
27582                 error "$pct% of I/O are 1-page"
27583         }
27584
27585         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27586         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27587                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27588                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27589                 --filename=$DIR/$tfile
27590         [ $? -eq 0 ] || error "fio mixed read write error"
27591
27592         echo "AIO with large block size ${size}M"
27593         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27594                 --numjobs=1 --fallocate=none --ioengine=libaio \
27595                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27596                 --filename=$DIR/$tfile
27597         [ $? -eq 0 ] || error "fio large block size failed"
27598
27599         rm -f $DIR/$tfile
27600         $LCTL set_param debug="$saved_debug"
27601 }
27602 run_test 398c "run fio to test AIO"
27603
27604 test_398d() { #  LU-13846
27605         which aiocp || skip_env "no aiocp installed"
27606         local aio_file=$DIR/$tfile.aio
27607
27608         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27609
27610         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27611         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27612         stack_trap "rm -f $DIR/$tfile $aio_file"
27613
27614         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27615
27616         # test memory unaligned aio
27617         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27618                 error "unaligned aio failed"
27619         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27620
27621         rm -f $DIR/$tfile $aio_file
27622 }
27623 run_test 398d "run aiocp to verify block size > stripe size"
27624
27625 test_398e() {
27626         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27627         touch $DIR/$tfile.new
27628         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27629 }
27630 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27631
27632 test_398f() { #  LU-14687
27633         which aiocp || skip_env "no aiocp installed"
27634         local aio_file=$DIR/$tfile.aio
27635
27636         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27637
27638         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27639         stack_trap "rm -f $DIR/$tfile $aio_file"
27640
27641         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27642         $LCTL set_param fail_loc=0x1418
27643         # make sure we don't crash and fail properly
27644         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27645                 error "aio with page allocation failure succeeded"
27646         $LCTL set_param fail_loc=0
27647         diff $DIR/$tfile $aio_file
27648         [[ $? != 0 ]] || error "no diff after failed aiocp"
27649 }
27650 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27651
27652 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27653 # stripe and i/o size must be > stripe size
27654 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27655 # single RPC in flight.  This test shows async DIO submission is working by
27656 # showing multiple RPCs in flight.
27657 test_398g() { #  LU-13798
27658         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27659
27660         # We need to do some i/o first to acquire enough grant to put our RPCs
27661         # in flight; otherwise a new connection may not have enough grant
27662         # available
27663         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27664                 error "parallel dio failed"
27665         stack_trap "rm -f $DIR/$tfile"
27666
27667         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27668         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27669         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27670         stack_trap "$LCTL set_param -n $pages_per_rpc"
27671
27672         # Recreate file so it's empty
27673         rm -f $DIR/$tfile
27674         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27675         #Pause rpc completion to guarantee we see multiple rpcs in flight
27676         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27677         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27678         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27679
27680         # Clear rpc stats
27681         $LCTL set_param osc.*.rpc_stats=c
27682
27683         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27684                 error "parallel dio failed"
27685         stack_trap "rm -f $DIR/$tfile"
27686
27687         $LCTL get_param osc.*-OST0000-*.rpc_stats
27688         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27689                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27690                 grep "8:" | awk '{print $8}')
27691         # We look at the "8 rpcs in flight" field, and verify A) it is present
27692         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27693         # as expected for an 8M DIO to a file with 1M stripes.
27694         # NB: There is occasionally a mystery extra write RPC to a different
27695         # file.  I can't identify why that's happening, so we set up a margin
27696         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27697         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27698
27699         # Verify turning off parallel dio works as expected
27700         # Clear rpc stats
27701         $LCTL set_param osc.*.rpc_stats=c
27702         $LCTL set_param llite.*.parallel_dio=0
27703         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27704
27705         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27706                 error "dio with parallel dio disabled failed"
27707
27708         # Ideally, we would see only one RPC in flight here, but there is an
27709         # unavoidable race between i/o completion and RPC in flight counting,
27710         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27711         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27712         # So instead we just verify it's always < 8.
27713         $LCTL get_param osc.*-OST0000-*.rpc_stats
27714         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27715                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27716                 grep '^$' -B1 | grep . | awk '{print $1}')
27717         [ $ret != "8:" ] ||
27718                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27719 }
27720 run_test 398g "verify parallel dio async RPC submission"
27721
27722 test_398h() { #  LU-13798
27723         local dio_file=$DIR/$tfile.dio
27724
27725         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27726
27727         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27728         stack_trap "rm -f $DIR/$tfile $dio_file"
27729
27730         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27731                 error "parallel dio failed"
27732         diff $DIR/$tfile $dio_file
27733         [[ $? == 0 ]] || error "file diff after aiocp"
27734 }
27735 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27736
27737 test_398i() { #  LU-13798
27738         local dio_file=$DIR/$tfile.dio
27739
27740         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27741
27742         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27743         stack_trap "rm -f $DIR/$tfile $dio_file"
27744
27745         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27746         $LCTL set_param fail_loc=0x1418
27747         # make sure we don't crash and fail properly
27748         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27749                 error "parallel dio page allocation failure succeeded"
27750         diff $DIR/$tfile $dio_file
27751         [[ $? != 0 ]] || error "no diff after failed aiocp"
27752 }
27753 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27754
27755 test_398j() { #  LU-13798
27756         # Stripe size > RPC size but less than i/o size tests split across
27757         # stripes and RPCs for individual i/o op
27758         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27759
27760         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27761         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27762         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27763         stack_trap "$LCTL set_param -n $pages_per_rpc"
27764
27765         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27766                 error "parallel dio write failed"
27767         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27768
27769         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27770                 error "parallel dio read failed"
27771         diff $DIR/$tfile $DIR/$tfile.2
27772         [[ $? == 0 ]] || error "file diff after parallel dio read"
27773 }
27774 run_test 398j "test parallel dio where stripe size > rpc_size"
27775
27776 test_398k() { #  LU-13798
27777         wait_delete_completed
27778         wait_mds_ost_sync
27779
27780         # 4 stripe file; we will cause out of space on OST0
27781         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27782
27783         # Fill OST0 (if it's not too large)
27784         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27785                    head -n1)
27786         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27787                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27788         fi
27789         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27790         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27791                 error "dd should fill OST0"
27792         stack_trap "rm -f $DIR/$tfile.1"
27793
27794         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27795         err=$?
27796
27797         ls -la $DIR/$tfile
27798         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27799                 error "file is not 0 bytes in size"
27800
27801         # dd above should not succeed, but don't error until here so we can
27802         # get debug info above
27803         [[ $err != 0 ]] ||
27804                 error "parallel dio write with enospc succeeded"
27805         stack_trap "rm -f $DIR/$tfile"
27806 }
27807 run_test 398k "test enospc on first stripe"
27808
27809 test_398l() { #  LU-13798
27810         wait_delete_completed
27811         wait_mds_ost_sync
27812
27813         # 4 stripe file; we will cause out of space on OST0
27814         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27815         # happens on the second i/o chunk we issue
27816         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27817
27818         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27819         stack_trap "rm -f $DIR/$tfile"
27820
27821         # Fill OST0 (if it's not too large)
27822         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27823                    head -n1)
27824         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27825                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27826         fi
27827         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27828         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27829                 error "dd should fill OST0"
27830         stack_trap "rm -f $DIR/$tfile.1"
27831
27832         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27833         err=$?
27834         stack_trap "rm -f $DIR/$tfile.2"
27835
27836         # Check that short write completed as expected
27837         ls -la $DIR/$tfile.2
27838         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27839                 error "file is not 1M in size"
27840
27841         # dd above should not succeed, but don't error until here so we can
27842         # get debug info above
27843         [[ $err != 0 ]] ||
27844                 error "parallel dio write with enospc succeeded"
27845
27846         # Truncate source file to same length as output file and diff them
27847         $TRUNCATE $DIR/$tfile 1048576
27848         diff $DIR/$tfile $DIR/$tfile.2
27849         [[ $? == 0 ]] || error "data incorrect after short write"
27850 }
27851 run_test 398l "test enospc on intermediate stripe/RPC"
27852
27853 test_398m() { #  LU-13798
27854         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27855
27856         # Set up failure on OST0, the first stripe:
27857         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27858         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27859         # OST0 is on ost1, OST1 is on ost2.
27860         # So this fail_val specifies OST0
27861         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27862         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27863
27864         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27865                 error "parallel dio write with failure on first stripe succeeded"
27866         stack_trap "rm -f $DIR/$tfile"
27867         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27868
27869         # Place data in file for read
27870         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27871                 error "parallel dio write failed"
27872
27873         # Fail read on OST0, first stripe
27874         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27875         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27876         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27877                 error "parallel dio read with error on first stripe succeeded"
27878         rm -f $DIR/$tfile.2
27879         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27880
27881         # Switch to testing on OST1, second stripe
27882         # Clear file contents, maintain striping
27883         echo > $DIR/$tfile
27884         # Set up failure on OST1, second stripe:
27885         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27886         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27887
27888         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27889                 error "parallel dio write with failure on second stripe succeeded"
27890         stack_trap "rm -f $DIR/$tfile"
27891         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27892
27893         # Place data in file for read
27894         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27895                 error "parallel dio write failed"
27896
27897         # Fail read on OST1, second stripe
27898         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27899         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27900         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27901                 error "parallel dio read with error on second stripe succeeded"
27902         rm -f $DIR/$tfile.2
27903         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27904 }
27905 run_test 398m "test RPC failures with parallel dio"
27906
27907 # Parallel submission of DIO should not cause problems for append, but it's
27908 # important to verify.
27909 test_398n() { #  LU-13798
27910         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27911
27912         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27913                 error "dd to create source file failed"
27914         stack_trap "rm -f $DIR/$tfile"
27915
27916         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27917                 error "parallel dio write with failure on second stripe succeeded"
27918         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27919         diff $DIR/$tfile $DIR/$tfile.1
27920         [[ $? == 0 ]] || error "data incorrect after append"
27921
27922 }
27923 run_test 398n "test append with parallel DIO"
27924
27925 test_398o() {
27926         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27927 }
27928 run_test 398o "right kms with DIO"
27929
27930 test_398p()
27931 {
27932         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27933         which aiocp || skip_env "no aiocp installed"
27934
27935         local stripe_size=$((1024 * 1024)) #1 MiB
27936         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27937         local file_size=$((25 * stripe_size))
27938
27939         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27940         stack_trap "rm -f $DIR/$tfile*"
27941         # Just a bit bigger than the largest size in the test set below
27942         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27943                 error "buffered i/o to create file failed"
27944
27945         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27946                 $((stripe_size * 4)); do
27947
27948                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27949
27950                 echo "bs: $bs, file_size $file_size"
27951                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27952                         $DIR/$tfile.1 $DIR/$tfile.2 &
27953                 pid_dio1=$!
27954                 # Buffered I/O with similar but not the same block size
27955                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27956                         conv=notrunc &
27957                 pid_bio2=$!
27958                 wait $pid_dio1
27959                 rc1=$?
27960                 wait $pid_bio2
27961                 rc2=$?
27962                 if (( rc1 != 0 )); then
27963                         error "aio copy 1 w/bsize $bs failed: $rc1"
27964                 fi
27965                 if (( rc2 != 0 )); then
27966                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27967                 fi
27968
27969                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27970                         error "size incorrect"
27971                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27972                         error "files differ, bsize $bs"
27973                 rm -f $DIR/$tfile.2
27974         done
27975 }
27976 run_test 398p "race aio with buffered i/o"
27977
27978 test_398q()
27979 {
27980         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27981
27982         local stripe_size=$((1024 * 1024)) #1 MiB
27983         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27984         local file_size=$((25 * stripe_size))
27985
27986         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27987         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27988
27989         # Just a bit bigger than the largest size in the test set below
27990         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27991                 error "buffered i/o to create file failed"
27992
27993         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27994                 $((stripe_size * 4)); do
27995
27996                 echo "bs: $bs, file_size $file_size"
27997                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27998                         conv=notrunc oflag=direct iflag=direct &
27999                 pid_dio1=$!
28000                 # Buffered I/O with similar but not the same block size
28001                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
28002                         conv=notrunc &
28003                 pid_bio2=$!
28004                 wait $pid_dio1
28005                 rc1=$?
28006                 wait $pid_bio2
28007                 rc2=$?
28008                 if (( rc1 != 0 )); then
28009                         error "dio copy 1 w/bsize $bs failed: $rc1"
28010                 fi
28011                 if (( rc2 != 0 )); then
28012                         error "buffered copy 2 w/bsize $bs failed: $rc2"
28013                 fi
28014
28015                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
28016                         error "size incorrect"
28017                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
28018                         error "files differ, bsize $bs"
28019         done
28020
28021         rm -f $DIR/$tfile*
28022 }
28023 run_test 398q "race dio with buffered i/o"
28024
28025 test_398r() {
28026         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
28027         echo "hello, world" > $DIR/$tfile
28028
28029         cancel_lru_locks osc
28030
28031 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28032         do_facet ost1 $LCTL set_param fail_loc=0x20f
28033         cat $DIR/$tfile > /dev/null && error "cat should fail"
28034         return 0
28035 }
28036 run_test 398r "i/o error on file read"
28037
28038 test_398s() {
28039         [[ $OSTCOUNT -ge 2 && "$ost1_HOST" = "$ost2_HOST" ]] ||
28040                 skip "remote OST"
28041
28042         $LFS mirror create -N -i 0 -c 1 -N -i 1 -c 1 $DIR/$tfile ||
28043                 error "mirror create failed"
28044
28045         echo "hello, world" > $DIR/$tfile
28046         $LFS mirror resync $DIR/$tfile || error "mirror resync failed"
28047
28048         cancel_lru_locks osc
28049
28050 #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
28051         do_facet ost1 $LCTL set_param fail_loc=0x20f
28052         cat $DIR/$tfile > /dev/null && error "cat should fail"
28053         return 0
28054 }
28055 run_test 398s "i/o error on mirror file read"
28056
28057 test_fake_rw() {
28058         local read_write=$1
28059         if [ "$read_write" = "write" ]; then
28060                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
28061         elif [ "$read_write" = "read" ]; then
28062                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
28063         else
28064                 error "argument error"
28065         fi
28066
28067         # turn off debug for performance testing
28068         local saved_debug=$($LCTL get_param -n debug)
28069         $LCTL set_param debug=0
28070
28071         $LFS setstripe -c 1 -i 0 $DIR/$tfile
28072
28073         # get ost1 size - $FSNAME-OST0000
28074         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
28075         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
28076         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
28077
28078         if [ "$read_write" = "read" ]; then
28079                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
28080         fi
28081
28082         local start_time=$(date +%s.%N)
28083         $dd_cmd bs=1M count=$blocks oflag=sync ||
28084                 error "real dd $read_write error"
28085         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
28086
28087         if [ "$read_write" = "write" ]; then
28088                 rm -f $DIR/$tfile
28089         fi
28090
28091         # define OBD_FAIL_OST_FAKE_RW           0x238
28092         do_facet ost1 $LCTL set_param fail_loc=0x238
28093
28094         local start_time=$(date +%s.%N)
28095         $dd_cmd bs=1M count=$blocks oflag=sync ||
28096                 error "fake dd $read_write error"
28097         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
28098
28099         if [ "$read_write" = "write" ]; then
28100                 # verify file size
28101                 cancel_lru_locks osc
28102                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
28103                         error "$tfile size not $blocks MB"
28104         fi
28105         do_facet ost1 $LCTL set_param fail_loc=0
28106
28107         echo "fake $read_write $duration_fake vs. normal $read_write" \
28108                 "$duration in seconds"
28109         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
28110                 error_not_in_vm "fake write is slower"
28111
28112         $LCTL set_param -n debug="$saved_debug"
28113         rm -f $DIR/$tfile
28114 }
28115 test_399a() { # LU-7655 for OST fake write
28116         remote_ost_nodsh && skip "remote OST with nodsh"
28117
28118         test_fake_rw write
28119 }
28120 run_test 399a "fake write should not be slower than normal write"
28121
28122 test_399b() { # LU-8726 for OST fake read
28123         remote_ost_nodsh && skip "remote OST with nodsh"
28124         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
28125                 skip_env "ldiskfs only test"
28126         fi
28127
28128         test_fake_rw read
28129 }
28130 run_test 399b "fake read should not be slower than normal read"
28131
28132 test_400a() { # LU-1606, was conf-sanity test_74
28133         if ! which $CC > /dev/null 2>&1; then
28134                 skip_env "$CC is not installed"
28135         fi
28136
28137         local extra_flags=''
28138         local out=$TMP/$tfile
28139         local prefix=/usr/include/lustre
28140         local prog
28141
28142         # Oleg removes .c files in his test rig so test if any c files exist
28143         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
28144                 skip_env "Needed .c test files are missing"
28145
28146         if ! [[ -d $prefix ]]; then
28147                 # Assume we're running in tree and fixup the include path.
28148                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
28149                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
28150                 extra_flags+=" -L$LUSTRE/utils/.libs"
28151         fi
28152
28153         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
28154                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
28155                         error "client api broken"
28156         done
28157         rm -f $out
28158 }
28159 run_test 400a "Lustre client api program can compile and link"
28160
28161 test_400b() { # LU-1606, LU-5011
28162         local header
28163         local out=$TMP/$tfile
28164         local prefix=/usr/include/linux/lustre
28165
28166         # We use a hard coded prefix so that this test will not fail
28167         # when run in tree. There are headers in lustre/include/lustre/
28168         # that are not packaged (like lustre_idl.h) and have more
28169         # complicated include dependencies (like config.h and lnet/types.h).
28170         # Since this test about correct packaging we just skip them when
28171         # they don't exist (see below) rather than try to fixup cppflags.
28172
28173         if ! which $CC > /dev/null 2>&1; then
28174                 skip_env "$CC is not installed"
28175         fi
28176
28177         for header in $prefix/*.h; do
28178                 if ! [[ -f "$header" ]]; then
28179                         continue
28180                 fi
28181
28182                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28183                         continue # lustre_ioctl.h is internal header
28184                 fi
28185
28186                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28187                         error "cannot compile '$header'"
28188         done
28189         rm -f $out
28190 }
28191 run_test 400b "packaged headers can be compiled"
28192
28193 test_401a() { #LU-7437
28194         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28195         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28196
28197         #count the number of parameters by "list_param -R"
28198         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28199         #count the number of parameters by listing proc files
28200         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28201         echo "proc_dirs='$proc_dirs'"
28202         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28203         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28204                       sort -u | wc -l)
28205
28206         [ $params -eq $procs ] ||
28207                 error "found $params parameters vs. $procs proc files"
28208
28209         # test the list_param -D option only returns directories
28210         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28211         #count the number of parameters by listing proc directories
28212         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28213                 sort -u | wc -l)
28214
28215         [ $params -eq $procs ] ||
28216                 error "found $params parameters vs. $procs proc files"
28217 }
28218 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28219
28220 test_401b() {
28221         # jobid_var may not allow arbitrary values, so use jobid_name
28222         # if available
28223         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28224                 local testname=jobid_name tmp='testing%p'
28225         else
28226                 local testname=jobid_var tmp=testing
28227         fi
28228
28229         local save=$($LCTL get_param -n $testname)
28230
28231         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28232                 error "no error returned when setting bad parameters"
28233
28234         local jobid_new=$($LCTL get_param -n foe $testname baz)
28235         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28236
28237         $LCTL set_param -n fog=bam $testname=$save bat=fog
28238         local jobid_old=$($LCTL get_param -n foe $testname bag)
28239         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28240 }
28241 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28242
28243 test_401c() {
28244         # jobid_var may not allow arbitrary values, so use jobid_name
28245         # if available
28246         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28247                 local testname=jobid_name
28248         else
28249                 local testname=jobid_var
28250         fi
28251
28252         local jobid_var_old=$($LCTL get_param -n $testname)
28253         local jobid_var_new
28254
28255         $LCTL set_param $testname= &&
28256                 error "no error returned for 'set_param a='"
28257
28258         jobid_var_new=$($LCTL get_param -n $testname)
28259         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28260                 error "$testname was changed by setting without value"
28261
28262         $LCTL set_param $testname &&
28263                 error "no error returned for 'set_param a'"
28264
28265         jobid_var_new=$($LCTL get_param -n $testname)
28266         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28267                 error "$testname was changed by setting without value"
28268 }
28269 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28270
28271 test_401d() {
28272         # jobid_var may not allow arbitrary values, so use jobid_name
28273         # if available
28274         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28275                 local testname=jobid_name new_value='foo=bar%p'
28276         else
28277                 local testname=jobid_var new_valuie=foo=bar
28278         fi
28279
28280         local jobid_var_old=$($LCTL get_param -n $testname)
28281         local jobid_var_new
28282
28283         $LCTL set_param $testname=$new_value ||
28284                 error "'set_param a=b' did not accept a value containing '='"
28285
28286         jobid_var_new=$($LCTL get_param -n $testname)
28287         [[ "$jobid_var_new" == "$new_value" ]] ||
28288                 error "'set_param a=b' failed on a value containing '='"
28289
28290         # Reset the $testname to test the other format
28291         $LCTL set_param $testname=$jobid_var_old
28292         jobid_var_new=$($LCTL get_param -n $testname)
28293         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28294                 error "failed to reset $testname"
28295
28296         $LCTL set_param $testname $new_value ||
28297                 error "'set_param a b' did not accept a value containing '='"
28298
28299         jobid_var_new=$($LCTL get_param -n $testname)
28300         [[ "$jobid_var_new" == "$new_value" ]] ||
28301                 error "'set_param a b' failed on a value containing '='"
28302
28303         $LCTL set_param $testname $jobid_var_old
28304         jobid_var_new=$($LCTL get_param -n $testname)
28305         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28306                 error "failed to reset $testname"
28307 }
28308 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28309
28310 test_401e() { # LU-14779
28311         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28312                 error "lctl list_param MGC* failed"
28313         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28314         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28315                 error "lctl get_param lru_size failed"
28316 }
28317 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28318
28319 test_402() {
28320         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28321         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28322                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28323         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28324                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28325                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28326         remote_mds_nodsh && skip "remote MDS with nodsh"
28327
28328         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28329 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28330         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28331         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28332                 echo "Touch failed - OK"
28333 }
28334 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28335
28336 test_403() {
28337         local file1=$DIR/$tfile.1
28338         local file2=$DIR/$tfile.2
28339         local tfile=$TMP/$tfile
28340
28341         rm -f $file1 $file2 $tfile
28342
28343         touch $file1
28344         ln $file1 $file2
28345
28346         # 30 sec OBD_TIMEOUT in ll_getattr()
28347         # right before populating st_nlink
28348         $LCTL set_param fail_loc=0x80001409
28349         stat -c %h $file1 > $tfile &
28350
28351         # create an alias, drop all locks and reclaim the dentry
28352         < $file2
28353         cancel_lru_locks mdc
28354         cancel_lru_locks osc
28355         sysctl -w vm.drop_caches=2
28356
28357         wait
28358
28359         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28360
28361         rm -f $tfile $file1 $file2
28362 }
28363 run_test 403 "i_nlink should not drop to zero due to aliasing"
28364
28365 test_404() { # LU-6601
28366         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28367                 skip "Need server version newer than 2.8.52"
28368         remote_mds_nodsh && skip "remote MDS with nodsh"
28369
28370         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28371                 awk '/osp .*-osc-MDT/ { print $4}')
28372
28373         local osp
28374         for osp in $mosps; do
28375                 echo "Deactivate: " $osp
28376                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28377                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28378                         awk -vp=$osp '$4 == p { print $2 }')
28379                 [ $stat = IN ] || {
28380                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28381                         error "deactivate error"
28382                 }
28383                 echo "Activate: " $osp
28384                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28385                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28386                         awk -vp=$osp '$4 == p { print $2 }')
28387                 [ $stat = UP ] || {
28388                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28389                         error "activate error"
28390                 }
28391         done
28392 }
28393 run_test 404 "validate manual {de}activated works properly for OSPs"
28394
28395 test_405() {
28396         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28397         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28398                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28399                         skip "Layout swap lock is not supported"
28400
28401         check_swap_layouts_support
28402         check_swap_layout_no_dom $DIR
28403
28404         test_mkdir $DIR/$tdir
28405         swap_lock_test -d $DIR/$tdir ||
28406                 error "One layout swap locked test failed"
28407 }
28408 run_test 405 "Various layout swap lock tests"
28409
28410 test_406() {
28411         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28412         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28413         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28415         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28416                 skip "Need MDS version at least 2.8.50"
28417
28418         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28419         local test_pool=$TESTNAME
28420
28421         pool_add $test_pool || error "pool_add failed"
28422         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28423                 error "pool_add_targets failed"
28424
28425         save_layout_restore_at_exit $MOUNT
28426
28427         # parent set default stripe count only, child will stripe from both
28428         # parent and fs default
28429         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28430                 error "setstripe $MOUNT failed"
28431         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28432         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28433         for i in $(seq 10); do
28434                 local f=$DIR/$tdir/$tfile.$i
28435                 touch $f || error "touch failed"
28436                 local count=$($LFS getstripe -c $f)
28437                 [ $count -eq $OSTCOUNT ] ||
28438                         error "$f stripe count $count != $OSTCOUNT"
28439                 local offset=$($LFS getstripe -i $f)
28440                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28441                 local size=$($LFS getstripe -S $f)
28442                 [ $size -eq $((def_stripe_size * 2)) ] ||
28443                         error "$f stripe size $size != $((def_stripe_size * 2))"
28444                 local pool=$($LFS getstripe -p $f)
28445                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28446         done
28447
28448         # change fs default striping, delete parent default striping, now child
28449         # will stripe from new fs default striping only
28450         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28451                 error "change $MOUNT default stripe failed"
28452         $LFS setstripe -c 0 $DIR/$tdir ||
28453                 error "delete $tdir default stripe failed"
28454         for i in $(seq 11 20); do
28455                 local f=$DIR/$tdir/$tfile.$i
28456                 touch $f || error "touch $f failed"
28457                 local count=$($LFS getstripe -c $f)
28458                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28459                 local offset=$($LFS getstripe -i $f)
28460                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28461                 local size=$($LFS getstripe -S $f)
28462                 [ $size -eq $def_stripe_size ] ||
28463                         error "$f stripe size $size != $def_stripe_size"
28464                 local pool=$($LFS getstripe -p $f)
28465                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28466         done
28467
28468         unlinkmany $DIR/$tdir/$tfile. 1 20
28469
28470         local f=$DIR/$tdir/$tfile
28471         pool_remove_all_targets $test_pool $f
28472         pool_remove $test_pool $f
28473 }
28474 run_test 406 "DNE support fs default striping"
28475
28476 test_407() {
28477         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28478         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28479                 skip "Need MDS version at least 2.8.55"
28480         remote_mds_nodsh && skip "remote MDS with nodsh"
28481
28482         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28483                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28484         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28485                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28486         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28487
28488         #define OBD_FAIL_DT_TXN_STOP    0x2019
28489         for idx in $(seq $MDSCOUNT); do
28490                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28491         done
28492         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28493         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28494                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28495         true
28496 }
28497 run_test 407 "transaction fail should cause operation fail"
28498
28499 test_408() {
28500         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28501
28502         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28503         lctl set_param fail_loc=0x8000040a
28504         # let ll_prepare_partial_page() fail
28505         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28506
28507         rm -f $DIR/$tfile
28508
28509         # create at least 100 unused inodes so that
28510         # shrink_icache_memory(0) should not return 0
28511         touch $DIR/$tfile-{0..100}
28512         rm -f $DIR/$tfile-{0..100}
28513         sync
28514
28515         echo 2 > /proc/sys/vm/drop_caches
28516 }
28517 run_test 408 "drop_caches should not hang due to page leaks"
28518
28519 test_409()
28520 {
28521         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28522
28523         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28524         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28525         touch $DIR/$tdir/guard || error "(2) Fail to create"
28526
28527         local PREFIX=$(str_repeat 'A' 128)
28528         echo "Create 1K hard links start at $(date)"
28529         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28530                 error "(3) Fail to hard link"
28531
28532         echo "Links count should be right although linkEA overflow"
28533         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28534         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28535         [ $linkcount -eq 1001 ] ||
28536                 error "(5) Unexpected hard links count: $linkcount"
28537
28538         echo "List all links start at $(date)"
28539         ls -l $DIR/$tdir/foo > /dev/null ||
28540                 error "(6) Fail to list $DIR/$tdir/foo"
28541
28542         echo "Unlink hard links start at $(date)"
28543         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28544                 error "(7) Fail to unlink"
28545         echo "Unlink hard links finished at $(date)"
28546 }
28547 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28548
28549 test_410()
28550 {
28551         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28552                 skip "Need client version at least 2.9.59"
28553
28554         # Create a file, and stat it from the kernel
28555         local testfile=$DIR/$tfile
28556         touch $testfile
28557
28558         local run_id=$RANDOM
28559         local my_ino=$(stat --format "%i" $testfile)
28560
28561         # Try to insert the module.
28562         load_module kunit/kinode run_id=$run_id fname=$testfile ||
28563                 error "load_module failed"
28564
28565         # Anything but success is a test failure
28566         dmesg | grep -q \
28567             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28568             error "no inode match"
28569
28570         # Remove the test module
28571         rmmod -v kinode ||
28572                 error "rmmod failed (may trigger a failure in a later test)"
28573 }
28574 run_test 410 "Test inode number returned from kernel thread"
28575
28576 cleanup_test411_cgroup() {
28577         trap 0
28578         cat $1/memory.stat
28579         rmdir "$1"
28580 }
28581
28582 test_411a() {
28583         local cg_basedir=/sys/fs/cgroup/memory
28584         # LU-9966
28585         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28586                 skip "no setup for cgroup"
28587
28588         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28589                 error "test file creation failed"
28590         cancel_lru_locks osc
28591
28592         # Create a very small memory cgroup to force a slab allocation error
28593         local cgdir=$cg_basedir/osc_slab_alloc
28594         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28595         trap "cleanup_test411_cgroup $cgdir" EXIT
28596         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28597         echo 1M > $cgdir/memory.limit_in_bytes
28598
28599         # Should not LBUG, just be killed by oom-killer
28600         # dd will return 0 even allocation failure in some environment.
28601         # So don't check return value
28602         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28603         cleanup_test411_cgroup $cgdir
28604
28605         return 0
28606 }
28607 run_test 411a "Slab allocation error with cgroup does not LBUG"
28608
28609 test_411b() {
28610         local cg_basedir=/sys/fs/cgroup/memory
28611         # LU-9966
28612         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28613                 skip "no setup for cgroup"
28614         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28615         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28616         # limit, so we have 384M in cgroup
28617         # (arm) this seems to hit OOM more often than x86, so 1024M
28618         if [[ $(uname -m) = aarch64 ]]; then
28619                 local memlimit_mb=1024
28620         else
28621                 local memlimit_mb=384
28622         fi
28623
28624         # Create a cgroup and set memory limit
28625         # (tfile is used as an easy way to get a recognizable cgroup name)
28626         local cgdir=$cg_basedir/$tfile
28627         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28628         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28629         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28630
28631         echo "writing first file"
28632         # Write a file 4x the memory limit in size
28633         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28634                 error "(1) failed to write successfully"
28635
28636         sync
28637         cancel_lru_locks osc
28638
28639         rm -f $DIR/$tfile
28640         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28641
28642         # Try writing at a larger block size
28643         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28644         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28645         # need *some* memory to do IO in)
28646         echo "writing at larger block size"
28647         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28648                 error "(3) failed to write successfully"
28649
28650         sync
28651         cancel_lru_locks osc
28652         rm -f $DIR/$tfile
28653         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28654
28655         # Try writing multiple files at once
28656         echo "writing multiple files"
28657         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28658         local pid1=$!
28659         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28660         local pid2=$!
28661         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28662         local pid3=$!
28663         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28664         local pid4=$!
28665
28666         wait $pid1
28667         local rc1=$?
28668         wait $pid2
28669         local rc2=$?
28670         wait $pid3
28671         local rc3=$?
28672         wait $pid4
28673         local rc4=$?
28674         if (( rc1 != 0)); then
28675                 error "error $rc1 writing to file from $pid1"
28676         fi
28677         if (( rc2 != 0)); then
28678                 error "error $rc2 writing to file from $pid2"
28679         fi
28680         if (( rc3 != 0)); then
28681                 error "error $rc3 writing to file from $pid3"
28682         fi
28683         if (( rc4 != 0)); then
28684                 error "error $rc4 writing to file from $pid4"
28685         fi
28686
28687         sync
28688         cancel_lru_locks osc
28689
28690         # These files can be large-ish (~1 GiB total), so delete them rather
28691         # than leave for later cleanup
28692         rm -f $DIR/$tfile.*
28693         return 0
28694 }
28695 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28696
28697 test_412() {
28698         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28699         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28700                 skip "Need server version at least 2.10.55"
28701
28702         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28703                 error "mkdir failed"
28704         $LFS getdirstripe $DIR/$tdir
28705         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28706         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28707                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28708         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28709         [ $stripe_count -eq 2 ] ||
28710                 error "expect 2 get $stripe_count"
28711
28712         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28713
28714         local index
28715         local index2
28716
28717         # subdirs should be on the same MDT as parent
28718         for i in $(seq 0 $((MDSCOUNT - 1))); do
28719                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28720                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28721                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28722                 (( index == i )) || error "mdt$i/sub on MDT$index"
28723         done
28724
28725         # stripe offset -1, ditto
28726         for i in {1..10}; do
28727                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28728                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28729                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28730                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28731                 (( index == index2 )) ||
28732                         error "qos$i on MDT$index, sub on MDT$index2"
28733         done
28734
28735         local testdir=$DIR/$tdir/inherit
28736
28737         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28738         # inherit 2 levels
28739         for i in 1 2; do
28740                 testdir=$testdir/s$i
28741                 mkdir $testdir || error "mkdir $testdir failed"
28742                 index=$($LFS getstripe -m $testdir)
28743                 (( index == 1 )) ||
28744                         error "$testdir on MDT$index"
28745         done
28746
28747         # not inherit any more
28748         testdir=$testdir/s3
28749         mkdir $testdir || error "mkdir $testdir failed"
28750         getfattr -d -m dmv $testdir | grep dmv &&
28751                 error "default LMV set on $testdir" || true
28752 }
28753 run_test 412 "mkdir on specific MDTs"
28754
28755 TEST413_COUNT=${TEST413_COUNT:-200}
28756
28757 #
28758 # set_maxage() is used by test_413 only.
28759 # This is a helper function to set maxage. Does not return any value.
28760 # Input: maxage to set
28761 #
28762 set_maxage() {
28763         local lmv_qos_maxage
28764         local lod_qos_maxage
28765         local new_maxage=$1
28766
28767         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28768         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28769         stack_trap "$LCTL set_param \
28770                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28771         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28772                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28773         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28774                 lod.*.mdt_qos_maxage=$new_maxage
28775         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28776                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28777 }
28778
28779 generate_uneven_mdts() {
28780         local threshold=$1
28781         local ffree
28782         local bavail
28783         local max
28784         local min
28785         local max_index
28786         local min_index
28787         local tmp
28788         local i
28789
28790         echo
28791         echo "Check for uneven MDTs: "
28792
28793         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28794         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28795         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28796
28797         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28798         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28799         max_index=0
28800         min_index=0
28801         for ((i = 1; i < ${#ffree[@]}; i++)); do
28802                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28803                 if [ $tmp -gt $max ]; then
28804                         max=$tmp
28805                         max_index=$i
28806                 fi
28807                 if [ $tmp -lt $min ]; then
28808                         min=$tmp
28809                         min_index=$i
28810                 fi
28811         done
28812
28813         (( min > 0 )) || skip "low space on MDT$min_index"
28814         (( ${ffree[min_index]} > 0 )) ||
28815                 skip "no free files on MDT$min_index"
28816         (( ${ffree[min_index]} < 10000000 )) ||
28817                 skip "too many free files on MDT$min_index"
28818
28819         # Check if we need to generate uneven MDTs
28820         local diff=$(((max - min) * 100 / min))
28821         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28822         local testdir # individual folder within $testdirp
28823         local start
28824         local cmd
28825
28826         # fallocate is faster to consume space on MDT, if available
28827         if check_fallocate_supported mds$((min_index + 1)); then
28828                 cmd="fallocate -l 128K "
28829         else
28830                 cmd="dd if=/dev/zero bs=128K count=1 of="
28831         fi
28832
28833         echo "using cmd $cmd"
28834         for (( i = 0; diff < threshold; i++ )); do
28835                 testdir=${testdirp}/$i
28836                 [ -d $testdir ] && continue
28837
28838                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28839
28840                 mkdir -p $testdirp
28841                 # generate uneven MDTs, create till $threshold% diff
28842                 echo -n "weight diff=$diff% must be > $threshold% ..."
28843                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28844                 $LFS mkdir -i $min_index $testdir ||
28845                         error "mkdir $testdir failed"
28846                 $LFS setstripe -E 1M -L mdt $testdir ||
28847                         error "setstripe $testdir failed"
28848                 start=$SECONDS
28849                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28850                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28851                 done
28852                 sync; sleep 1; sync
28853
28854                 # wait for QOS to update
28855                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28856
28857                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28858                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28859                 max=$(((${ffree[max_index]} >> 8) *
28860                         (${bavail[max_index]} * bsize >> 16)))
28861                 min=$(((${ffree[min_index]} >> 8) *
28862                         (${bavail[min_index]} * bsize >> 16)))
28863                 (( min > 0 )) || skip "low space on MDT$min_index"
28864                 diff=$(((max - min) * 100 / min))
28865         done
28866
28867         echo "MDT filesfree available: ${ffree[*]}"
28868         echo "MDT blocks available: ${bavail[*]}"
28869         echo "weight diff=$diff%"
28870 }
28871
28872 test_qos_mkdir() {
28873         local mkdir_cmd=$1
28874         local stripe_count=$2
28875         local mdts=$(comma_list $(mdts_nodes))
28876
28877         local testdir
28878         local lmv_qos_prio_free
28879         local lmv_qos_threshold_rr
28880         local lod_qos_prio_free
28881         local lod_qos_threshold_rr
28882         local total
28883         local count
28884         local i
28885
28886         # @total is total directories created if it's testing plain
28887         # directories, otherwise it's total stripe object count for
28888         # striped directories test.
28889         # remote/striped directory unlinking is slow on zfs and may
28890         # timeout, test with fewer directories
28891         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28892
28893         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28894         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28895         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28896                 head -n1)
28897         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28898         stack_trap "$LCTL set_param \
28899                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28900         stack_trap "$LCTL set_param \
28901                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28902
28903         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28904                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28905         lod_qos_prio_free=${lod_qos_prio_free%%%}
28906         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28907                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28908         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28909         stack_trap "do_nodes $mdts $LCTL set_param \
28910                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28911         stack_trap "do_nodes $mdts $LCTL set_param \
28912                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28913
28914         # decrease statfs age, so that it can be updated in time
28915         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28916         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28917
28918         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28919         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28920
28921         testdir=$DIR/$tdir-s$stripe_count/rr
28922
28923         local stripe_index=$($LFS getstripe -m $testdir)
28924         local test_mkdir_rr=true
28925
28926         getfattr -d -m dmv -e hex $testdir | grep dmv
28927         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28928                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28929                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28930                         test_mkdir_rr=false
28931         fi
28932
28933         echo
28934         $test_mkdir_rr &&
28935                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28936                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28937
28938         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28939         for (( i = 0; i < total / stripe_count; i++ )); do
28940                 eval $mkdir_cmd $testdir/subdir$i ||
28941                         error "$mkdir_cmd subdir$i failed"
28942         done
28943
28944         for (( i = 0; i < $MDSCOUNT; i++ )); do
28945                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28946                 echo "$count directories created on MDT$i"
28947                 if $test_mkdir_rr; then
28948                         (( count == total / stripe_count / MDSCOUNT )) ||
28949                                 error "subdirs are not evenly distributed"
28950                 elif (( i == stripe_index )); then
28951                         (( count == total / stripe_count )) ||
28952                                 error "$count subdirs created on MDT$i"
28953                 else
28954                         (( count == 0 )) ||
28955                                 error "$count subdirs created on MDT$i"
28956                 fi
28957
28958                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28959                         count=$($LFS getdirstripe $testdir/* |
28960                                 grep -c -P "^\s+$i\t")
28961                         echo "$count stripes created on MDT$i"
28962                         # deviation should < 5% of average
28963                         delta=$((count - total / MDSCOUNT))
28964                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28965                                 error "stripes are not evenly distributed"
28966                 fi
28967         done
28968
28969         echo
28970         echo "Check for uneven MDTs: "
28971
28972         local ffree
28973         local bavail
28974         local max
28975         local min
28976         local max_index
28977         local min_index
28978         local tmp
28979
28980         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28981         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28982         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28983
28984         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28985         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28986         max_index=0
28987         min_index=0
28988         for ((i = 1; i < ${#ffree[@]}; i++)); do
28989                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28990                 if [ $tmp -gt $max ]; then
28991                         max=$tmp
28992                         max_index=$i
28993                 fi
28994                 if [ $tmp -lt $min ]; then
28995                         min=$tmp
28996                         min_index=$i
28997                 fi
28998         done
28999         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
29000
29001         (( min > 0 )) || skip "low space on MDT$min_index"
29002         (( ${ffree[min_index]} < 10000000 )) ||
29003                 skip "too many free files on MDT$min_index"
29004
29005         generate_uneven_mdts 120
29006
29007         echo "MDT filesfree available: ${ffree[*]}"
29008         echo "MDT blocks available: ${bavail[*]}"
29009         echo "weight diff=$(((max - min) * 100 / min))%"
29010         echo
29011         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
29012
29013         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
29014         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
29015         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
29016         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
29017
29018         sleep 1
29019
29020         testdir=$DIR/$tdir-s$stripe_count/qos
29021
29022         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
29023         for (( i = 0; i < total / stripe_count; i++ )); do
29024                 eval $mkdir_cmd $testdir/subdir$i ||
29025                         error "$mkdir_cmd subdir$i failed"
29026         done
29027
29028         max=0
29029         for (( i = 0; i < $MDSCOUNT; i++ )); do
29030                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
29031                 (( count > max )) && max=$count
29032                 echo "$count directories created on MDT$i : curmax=$max"
29033         done
29034
29035         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
29036
29037         # D-value should > 10% of average
29038         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
29039                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
29040
29041         # ditto for stripes
29042         if (( stripe_count > 1 )); then
29043                 max=0
29044                 for (( i = 0; i < $MDSCOUNT; i++ )); do
29045                         count=$($LFS getdirstripe $testdir/* |
29046                                 grep -c -P "^\s+$i\t")
29047                         (( count > max )) && max=$count
29048                         echo "$count stripes created on MDT$i"
29049                 done
29050
29051                 min=$($LFS getdirstripe $testdir/* |
29052                         grep -c -P "^\s+$min_index\t")
29053                 (( max - min > total / MDSCOUNT / 10 )) ||
29054                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
29055         fi
29056 }
29057
29058 most_full_mdt() {
29059         local ffree
29060         local bavail
29061         local bsize
29062         local min
29063         local min_index
29064         local tmp
29065
29066         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
29067         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
29068         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
29069
29070         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
29071         min_index=0
29072         for ((i = 1; i < ${#ffree[@]}; i++)); do
29073                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
29074                 (( tmp < min )) && min=$tmp && min_index=$i
29075         done
29076
29077         echo -n $min_index
29078 }
29079
29080 test_413a() {
29081         [ $MDSCOUNT -lt 2 ] &&
29082                 skip "We need at least 2 MDTs for this test"
29083
29084         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29085                 skip "Need server version at least 2.12.52"
29086
29087         local stripe_max=$((MDSCOUNT - 1))
29088         local stripe_count
29089
29090         # let caller set maxage for latest result
29091         set_maxage 1
29092
29093         # fill MDT unevenly
29094         generate_uneven_mdts 120
29095
29096         # test 4-stripe directory at most, otherwise it's too slow
29097         # We are being very defensive. Although Autotest uses 4 MDTs.
29098         # We make sure stripe_max does not go over 4.
29099         (( stripe_max > 4 )) && stripe_max=4
29100         # unlinking striped directory is slow on zfs, and may timeout, only test
29101         # plain directory
29102         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29103         for stripe_count in $(seq 1 $stripe_max); do
29104                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
29105                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
29106                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
29107                         error "mkdir failed"
29108                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
29109         done
29110 }
29111 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
29112
29113 test_413b() {
29114         [ $MDSCOUNT -lt 2 ] &&
29115                 skip "We need at least 2 MDTs for this test"
29116
29117         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
29118                 skip "Need server version at least 2.12.52"
29119
29120         local stripe_max=$((MDSCOUNT - 1))
29121         local testdir
29122         local stripe_count
29123
29124         # let caller set maxage for latest result
29125         set_maxage 1
29126
29127         # fill MDT unevenly
29128         generate_uneven_mdts 120
29129
29130         # test 4-stripe directory at most, otherwise it's too slow
29131         # We are being very defensive. Although Autotest uses 4 MDTs.
29132         # We make sure stripe_max does not go over 4.
29133         (( stripe_max > 4 )) && stripe_max=4
29134         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
29135         for stripe_count in $(seq 1 $stripe_max); do
29136                 testdir=$DIR/$tdir-s$stripe_count
29137                 mkdir $testdir || error "mkdir $testdir failed"
29138                 mkdir $testdir/rr || error "mkdir rr failed"
29139                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
29140                         error "mkdir qos failed"
29141                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
29142                         $testdir/rr || error "setdirstripe rr failed"
29143                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
29144                         error "setdirstripe failed"
29145                 test_qos_mkdir "mkdir" $stripe_count
29146         done
29147 }
29148 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
29149
29150 test_413c() {
29151         (( $MDSCOUNT >= 2 )) ||
29152                 skip "We need at least 2 MDTs for this test"
29153
29154         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
29155                 skip "Need server version at least 2.14.51"
29156
29157         local testdir
29158         local inherit
29159         local inherit_rr
29160         local lmv_qos_maxage
29161         local lod_qos_maxage
29162
29163         # let caller set maxage for latest result
29164         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29165         $LCTL set_param lmv.*.qos_maxage=1
29166         stack_trap "$LCTL set_param \
29167                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29168         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29169                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29170         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29171                 lod.*.mdt_qos_maxage=1
29172         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29173                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29174
29175         # fill MDT unevenly
29176         generate_uneven_mdts 120
29177
29178         testdir=$DIR/${tdir}-s1
29179         mkdir $testdir || error "mkdir $testdir failed"
29180         mkdir $testdir/rr || error "mkdir rr failed"
29181         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29182         # default max_inherit is -1, default max_inherit_rr is 0
29183         $LFS setdirstripe -D -c 1 $testdir/rr ||
29184                 error "setdirstripe rr failed"
29185         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29186                 error "setdirstripe qos failed"
29187         test_qos_mkdir "mkdir" 1
29188
29189         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29190         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29191         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29192         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29193         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29194
29195         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29196         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29197         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29198         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29199         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29200         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29201         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29202                 error "level2 shouldn't have default LMV" || true
29203 }
29204 run_test 413c "mkdir with default LMV max inherit rr"
29205
29206 test_413d() {
29207         (( MDSCOUNT >= 2 )) ||
29208                 skip "We need at least 2 MDTs for this test"
29209
29210         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29211                 skip "Need server version at least 2.14.51"
29212
29213         local lmv_qos_threshold_rr
29214
29215         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29216                 head -n1)
29217         stack_trap "$LCTL set_param \
29218                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29219
29220         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29221         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29222         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29223                 error "$tdir shouldn't have default LMV"
29224         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29225                 error "mkdir sub failed"
29226
29227         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29228
29229         (( count == 100 )) || error "$count subdirs on MDT0"
29230 }
29231 run_test 413d "inherit ROOT default LMV"
29232
29233 test_413e() {
29234         (( MDSCOUNT >= 2 )) ||
29235                 skip "We need at least 2 MDTs for this test"
29236         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29237                 skip "Need server version at least 2.14.55"
29238
29239         local testdir=$DIR/$tdir
29240         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29241         local max_inherit
29242         local sub_max_inherit
29243
29244         mkdir -p $testdir || error "failed to create $testdir"
29245
29246         # set default max-inherit to -1 if stripe count is 0 or 1
29247         $LFS setdirstripe -D -c 1 $testdir ||
29248                 error "failed to set default LMV"
29249         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29250         (( max_inherit == -1 )) ||
29251                 error "wrong max_inherit value $max_inherit"
29252
29253         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29254         $LFS setdirstripe -D -c -1 $testdir ||
29255                 error "failed to set default LMV"
29256         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29257         (( max_inherit > 0 )) ||
29258                 error "wrong max_inherit value $max_inherit"
29259
29260         # and the subdir will decrease the max_inherit by 1
29261         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29262         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29263         (( sub_max_inherit == max_inherit - 1)) ||
29264                 error "wrong max-inherit of subdir $sub_max_inherit"
29265
29266         # check specified --max-inherit and warning message
29267         stack_trap "rm -f $tmpfile"
29268         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29269                 error "failed to set default LMV"
29270         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29271         (( max_inherit == -1 )) ||
29272                 error "wrong max_inherit value $max_inherit"
29273
29274         # check the warning messages
29275         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29276                 error "failed to detect warning string"
29277         fi
29278 }
29279 run_test 413e "check default max-inherit value"
29280
29281 test_fs_dmv_inherit()
29282 {
29283         local testdir=$DIR/$tdir
29284
29285         local count
29286         local inherit
29287         local inherit_rr
29288
29289         for i in 1 2; do
29290                 mkdir $testdir || error "mkdir $testdir failed"
29291                 count=$($LFS getdirstripe -D -c $testdir)
29292                 (( count == 1 )) ||
29293                         error "$testdir default LMV count mismatch $count != 1"
29294                 inherit=$($LFS getdirstripe -D -X $testdir)
29295                 (( inherit == 3 - i )) ||
29296                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29297                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29298                 (( inherit_rr == 3 - i )) ||
29299                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29300                 testdir=$testdir/sub
29301         done
29302
29303         mkdir $testdir || error "mkdir $testdir failed"
29304         count=$($LFS getdirstripe -D -c $testdir)
29305         (( count == 0 )) ||
29306                 error "$testdir default LMV count not zero: $count"
29307 }
29308
29309 test_413f() {
29310         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29311
29312         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29313                 skip "Need server version at least 2.14.55"
29314
29315         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29316                 error "dump $DIR default LMV failed"
29317         stack_trap "setfattr --restore=$TMP/dmv.ea"
29318
29319         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29320                 error "set $DIR default LMV failed"
29321
29322         test_fs_dmv_inherit
29323 }
29324 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29325
29326 test_413g() {
29327         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29328
29329         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29330         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29331                 error "dump $DIR default LMV failed"
29332         stack_trap "setfattr --restore=$TMP/dmv.ea"
29333
29334         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29335                 error "set $DIR default LMV failed"
29336
29337         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29338                 error "mount $MOUNT2 failed"
29339         stack_trap "umount_client $MOUNT2"
29340
29341         local saved_DIR=$DIR
29342
29343         export DIR=$MOUNT2
29344
29345         stack_trap "export DIR=$saved_DIR"
29346
29347         # first check filesystem-wide default LMV inheritance
29348         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29349
29350         # then check subdirs are spread to all MDTs
29351         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29352
29353         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29354
29355         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29356 }
29357 run_test 413g "enforce ROOT default LMV on subdir mount"
29358
29359 test_413h() {
29360         (( MDSCOUNT >= 2 )) ||
29361                 skip "We need at least 2 MDTs for this test"
29362
29363         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29364                 skip "Need server version at least 2.15.50.6"
29365
29366         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29367
29368         stack_trap "$LCTL set_param \
29369                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29370         $LCTL set_param lmv.*.qos_maxage=1
29371
29372         local depth=5
29373         local rr_depth=4
29374         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29375         local count=$((MDSCOUNT * 20))
29376
29377         generate_uneven_mdts 50
29378
29379         mkdir -p $dir || error "mkdir $dir failed"
29380         stack_trap "rm -rf $dir"
29381         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29382                 --max-inherit-rr=$rr_depth $dir
29383
29384         for ((d=0; d < depth + 2; d++)); do
29385                 log "dir=$dir:"
29386                 for ((sub=0; sub < count; sub++)); do
29387                         mkdir $dir/d$sub
29388                 done
29389                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29390                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29391                 # subdirs within $rr_depth should be created round-robin
29392                 if (( d < rr_depth )); then
29393                         (( ${num[0]} != count )) ||
29394                                 error "all objects created on MDT ${num[1]}"
29395                 fi
29396
29397                 dir=$dir/d0
29398         done
29399 }
29400 run_test 413h "don't stick to parent for round-robin dirs"
29401
29402 test_413i() {
29403         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29404
29405         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29406                 skip "Need server version at least 2.14.55"
29407
29408         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29409                 error "dump $DIR default LMV failed"
29410         stack_trap "setfattr --restore=$TMP/dmv.ea"
29411
29412         local testdir=$DIR/$tdir
29413         local def_max_rr=1
29414         local def_max=3
29415         local count
29416
29417         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29418                 --max-inherit-rr=$def_max_rr $DIR ||
29419                 error "set $DIR default LMV failed"
29420
29421         for i in $(seq 2 3); do
29422                 def_max=$((def_max - 1))
29423                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29424
29425                 mkdir $testdir
29426                 # RR is decremented and keeps zeroed once exhausted
29427                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29428                 (( count == def_max_rr )) ||
29429                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29430
29431                 # max-inherit is decremented
29432                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29433                 (( count == def_max )) ||
29434                         error_noexit "$testdir: max-inherit $count != $def_max"
29435
29436                 testdir=$testdir/d$i
29437         done
29438
29439         # d3 is the last inherited from ROOT, no inheritance anymore
29440         # i.e. no the default layout anymore
29441         mkdir -p $testdir/d4/d5
29442         count=$($LFS getdirstripe -D --max-inherit $testdir)
29443         (( count == -1 )) ||
29444                 error_noexit "$testdir: max-inherit $count != -1"
29445
29446         local p_count=$($LFS getdirstripe -i $testdir)
29447
29448         for i in $(seq 4 5); do
29449                 testdir=$testdir/d$i
29450
29451                 # the root default layout is not applied once exhausted
29452                 count=$($LFS getdirstripe -i $testdir)
29453                 (( count == p_count )) ||
29454                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29455         done
29456
29457         $LFS setdirstripe -i 0 $DIR/d2
29458         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29459         (( count == -1 )) ||
29460                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29461 }
29462 run_test 413i "check default layout inheritance"
29463
29464 test_413j()
29465 {
29466         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29467
29468         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29469         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29470                 error "setdirstripe $tdir failed"
29471
29472         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29473                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29474
29475         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29476         # setfattr dmv calls setdirstripe -D
29477         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29478                 error "setfattr sub failed"
29479         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29480                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29481
29482         [ $value == $value2 ] || error "dmv mismatch"
29483
29484         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29485
29486         # do not allow remove dmv by setfattr -x
29487         do_nodes $(comma_list $(mdts_nodes)) \
29488                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29489         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29490         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29491
29492         # allow remove dmv by setfattr -x
29493         do_nodes $(comma_list $(mdts_nodes)) \
29494                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29495         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29496         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29497         do_nodes $(comma_list $(mdts_nodes)) \
29498                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29499 }
29500 run_test 413j "set default LMV by setxattr"
29501
29502 test_413k() {
29503         (( $MDS1_VERSION >= $(version_code 2.15.60) )) ||
29504                 skip "Need server version at least 2.15.60"
29505
29506         local index1
29507         local index2
29508         local old=$($LCTL get_param -n lmv.*.qos_exclude_prefixes)
29509         local count=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29510         local prefixes="abc:123:foo bar"
29511
29512         # add prefixes
29513         stack_trap "$LCTL set_param lmv.*.qos_exclude_prefixes=\"$old\""
29514         $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes"
29515
29516         mkdir $DIR/$tdir || error "mkdir $tdir failed"
29517         index1=$($LFS getstripe -m $DIR/$tdir)
29518         for dname in _temporary _temporary.XXXXXX abc 123 "foo bar"; do
29519                 mkdir "$DIR/$tdir/$dname" || error "mkdir $dname failed"
29520                 index2=$($LFS getstripe -m "$DIR/$tdir/$dname")
29521                 ((index1 == index2)) ||
29522                         error "$tdir on MDT$index1, $dname on MDT$index2"
29523         done
29524
29525         # remove prefixes
29526         $LCTL set_param lmv.*.qos_exclude_prefixes="-$prefixes"
29527
29528         # total prefixes length > PAGE_SIZE can be printed correctly
29529         for c in {a..z}; do
29530                 prefixes=$(str_repeat $c 255)
29531                 $LCTL set_param lmv.*.qos_exclude_prefixes="+$prefixes" >/dev/null
29532         done
29533         local count2=$($LCTL get_param -n lmv.*.qos_exclude_prefixes | wc -l)
29534         ((count2 == count + 26)) ||
29535                 error "prefixes count $count2 != $((count + 26))"
29536 }
29537 run_test 413k "QoS mkdir exclude prefixes"
29538
29539 test_413z() {
29540         local pids=""
29541         local subdir
29542         local pid
29543
29544         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29545                 unlinkmany $subdir/f. $TEST413_COUNT &
29546                 pids="$pids $!"
29547         done
29548
29549         for pid in $pids; do
29550                 wait $pid
29551         done
29552
29553         true
29554 }
29555 run_test 413z "413 test cleanup"
29556
29557 test_414() {
29558 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29559         $LCTL set_param fail_loc=0x80000521
29560         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29561         rm -f $DIR/$tfile
29562 }
29563 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29564
29565 test_415() {
29566         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29567         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29568                 skip "Need server version at least 2.11.52"
29569
29570         # LU-11102
29571         local total=500
29572         local max=120
29573
29574         # this test may be slow on ZFS
29575         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29576
29577         # though this test is designed for striped directory, let's test normal
29578         # directory too since lock is always saved as CoS lock.
29579         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29580         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29581         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29582         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29583         wait_delete_completed_mds
29584
29585         # run a loop without concurrent touch to measure rename duration.
29586         # only for test debug/robustness, NOT part of COS functional test.
29587         local start_time=$SECONDS
29588         for ((i = 0; i < total; i++)); do
29589                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29590                         > /dev/null
29591         done
29592         local baseline=$((SECONDS - start_time))
29593         echo "rename $total files without 'touch' took $baseline sec"
29594
29595         (
29596                 while true; do
29597                         touch $DIR/$tdir
29598                 done
29599         ) &
29600         local setattr_pid=$!
29601
29602         # rename files back to original name so unlinkmany works
29603         start_time=$SECONDS
29604         for ((i = 0; i < total; i++)); do
29605                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29606                         > /dev/null
29607         done
29608         local duration=$((SECONDS - start_time))
29609
29610         kill -9 $setattr_pid
29611
29612         echo "rename $total files with 'touch' took $duration sec"
29613         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29614         (( duration <= max )) ||
29615                 error_not_in_vm "rename took $duration > $max sec"
29616 }
29617 run_test 415 "lock revoke is not missing"
29618
29619 test_416() {
29620         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29621                 skip "Need server version at least 2.11.55"
29622
29623         # define OBD_FAIL_OSD_TXN_START    0x19a
29624         do_facet mds1 lctl set_param fail_loc=0x19a
29625
29626         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29627
29628         true
29629 }
29630 run_test 416 "transaction start failure won't cause system hung"
29631
29632 cleanup_417() {
29633         trap 0
29634         do_nodes $(comma_list $(mdts_nodes)) \
29635                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29636         do_nodes $(comma_list $(mdts_nodes)) \
29637                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29638         do_nodes $(comma_list $(mdts_nodes)) \
29639                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29640 }
29641
29642 test_417() {
29643         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29644         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29645                 skip "Need MDS version at least 2.11.56"
29646
29647         trap cleanup_417 RETURN EXIT
29648
29649         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29650         do_nodes $(comma_list $(mdts_nodes)) \
29651                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29652         $LFS migrate -m 0 $DIR/$tdir.1 &&
29653                 error "migrate dir $tdir.1 should fail"
29654
29655         do_nodes $(comma_list $(mdts_nodes)) \
29656                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29657         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29658                 error "create remote dir $tdir.2 should fail"
29659
29660         do_nodes $(comma_list $(mdts_nodes)) \
29661                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29662         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29663                 error "create striped dir $tdir.3 should fail"
29664         true
29665 }
29666 run_test 417 "disable remote dir, striped dir and dir migration"
29667
29668 # Checks that the outputs of df [-i] and lfs df [-i] match
29669 #
29670 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29671 check_lfs_df() {
29672         local dir=$2
29673         local inodes
29674         local df_out
29675         local lfs_df_out
29676         local count
29677         local passed=false
29678
29679         # blocks or inodes
29680         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29681
29682         for count in {1..100}; do
29683                 do_nodes "$CLIENTS" \
29684                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29685                 sync; sleep 0.2
29686
29687                 # read the lines of interest
29688                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29689                         error "df $inodes $dir | tail -n +2 failed"
29690                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29691                         error "lfs df $inodes $dir | grep summary: failed"
29692
29693                 # skip first substrings of each output as they are different
29694                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29695                 # compare the two outputs
29696                 passed=true
29697                 #  skip "available" on MDT until LU-13997 is fixed.
29698                 #for i in {1..5}; do
29699                 for i in 1 2 4 5; do
29700                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29701                 done
29702                 $passed && break
29703         done
29704
29705         if ! $passed; then
29706                 df -P $inodes $dir
29707                 echo
29708                 lfs df $inodes $dir
29709                 error "df and lfs df $1 output mismatch: "      \
29710                       "df ${inodes}: ${df_out[*]}, "            \
29711                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29712         fi
29713 }
29714
29715 test_418() {
29716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29717
29718         local dir=$DIR/$tdir
29719         local numfiles=$((RANDOM % 4096 + 2))
29720         local numblocks=$((RANDOM % 256 + 1))
29721
29722         wait_delete_completed
29723         test_mkdir $dir
29724
29725         # check block output
29726         check_lfs_df blocks $dir
29727         # check inode output
29728         check_lfs_df inodes $dir
29729
29730         # create a single file and retest
29731         echo "Creating a single file and testing"
29732         createmany -o $dir/$tfile- 1 &>/dev/null ||
29733                 error "creating 1 file in $dir failed"
29734         check_lfs_df blocks $dir
29735         check_lfs_df inodes $dir
29736
29737         # create a random number of files
29738         echo "Creating $((numfiles - 1)) files and testing"
29739         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29740                 error "creating $((numfiles - 1)) files in $dir failed"
29741
29742         # write a random number of blocks to the first test file
29743         echo "Writing $numblocks 4K blocks and testing"
29744         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29745                 count=$numblocks &>/dev/null ||
29746                 error "dd to $dir/${tfile}-0 failed"
29747
29748         # retest
29749         check_lfs_df blocks $dir
29750         check_lfs_df inodes $dir
29751
29752         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29753                 error "unlinking $numfiles files in $dir failed"
29754 }
29755 run_test 418 "df and lfs df outputs match"
29756
29757 test_419()
29758 {
29759         local dir=$DIR/$tdir
29760
29761         mkdir -p $dir
29762         touch $dir/file
29763
29764         cancel_lru_locks mdc
29765
29766         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29767         $LCTL set_param fail_loc=0x1410
29768         cat $dir/file
29769         $LCTL set_param fail_loc=0
29770         rm -rf $dir
29771 }
29772 run_test 419 "Verify open file by name doesn't crash kernel"
29773
29774 test_420()
29775 {
29776         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29777                 skip "Need MDS version at least 2.12.53"
29778
29779         local SAVE_UMASK=$(umask)
29780         local dir=$DIR/$tdir
29781         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29782
29783         mkdir -p $dir
29784         umask 0000
29785         mkdir -m03777 $dir/testdir
29786         ls -dn $dir/testdir
29787         # Need to remove trailing '.' when SELinux is enabled
29788         local dirperms=$(ls -dn $dir/testdir |
29789                          awk '{ sub(/\.$/, "", $1); print $1}')
29790         [ $dirperms == "drwxrwsrwt" ] ||
29791                 error "incorrect perms on $dir/testdir"
29792
29793         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29794                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29795         ls -n $dir/testdir/testfile
29796         local fileperms=$(ls -n $dir/testdir/testfile |
29797                           awk '{ sub(/\.$/, "", $1); print $1}')
29798         [ $fileperms == "-rwxr-xr-x" ] ||
29799                 error "incorrect perms on $dir/testdir/testfile"
29800
29801         umask $SAVE_UMASK
29802 }
29803 run_test 420 "clear SGID bit on non-directories for non-members"
29804
29805 test_421a() {
29806         local cnt
29807         local fid1
29808         local fid2
29809
29810         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29811                 skip "Need MDS version at least 2.12.54"
29812
29813         test_mkdir $DIR/$tdir
29814         createmany -o $DIR/$tdir/f 3
29815         cnt=$(ls -1 $DIR/$tdir | wc -l)
29816         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29817
29818         fid1=$(lfs path2fid $DIR/$tdir/f1)
29819         fid2=$(lfs path2fid $DIR/$tdir/f2)
29820         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29821
29822         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29823         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29824
29825         cnt=$(ls -1 $DIR/$tdir | wc -l)
29826         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29827
29828         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29829         createmany -o $DIR/$tdir/f 3
29830         cnt=$(ls -1 $DIR/$tdir | wc -l)
29831         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29832
29833         fid1=$(lfs path2fid $DIR/$tdir/f1)
29834         fid2=$(lfs path2fid $DIR/$tdir/f2)
29835         echo "remove using fsname $FSNAME"
29836         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29837
29838         cnt=$(ls -1 $DIR/$tdir | wc -l)
29839         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29840 }
29841 run_test 421a "simple rm by fid"
29842
29843 test_421b() {
29844         local cnt
29845         local FID1
29846         local FID2
29847
29848         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29849                 skip "Need MDS version at least 2.12.54"
29850
29851         test_mkdir $DIR/$tdir
29852         createmany -o $DIR/$tdir/f 3
29853         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29854         MULTIPID=$!
29855
29856         FID1=$(lfs path2fid $DIR/$tdir/f1)
29857         FID2=$(lfs path2fid $DIR/$tdir/f2)
29858         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29859
29860         kill -USR1 $MULTIPID
29861         wait
29862
29863         cnt=$(ls $DIR/$tdir | wc -l)
29864         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29865 }
29866 run_test 421b "rm by fid on open file"
29867
29868 test_421c() {
29869         local cnt
29870         local FIDS
29871
29872         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29873                 skip "Need MDS version at least 2.12.54"
29874
29875         test_mkdir $DIR/$tdir
29876         createmany -o $DIR/$tdir/f 3
29877         touch $DIR/$tdir/$tfile
29878         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29879         cnt=$(ls -1 $DIR/$tdir | wc -l)
29880         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29881
29882         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29883         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29884
29885         cnt=$(ls $DIR/$tdir | wc -l)
29886         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29887 }
29888 run_test 421c "rm by fid against hardlinked files"
29889
29890 test_421d() {
29891         local cnt
29892         local FIDS
29893
29894         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29895                 skip "Need MDS version at least 2.12.54"
29896
29897         test_mkdir $DIR/$tdir
29898         createmany -o $DIR/$tdir/f 4097
29899         cnt=$(ls -1 $DIR/$tdir | wc -l)
29900         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29901
29902         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29903         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29904
29905         cnt=$(ls $DIR/$tdir | wc -l)
29906         rm -rf $DIR/$tdir
29907         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29908 }
29909 run_test 421d "rmfid en masse"
29910
29911 test_421e() {
29912         local cnt
29913         local FID
29914
29915         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29916         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29917                 skip "Need MDS version at least 2.12.54"
29918
29919         mkdir -p $DIR/$tdir
29920         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29921         createmany -o $DIR/$tdir/striped_dir/f 512
29922         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29923         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29924
29925         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29926                 sed "s/[/][^:]*://g")
29927         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29928
29929         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29930         rm -rf $DIR/$tdir
29931         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29932 }
29933 run_test 421e "rmfid in DNE"
29934
29935 test_421f() {
29936         local cnt
29937         local FID
29938
29939         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29940                 skip "Need MDS version at least 2.12.54"
29941
29942         test_mkdir $DIR/$tdir
29943         touch $DIR/$tdir/f
29944         cnt=$(ls -1 $DIR/$tdir | wc -l)
29945         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29946
29947         FID=$(lfs path2fid $DIR/$tdir/f)
29948         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29949         # rmfid should fail
29950         cnt=$(ls -1 $DIR/$tdir | wc -l)
29951         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29952
29953         chmod a+rw $DIR/$tdir
29954         ls -la $DIR/$tdir
29955         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29956         # rmfid should fail
29957         cnt=$(ls -1 $DIR/$tdir | wc -l)
29958         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29959
29960         rm -f $DIR/$tdir/f
29961         $RUNAS touch $DIR/$tdir/f
29962         FID=$(lfs path2fid $DIR/$tdir/f)
29963         echo "rmfid as root"
29964         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29965         cnt=$(ls -1 $DIR/$tdir | wc -l)
29966         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29967
29968         rm -f $DIR/$tdir/f
29969         $RUNAS touch $DIR/$tdir/f
29970         cnt=$(ls -1 $DIR/$tdir | wc -l)
29971         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29972         FID=$(lfs path2fid $DIR/$tdir/f)
29973         # rmfid w/o user_fid2path mount option should fail
29974         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29975         cnt=$(ls -1 $DIR/$tdir | wc -l)
29976         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29977
29978         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29979         stack_trap "rmdir $tmpdir"
29980         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29981                 error "failed to mount client'"
29982         stack_trap "umount_client $tmpdir"
29983
29984         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29985         # rmfid should succeed
29986         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29987         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29988
29989         # rmfid shouldn't allow to remove files due to dir's permission
29990         chmod a+rwx $tmpdir/$tdir
29991         touch $tmpdir/$tdir/f
29992         ls -la $tmpdir/$tdir
29993         FID=$(lfs path2fid $tmpdir/$tdir/f)
29994         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29995         return 0
29996 }
29997 run_test 421f "rmfid checks permissions"
29998
29999 test_421g() {
30000         local cnt
30001         local FIDS
30002
30003         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
30004         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
30005                 skip "Need MDS version at least 2.12.54"
30006
30007         mkdir -p $DIR/$tdir
30008         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
30009         createmany -o $DIR/$tdir/striped_dir/f 512
30010         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30011         [ $cnt != 512 ] && error "unexpected #files: $cnt"
30012
30013         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
30014                 sed "s/[/][^:]*://g")
30015
30016         rm -f $DIR/$tdir/striped_dir/f1*
30017         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
30018         removed=$((512 - cnt))
30019
30020         # few files have been just removed, so we expect
30021         # rmfid to fail on their fids
30022         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
30023         [ $removed != $errors ] && error "$errors != $removed"
30024
30025         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
30026         rm -rf $DIR/$tdir
30027         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
30028 }
30029 run_test 421g "rmfid to return errors properly"
30030
30031 test_421h() {
30032         local mount_other
30033         local mount_ret
30034         local rmfid_ret
30035         local old_fid
30036         local fidA
30037         local fidB
30038         local fidC
30039         local fidD
30040
30041         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
30042                 skip "Need MDS version at least 2.15.53"
30043
30044         test_mkdir $DIR/$tdir
30045         test_mkdir $DIR/$tdir/subdir
30046         touch $DIR/$tdir/subdir/file0
30047         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
30048         echo File $DIR/$tdir/subdir/file0 FID $old_fid
30049         rm -f $DIR/$tdir/subdir/file0
30050         touch $DIR/$tdir/subdir/fileA
30051         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
30052         echo File $DIR/$tdir/subdir/fileA FID $fidA
30053         touch $DIR/$tdir/subdir/fileB
30054         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
30055         echo File $DIR/$tdir/subdir/fileB FID $fidB
30056         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
30057         touch $DIR/$tdir/subdir/fileC
30058         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
30059         echo File $DIR/$tdir/subdir/fileC FID $fidC
30060         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
30061         touch $DIR/$tdir/fileD
30062         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
30063         echo File $DIR/$tdir/fileD FID $fidD
30064
30065         # mount another client mount point with subdirectory mount
30066         export FILESET=/$tdir/subdir
30067         mount_other=${MOUNT}_other
30068         mount_client $mount_other ${MOUNT_OPTS}
30069         mount_ret=$?
30070         export FILESET=""
30071         (( mount_ret == 0 )) || error "mount $mount_other failed"
30072
30073         echo Removing FIDs:
30074         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30075         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
30076         rmfid_ret=$?
30077
30078         umount_client $mount_other || error "umount $mount_other failed"
30079
30080         (( rmfid_ret != 0 )) || error "rmfid should have failed"
30081
30082         # fileA should have been deleted
30083         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
30084
30085         # fileB should have been deleted
30086         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
30087
30088         # fileC should not have been deleted, fid also exists outside of fileset
30089         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
30090
30091         # fileD should not have been deleted, it exists outside of fileset
30092         stat $DIR/$tdir/fileD || error "fileD deleted"
30093 }
30094 run_test 421h "rmfid with fileset mount"
30095
30096 test_422() {
30097         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
30098         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
30099         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
30100         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
30101         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
30102
30103         local amc=$(at_max_get client)
30104         local amo=$(at_max_get mds1)
30105         local timeout=`lctl get_param -n timeout`
30106
30107         at_max_set 0 client
30108         at_max_set 0 mds1
30109
30110 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
30111         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
30112                         fail_val=$(((2*timeout + 10)*1000))
30113         touch $DIR/$tdir/d3/file &
30114         sleep 2
30115 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
30116         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
30117                         fail_val=$((2*timeout + 5))
30118         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
30119         local pid=$!
30120         sleep 1
30121         kill -9 $pid
30122         sleep $((2 * timeout))
30123         echo kill $pid
30124         kill -9 $pid
30125         lctl mark touch
30126         touch $DIR/$tdir/d2/file3
30127         touch $DIR/$tdir/d2/file4
30128         touch $DIR/$tdir/d2/file5
30129
30130         wait
30131         at_max_set $amc client
30132         at_max_set $amo mds1
30133
30134         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
30135         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
30136                 error "Watchdog is always throttled"
30137 }
30138 run_test 422 "kill a process with RPC in progress"
30139
30140 stat_test() {
30141     df -h $MOUNT &
30142     df -h $MOUNT &
30143     df -h $MOUNT &
30144     df -h $MOUNT &
30145     df -h $MOUNT &
30146     df -h $MOUNT &
30147 }
30148
30149 test_423() {
30150     local _stats
30151     # ensure statfs cache is expired
30152     sleep 2;
30153
30154     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
30155     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
30156
30157     return 0
30158 }
30159 run_test 423 "statfs should return a right data"
30160
30161 test_424() {
30162 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
30163         $LCTL set_param fail_loc=0x80000522
30164         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
30165         rm -f $DIR/$tfile
30166 }
30167 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
30168
30169 test_425() {
30170         test_mkdir -c -1 $DIR/$tdir
30171         $LFS setstripe -c -1 $DIR/$tdir
30172
30173         lru_resize_disable "" 100
30174         stack_trap "lru_resize_enable" EXIT
30175
30176         sleep 5
30177
30178         for i in $(seq $((MDSCOUNT * 125))); do
30179                 local t=$DIR/$tdir/$tfile_$i
30180
30181                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
30182                         error_noexit "Create file $t"
30183         done
30184         stack_trap "rm -rf $DIR/$tdir" EXIT
30185
30186         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
30187                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
30188                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
30189
30190                 [ $lock_count -le $lru_size ] ||
30191                         error "osc lock count $lock_count > lru size $lru_size"
30192         done
30193
30194         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
30195                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
30196                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
30197
30198                 [ $lock_count -le $lru_size ] ||
30199                         error "mdc lock count $lock_count > lru size $lru_size"
30200         done
30201 }
30202 run_test 425 "lock count should not exceed lru size"
30203
30204 test_426() {
30205         splice-test -r $DIR/$tfile
30206         splice-test -rd $DIR/$tfile
30207         splice-test $DIR/$tfile
30208         splice-test -d $DIR/$tfile
30209 }
30210 run_test 426 "splice test on Lustre"
30211
30212 test_427() {
30213         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30214         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30215                 skip "Need MDS version at least 2.12.4"
30216         local log
30217
30218         mkdir $DIR/$tdir
30219         mkdir $DIR/$tdir/1
30220         mkdir $DIR/$tdir/2
30221         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30222         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30223
30224         $LFS getdirstripe $DIR/$tdir/1/dir
30225
30226         #first setfattr for creating updatelog
30227         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30228
30229 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30230         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30231         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30232         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30233
30234         sleep 2
30235         fail mds2
30236         wait_recovery_complete mds2 $((2*TIMEOUT))
30237
30238         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30239         echo $log | grep "get update log failed" &&
30240                 error "update log corruption is detected" || true
30241 }
30242 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30243
30244 test_428() {
30245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30246         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30247                               awk '/^max_cached_mb/ { print $2 }')
30248         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30249
30250         $LCTL set_param -n llite.*.max_cached_mb=64
30251
30252         mkdir $DIR/$tdir
30253         $LFS setstripe -c 1 $DIR/$tdir
30254         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30255         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30256         #test write
30257         for f in $(seq 4); do
30258                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30259         done
30260         wait
30261
30262         cancel_lru_locks osc
30263         # Test read
30264         for f in $(seq 4); do
30265                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30266         done
30267         wait
30268 }
30269 run_test 428 "large block size IO should not hang"
30270
30271 test_429() { # LU-7915 / LU-10948
30272         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30273         local testfile=$DIR/$tfile
30274         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30275         local new_flag=1
30276         local first_rpc
30277         local second_rpc
30278         local third_rpc
30279
30280         $LCTL get_param $ll_opencache_threshold_count ||
30281                 skip "client does not have opencache parameter"
30282
30283         set_opencache $new_flag
30284         stack_trap "restore_opencache"
30285         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30286                 error "enable opencache failed"
30287         touch $testfile
30288         # drop MDC DLM locks
30289         cancel_lru_locks mdc
30290         # clear MDC RPC stats counters
30291         $LCTL set_param $mdc_rpcstats=clear
30292
30293         # According to the current implementation, we need to run 3 times
30294         # open & close file to verify if opencache is enabled correctly.
30295         # 1st, RPCs are sent for lookup/open and open handle is released on
30296         #      close finally.
30297         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30298         #      so open handle won't be released thereafter.
30299         # 3rd, No RPC is sent out.
30300         $MULTIOP $testfile oc || error "multiop failed"
30301         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30302         echo "1st: $first_rpc RPCs in flight"
30303
30304         $MULTIOP $testfile oc || error "multiop failed"
30305         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30306         echo "2nd: $second_rpc RPCs in flight"
30307
30308         $MULTIOP $testfile oc || error "multiop failed"
30309         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30310         echo "3rd: $third_rpc RPCs in flight"
30311
30312         #verify no MDC RPC is sent
30313         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30314 }
30315 run_test 429 "verify if opencache flag on client side does work"
30316
30317 lseek_test_430() {
30318         local offset
30319         local file=$1
30320
30321         # data at [200K, 400K)
30322         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30323                 error "256K->512K dd fails"
30324         # data at [2M, 3M)
30325         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30326                 error "2M->3M dd fails"
30327         # data at [4M, 5M)
30328         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30329                 error "4M->5M dd fails"
30330         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30331         # start at first component hole #1
30332         printf "Seeking hole from 1000 ... "
30333         offset=$(lseek_test -l 1000 $file)
30334         echo $offset
30335         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30336         printf "Seeking data from 1000 ... "
30337         offset=$(lseek_test -d 1000 $file)
30338         echo $offset
30339         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30340
30341         # start at first component data block
30342         printf "Seeking hole from 300000 ... "
30343         offset=$(lseek_test -l 300000 $file)
30344         echo $offset
30345         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30346         printf "Seeking data from 300000 ... "
30347         offset=$(lseek_test -d 300000 $file)
30348         echo $offset
30349         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30350
30351         # start at the first component but beyond end of object size
30352         printf "Seeking hole from 1000000 ... "
30353         offset=$(lseek_test -l 1000000 $file)
30354         echo $offset
30355         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30356         printf "Seeking data from 1000000 ... "
30357         offset=$(lseek_test -d 1000000 $file)
30358         echo $offset
30359         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30360
30361         # start at second component stripe 2 (empty file)
30362         printf "Seeking hole from 1500000 ... "
30363         offset=$(lseek_test -l 1500000 $file)
30364         echo $offset
30365         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30366         printf "Seeking data from 1500000 ... "
30367         offset=$(lseek_test -d 1500000 $file)
30368         echo $offset
30369         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30370
30371         # start at second component stripe 1 (all data)
30372         printf "Seeking hole from 3000000 ... "
30373         offset=$(lseek_test -l 3000000 $file)
30374         echo $offset
30375         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30376         printf "Seeking data from 3000000 ... "
30377         offset=$(lseek_test -d 3000000 $file)
30378         echo $offset
30379         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30380
30381         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30382                 error "2nd dd fails"
30383         echo "Add data block at 640K...1280K"
30384
30385         # start at before new data block, in hole
30386         printf "Seeking hole from 600000 ... "
30387         offset=$(lseek_test -l 600000 $file)
30388         echo $offset
30389         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30390         printf "Seeking data from 600000 ... "
30391         offset=$(lseek_test -d 600000 $file)
30392         echo $offset
30393         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30394
30395         # start at the first component new data block
30396         printf "Seeking hole from 1000000 ... "
30397         offset=$(lseek_test -l 1000000 $file)
30398         echo $offset
30399         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30400         printf "Seeking data from 1000000 ... "
30401         offset=$(lseek_test -d 1000000 $file)
30402         echo $offset
30403         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30404
30405         # start at second component stripe 2, new data
30406         printf "Seeking hole from 1200000 ... "
30407         offset=$(lseek_test -l 1200000 $file)
30408         echo $offset
30409         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30410         printf "Seeking data from 1200000 ... "
30411         offset=$(lseek_test -d 1200000 $file)
30412         echo $offset
30413         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30414
30415         # start beyond file end
30416         printf "Using offset > filesize ... "
30417         lseek_test -l 4000000 $file && error "lseek should fail"
30418         printf "Using offset > filesize ... "
30419         lseek_test -d 4000000 $file && error "lseek should fail"
30420
30421         printf "Done\n\n"
30422 }
30423
30424 test_430a() {
30425         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30426                 skip "MDT does not support SEEK_HOLE"
30427
30428         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30429                 skip "OST does not support SEEK_HOLE"
30430
30431         local file=$DIR/$tdir/$tfile
30432
30433         mkdir -p $DIR/$tdir
30434
30435         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30436         # OST stripe #1 will have continuous data at [1M, 3M)
30437         # OST stripe #2 is empty
30438         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30439         lseek_test_430 $file
30440         rm $file
30441         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30442         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30443         lseek_test_430 $file
30444         rm $file
30445         $LFS setstripe -c2 -S 512K $file
30446         echo "Two stripes, stripe size 512K"
30447         lseek_test_430 $file
30448         rm $file
30449         # FLR with stale mirror
30450         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30451                        -N -c2 -S 1M $file
30452         echo "Mirrored file:"
30453         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30454         echo "Plain 2 stripes 1M"
30455         lseek_test_430 $file
30456         rm $file
30457 }
30458 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30459
30460 test_430b() {
30461         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30462                 skip "OST does not support SEEK_HOLE"
30463
30464         local offset
30465         local file=$DIR/$tdir/$tfile
30466
30467         mkdir -p $DIR/$tdir
30468         # Empty layout lseek should fail
30469         $MCREATE $file
30470         # seek from 0
30471         printf "Seeking hole from 0 ... "
30472         lseek_test -l 0 $file && error "lseek should fail"
30473         printf "Seeking data from 0 ... "
30474         lseek_test -d 0 $file && error "lseek should fail"
30475         rm $file
30476
30477         # 1M-hole file
30478         $LFS setstripe -E 1M -c2 -E eof $file
30479         $TRUNCATE $file 1048576
30480         printf "Seeking hole from 1000000 ... "
30481         offset=$(lseek_test -l 1000000 $file)
30482         echo $offset
30483         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30484         printf "Seeking data from 1000000 ... "
30485         lseek_test -d 1000000 $file && error "lseek should fail"
30486         rm $file
30487
30488         # full component followed by non-inited one
30489         $LFS setstripe -E 1M -c2 -E eof $file
30490         dd if=/dev/urandom of=$file bs=1M count=1
30491         printf "Seeking hole from 1000000 ... "
30492         offset=$(lseek_test -l 1000000 $file)
30493         echo $offset
30494         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30495         printf "Seeking hole from 1048576 ... "
30496         lseek_test -l 1048576 $file && error "lseek should fail"
30497         # init second component and truncate back
30498         echo "123" >> $file
30499         $TRUNCATE $file 1048576
30500         printf "Seeking hole from 1000000 ... "
30501         offset=$(lseek_test -l 1000000 $file)
30502         echo $offset
30503         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30504         printf "Seeking hole from 1048576 ... "
30505         lseek_test -l 1048576 $file && error "lseek should fail"
30506         # boundary checks for big values
30507         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30508         offset=$(lseek_test -d 0 $file.10g)
30509         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30510         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30511         offset=$(lseek_test -d 0 $file.100g)
30512         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30513         return 0
30514 }
30515 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30516
30517 test_430c() {
30518         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30519                 skip "OST does not support SEEK_HOLE"
30520
30521         local file=$DIR/$tdir/$tfile
30522         local start
30523
30524         mkdir -p $DIR/$tdir
30525         stack_trap "rm -f $file $file.tmp"
30526         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30527
30528         # cp version 8.33+ prefers lseek over fiemap
30529         local ver=$(cp --version | awk '{ print $4; exit; }')
30530
30531         echo "cp $ver installed"
30532         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30533                 start=$SECONDS
30534                 time cp -v $file $file.tmp || error "cp $file failed"
30535                 (( SECONDS - start < 5 )) || {
30536                         strace cp $file $file.tmp |&
30537                                 grep -E "open|read|seek|FIEMAP" |
30538                                 grep -A 100 $file
30539                         error "cp: too long runtime $((SECONDS - start))"
30540                 }
30541         else
30542                 echo "cp test skipped due to $ver < 8.33"
30543         fi
30544
30545         # tar version 1.29+ supports SEEK_HOLE/DATA
30546         ver=$(tar --version | awk '{ print $4; exit; }')
30547         echo "tar $ver installed"
30548         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30549                 start=$SECONDS
30550                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30551                 (( SECONDS - start < 5 )) || {
30552                         strace tar cf $file.tmp --sparse $file |&
30553                                 grep -E "open|read|seek|FIEMAP" |
30554                                 grep -A 100 $file
30555                         error "tar: too long runtime $((SECONDS - start))"
30556                 }
30557         else
30558                 echo "tar test skipped due to $ver < 1.29"
30559         fi
30560 }
30561 run_test 430c "lseek: external tools check"
30562
30563 test_431() { # LU-14187
30564         local file=$DIR/$tdir/$tfile
30565
30566         mkdir -p $DIR/$tdir
30567         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30568         dd if=/dev/urandom of=$file bs=4k count=1
30569         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30570         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30571         #define OBD_FAIL_OST_RESTART_IO 0x251
30572         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30573         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30574         cp $file $file.0
30575         cancel_lru_locks
30576         sync_all_data
30577         echo 3 > /proc/sys/vm/drop_caches
30578         diff  $file $file.0 || error "data diff"
30579 }
30580 run_test 431 "Restart transaction for IO"
30581
30582 cleanup_test_432() {
30583         do_facet mgs $LCTL nodemap_activate 0
30584         wait_nm_sync active
30585 }
30586
30587 test_432() {
30588         local tmpdir=$TMP/dir432
30589
30590         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30591                 skip "Need MDS version at least 2.14.52"
30592
30593         stack_trap cleanup_test_432 EXIT
30594         mkdir $DIR/$tdir
30595         mkdir $tmpdir
30596
30597         do_facet mgs $LCTL nodemap_activate 1
30598         wait_nm_sync active
30599         do_facet mgs $LCTL nodemap_modify --name default \
30600                 --property admin --value 1
30601         do_facet mgs $LCTL nodemap_modify --name default \
30602                 --property trusted --value 1
30603         cancel_lru_locks mdc
30604         wait_nm_sync default admin_nodemap
30605         wait_nm_sync default trusted_nodemap
30606
30607         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30608                grep -ci "Operation not permitted") -ne 0 ]; then
30609                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30610         fi
30611 }
30612 run_test 432 "mv dir from outside Lustre"
30613
30614 test_433() {
30615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30616
30617         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30618                 skip "inode cache not supported"
30619
30620         $LCTL set_param llite.*.inode_cache=0
30621         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30622
30623         local count=256
30624         local before
30625         local after
30626
30627         cancel_lru_locks mdc
30628         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30629         createmany -m $DIR/$tdir/f $count
30630         createmany -d $DIR/$tdir/d $count
30631         ls -l $DIR/$tdir > /dev/null
30632         stack_trap "rm -rf $DIR/$tdir"
30633
30634         before=$(num_objects)
30635         cancel_lru_locks mdc
30636         after=$(num_objects)
30637
30638         # sometimes even @before is less than 2 * count
30639         while (( before - after < count )); do
30640                 sleep 1
30641                 after=$(num_objects)
30642                 wait=$((wait + 1))
30643                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30644                 if (( wait > 60 )); then
30645                         error "inode slab grew from $before to $after"
30646                 fi
30647         done
30648
30649         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30650 }
30651 run_test 433 "ldlm lock cancel releases dentries and inodes"
30652
30653 test_434() {
30654         local file
30655         local getxattr_count
30656         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30657         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30658
30659         [[ $(getenforce) == "Disabled" ]] ||
30660                 skip "lsm selinux module have to be disabled for this test"
30661
30662         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30663                 error "fail to create $DIR/$tdir/ on MDT0000"
30664
30665         touch $DIR/$tdir/$tfile-{001..100}
30666
30667         # disable the xattr cache
30668         save_lustre_params client "llite.*.xattr_cache" > $p
30669         lctl set_param llite.*.xattr_cache=0
30670         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30671
30672         # clear clients mdc stats
30673         clear_stats $mdc_stat_param ||
30674                 error "fail to clear stats on mdc MDT0000"
30675
30676         for file in $DIR/$tdir/$tfile-{001..100}; do
30677                 getfattr -n security.selinux $file |&
30678                         grep -q "Operation not supported" ||
30679                         error "getxattr on security.selinux should return EOPNOTSUPP"
30680         done
30681
30682         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30683         (( getxattr_count < 100 )) ||
30684                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30685 }
30686 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30687
30688 test_440() {
30689         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30690                 source $LUSTRE/scripts/bash-completion/lustre
30691         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30692                 source /usr/share/bash-completion/completions/lustre
30693         else
30694                 skip "bash completion scripts not found"
30695         fi
30696
30697         local lctl_completions
30698         local lfs_completions
30699
30700         lctl_completions=$(_lustre_cmds lctl)
30701         if [[ ! $lctl_completions =~ "get_param" ]]; then
30702                 error "lctl bash completion failed"
30703         fi
30704
30705         lfs_completions=$(_lustre_cmds lfs)
30706         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30707                 error "lfs bash completion failed"
30708         fi
30709 }
30710 run_test 440 "bash completion for lfs, lctl"
30711
30712 test_442() {
30713         local pid1
30714         local pid2
30715         mkdir -p $DIR/$tdir
30716         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30717         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30718         sleep 1
30719         touch $DIR/$tdir/$tfile.2
30720         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30721         $LCTL set_param fail_loc=0x1430
30722         kill -USR1 $pid1
30723         sleep 1
30724         kill -USR1 $pid2
30725         wait
30726 }
30727 run_test 442 "truncate vs read/write should not panic"
30728
30729 test_460d() {
30730         verify_yaml_available || skip_env "YAML verification not installed"
30731         $LCTL get_param -n sptlrpc.page_pools
30732         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30733                 error "The output of encrypt_page_pools is not an valid YAML"
30734 }
30735 run_test 460d "Check encrypt pools output"
30736
30737 prep_801() {
30738         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30739         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30740                 skip "Need server version at least 2.9.55"
30741
30742         start_full_debug_logging
30743 }
30744
30745 post_801() {
30746         stop_full_debug_logging
30747 }
30748
30749 barrier_stat() {
30750         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30751                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30752                            awk '/The barrier for/ { print $7 }')
30753                 echo $st
30754         else
30755                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30756                 echo \'$st\'
30757         fi
30758 }
30759
30760 barrier_expired() {
30761         local expired
30762
30763         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30764                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30765                           awk '/will be expired/ { print $7 }')
30766         else
30767                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30768         fi
30769
30770         echo $expired
30771 }
30772
30773 test_801a() {
30774         prep_801
30775
30776         echo "Start barrier_freeze at: $(date)"
30777         #define OBD_FAIL_BARRIER_DELAY          0x2202
30778         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30779         # Do not reduce barrier time - See LU-11873
30780         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30781
30782         sleep 2
30783         local b_status=$(barrier_stat)
30784         echo "Got barrier status at: $(date)"
30785         [ "$b_status" = "'freezing_p1'" ] ||
30786                 error "(1) unexpected barrier status $b_status"
30787
30788         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30789         wait
30790         b_status=$(barrier_stat)
30791         [ "$b_status" = "'frozen'" ] ||
30792                 error "(2) unexpected barrier status $b_status"
30793
30794         local expired=$(barrier_expired)
30795         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30796         sleep $((expired + 3))
30797
30798         b_status=$(barrier_stat)
30799         [ "$b_status" = "'expired'" ] ||
30800                 error "(3) unexpected barrier status $b_status"
30801
30802         # Do not reduce barrier time - See LU-11873
30803         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30804                 error "(4) fail to freeze barrier"
30805
30806         b_status=$(barrier_stat)
30807         [ "$b_status" = "'frozen'" ] ||
30808                 error "(5) unexpected barrier status $b_status"
30809
30810         echo "Start barrier_thaw at: $(date)"
30811         #define OBD_FAIL_BARRIER_DELAY          0x2202
30812         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30813         do_facet mgs $LCTL barrier_thaw $FSNAME &
30814
30815         sleep 2
30816         b_status=$(barrier_stat)
30817         echo "Got barrier status at: $(date)"
30818         [ "$b_status" = "'thawing'" ] ||
30819                 error "(6) unexpected barrier status $b_status"
30820
30821         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30822         wait
30823         b_status=$(barrier_stat)
30824         [ "$b_status" = "'thawed'" ] ||
30825                 error "(7) unexpected barrier status $b_status"
30826
30827         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30828         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30829         do_facet mgs $LCTL barrier_freeze $FSNAME
30830
30831         b_status=$(barrier_stat)
30832         [ "$b_status" = "'failed'" ] ||
30833                 error "(8) unexpected barrier status $b_status"
30834
30835         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30836         do_facet mgs $LCTL barrier_thaw $FSNAME
30837
30838         post_801
30839 }
30840 run_test 801a "write barrier user interfaces and stat machine"
30841
30842 test_801b() {
30843         prep_801
30844
30845         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30846         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30847         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30848         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30849         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30850
30851         cancel_lru_locks mdc
30852
30853         # 180 seconds should be long enough
30854         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30855
30856         local b_status=$(barrier_stat)
30857         [ "$b_status" = "'frozen'" ] ||
30858                 error "(6) unexpected barrier status $b_status"
30859
30860         mkdir $DIR/$tdir/d0/d10 &
30861         mkdir_pid=$!
30862
30863         touch $DIR/$tdir/d1/f13 &
30864         touch_pid=$!
30865
30866         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30867         ln_pid=$!
30868
30869         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30870         mv_pid=$!
30871
30872         rm -f $DIR/$tdir/d4/f12 &
30873         rm_pid=$!
30874
30875         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30876
30877         # To guarantee taht the 'stat' is not blocked
30878         b_status=$(barrier_stat)
30879         [ "$b_status" = "'frozen'" ] ||
30880                 error "(8) unexpected barrier status $b_status"
30881
30882         # let above commands to run at background
30883         sleep 5
30884
30885         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30886         ps -p $touch_pid || error "(10) touch should be blocked"
30887         ps -p $ln_pid || error "(11) link should be blocked"
30888         ps -p $mv_pid || error "(12) rename should be blocked"
30889         ps -p $rm_pid || error "(13) unlink should be blocked"
30890
30891         b_status=$(barrier_stat)
30892         [ "$b_status" = "'frozen'" ] ||
30893                 error "(14) unexpected barrier status $b_status"
30894
30895         do_facet mgs $LCTL barrier_thaw $FSNAME
30896         b_status=$(barrier_stat)
30897         [ "$b_status" = "'thawed'" ] ||
30898                 error "(15) unexpected barrier status $b_status"
30899
30900         wait $mkdir_pid || error "(16) mkdir should succeed"
30901         wait $touch_pid || error "(17) touch should succeed"
30902         wait $ln_pid || error "(18) link should succeed"
30903         wait $mv_pid || error "(19) rename should succeed"
30904         wait $rm_pid || error "(20) unlink should succeed"
30905
30906         post_801
30907 }
30908 run_test 801b "modification will be blocked by write barrier"
30909
30910 test_801c() {
30911         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30912
30913         prep_801
30914
30915         stop mds2 || error "(1) Fail to stop mds2"
30916
30917         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30918
30919         local b_status=$(barrier_stat)
30920         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30921                 do_facet mgs $LCTL barrier_thaw $FSNAME
30922                 error "(2) unexpected barrier status $b_status"
30923         }
30924
30925         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30926                 error "(3) Fail to rescan barrier bitmap"
30927
30928         # Do not reduce barrier time - See LU-11873
30929         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30930
30931         b_status=$(barrier_stat)
30932         [ "$b_status" = "'frozen'" ] ||
30933                 error "(4) unexpected barrier status $b_status"
30934
30935         do_facet mgs $LCTL barrier_thaw $FSNAME
30936         b_status=$(barrier_stat)
30937         [ "$b_status" = "'thawed'" ] ||
30938                 error "(5) unexpected barrier status $b_status"
30939
30940         local devname=$(mdsdevname 2)
30941
30942         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30943
30944         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30945                 error "(7) Fail to rescan barrier bitmap"
30946
30947         post_801
30948 }
30949 run_test 801c "rescan barrier bitmap"
30950
30951 test_802b() {
30952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30953         remote_mds_nodsh && skip "remote MDS with nodsh"
30954
30955         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30956                 skip "readonly option not available"
30957
30958         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30959
30960         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30961                 error "(2) Fail to copy"
30962
30963         # write back all cached data before setting MDT to readonly
30964         cancel_lru_locks
30965         sync_all_data
30966
30967         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30968         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30969
30970         echo "Modify should be refused"
30971         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30972
30973         echo "Read should be allowed"
30974         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30975                 error "(7) Read should succeed under ro mode"
30976
30977         # disable readonly
30978         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30979 }
30980 run_test 802b "be able to set MDTs to readonly"
30981
30982 test_803a() {
30983         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30984         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30985                 skip "MDS needs to be newer than 2.10.54"
30986
30987         mkdir_on_mdt0 $DIR/$tdir
30988         # Create some objects on all MDTs to trigger related logs objects
30989         for idx in $(seq $MDSCOUNT); do
30990                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30991                         $DIR/$tdir/dir${idx} ||
30992                         error "Fail to create $DIR/$tdir/dir${idx}"
30993         done
30994
30995         wait_delete_completed # ensure old test cleanups are finished
30996         sleep 3
30997         echo "before create:"
30998         $LFS df -i $MOUNT
30999         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31000
31001         for i in {1..10}; do
31002                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
31003                         error "Fail to create $DIR/$tdir/foo$i"
31004         done
31005
31006         # sync ZFS-on-MDS to refresh statfs data
31007         wait_zfs_commit mds1
31008         sleep 3
31009         echo "after create:"
31010         $LFS df -i $MOUNT
31011         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31012
31013         # allow for an llog to be cleaned up during the test
31014         [ $after_used -ge $((before_used + 10 - 1)) ] ||
31015                 error "before ($before_used) + 10 > after ($after_used)"
31016
31017         for i in {1..10}; do
31018                 rm -rf $DIR/$tdir/foo$i ||
31019                         error "Fail to remove $DIR/$tdir/foo$i"
31020         done
31021
31022         # sync ZFS-on-MDS to refresh statfs data
31023         wait_zfs_commit mds1
31024         wait_delete_completed
31025         sleep 3 # avoid MDT return cached statfs
31026         echo "after unlink:"
31027         $LFS df -i $MOUNT
31028         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
31029
31030         # allow for an llog to be created during the test
31031         [ $after_used -le $((before_used + 1)) ] ||
31032                 error "after ($after_used) > before ($before_used) + 1"
31033 }
31034 run_test 803a "verify agent object for remote object"
31035
31036 test_803b() {
31037         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31038         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
31039                 skip "MDS needs to be newer than 2.13.56"
31040         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31041
31042         for i in $(seq 0 $((MDSCOUNT - 1))); do
31043                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
31044         done
31045
31046         local before=0
31047         local after=0
31048
31049         local tmp
31050
31051         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31052         for i in $(seq 0 $((MDSCOUNT - 1))); do
31053                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31054                         awk '/getattr/ { print $2 }')
31055                 before=$((before + tmp))
31056         done
31057         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
31058         for i in $(seq 0 $((MDSCOUNT - 1))); do
31059                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
31060                         awk '/getattr/ { print $2 }')
31061                 after=$((after + tmp))
31062         done
31063
31064         [ $before -eq $after ] || error "getattr count $before != $after"
31065 }
31066 run_test 803b "remote object can getattr from cache"
31067
31068 test_804() {
31069         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31070         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
31071                 skip "MDS needs to be newer than 2.10.54"
31072         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
31073
31074         mkdir -p $DIR/$tdir
31075         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
31076                 error "Fail to create $DIR/$tdir/dir0"
31077
31078         local fid=$($LFS path2fid $DIR/$tdir/dir0)
31079         local dev=$(mdsdevname 2)
31080
31081         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31082                 grep ${fid} || error "NOT found agent entry for dir0"
31083
31084         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
31085                 error "Fail to create $DIR/$tdir/dir1"
31086
31087         touch $DIR/$tdir/dir1/foo0 ||
31088                 error "Fail to create $DIR/$tdir/dir1/foo0"
31089         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
31090         local rc=0
31091
31092         for idx in $(seq $MDSCOUNT); do
31093                 dev=$(mdsdevname $idx)
31094                 do_facet mds${idx} \
31095                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31096                         grep ${fid} && rc=$idx
31097         done
31098
31099         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
31100                 error "Fail to rename foo0 to foo1"
31101         if [ $rc -eq 0 ]; then
31102                 for idx in $(seq $MDSCOUNT); do
31103                         dev=$(mdsdevname $idx)
31104                         do_facet mds${idx} \
31105                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31106                         grep ${fid} && rc=$idx
31107                 done
31108         fi
31109
31110         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
31111                 error "Fail to rename foo1 to foo2"
31112         if [ $rc -eq 0 ]; then
31113                 for idx in $(seq $MDSCOUNT); do
31114                         dev=$(mdsdevname $idx)
31115                         do_facet mds${idx} \
31116                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
31117                         grep ${fid} && rc=$idx
31118                 done
31119         fi
31120
31121         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
31122
31123         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
31124                 error "Fail to link to $DIR/$tdir/dir1/foo2"
31125         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
31126                 error "Fail to rename foo2 to foo0"
31127         unlink $DIR/$tdir/dir1/foo0 ||
31128                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
31129         rm -rf $DIR/$tdir/dir0 ||
31130                 error "Fail to rm $DIR/$tdir/dir0"
31131
31132         for idx in $(seq $MDSCOUNT); do
31133                 rc=0
31134
31135                 stop mds${idx}
31136                 dev=$(mdsdevname $idx)
31137                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
31138                         rc=$?
31139                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
31140                         error "mount mds$idx failed"
31141                 df $MOUNT > /dev/null 2>&1
31142
31143                 # e2fsck should not return error
31144                 [ $rc -eq 0 ] ||
31145                         error "e2fsck detected error on MDT${idx}: rc=$rc"
31146         done
31147 }
31148 run_test 804 "verify agent entry for remote entry"
31149
31150 cleanup_805() {
31151         do_facet $SINGLEMDS zfs set quota=$old $fsset
31152         unlinkmany $DIR/$tdir/f- 1000000
31153         trap 0
31154 }
31155
31156 test_805() {
31157         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
31158         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
31159         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
31160                 skip "netfree not implemented before 0.7"
31161         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
31162                 skip "Need MDS version at least 2.10.57"
31163
31164         local fsset
31165         local freekb
31166         local usedkb
31167         local old
31168         local quota
31169         local pref="osd-zfs.$FSNAME-MDT0000."
31170
31171         # limit available space on MDS dataset to meet nospace issue
31172         # quickly. then ZFS 0.7.2 can use reserved space if asked
31173         # properly (using netfree flag in osd_declare_destroy()
31174         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
31175         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
31176                 gawk '{print $3}')
31177         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
31178         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
31179         let "usedkb=usedkb-freekb"
31180         let "freekb=freekb/2"
31181         if let "freekb > 5000"; then
31182                 let "freekb=5000"
31183         fi
31184         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
31185         trap cleanup_805 EXIT
31186         mkdir_on_mdt0 $DIR/$tdir
31187         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
31188                 error "Can't set PFL layout"
31189         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
31190         rm -rf $DIR/$tdir || error "not able to remove"
31191         do_facet $SINGLEMDS zfs set quota=$old $fsset
31192         trap 0
31193 }
31194 run_test 805 "ZFS can remove from full fs"
31195
31196 # Size-on-MDS test
31197 check_lsom_data()
31198 {
31199         local file=$1
31200         local expect=$(stat -c %s $file)
31201
31202         check_lsom_size $1 $expect
31203
31204         local blocks=$($LFS getsom -b $file)
31205         expect=$(stat -c %b $file)
31206         [[ $blocks == $expect ]] ||
31207                 error "$file expected blocks: $expect, got: $blocks"
31208 }
31209
31210 check_lsom_size()
31211 {
31212         local size
31213         local expect=$2
31214
31215         cancel_lru_locks mdc
31216
31217         size=$($LFS getsom -s $1)
31218         [[ $size == $expect ]] ||
31219                 error "$file expected size: $expect, got: $size"
31220 }
31221
31222 test_806() {
31223         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31224                 skip "Need MDS version at least 2.11.52"
31225
31226         local bs=1048576
31227
31228         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31229
31230         disable_opencache
31231         stack_trap "restore_opencache"
31232
31233         # single-threaded write
31234         echo "Test SOM for single-threaded write"
31235         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31236                 error "write $tfile failed"
31237         check_lsom_size $DIR/$tfile $bs
31238
31239         local num=32
31240         local size=$(($num * $bs))
31241         local offset=0
31242         local i
31243
31244         echo "Test SOM for single client multi-threaded($num) write"
31245         $TRUNCATE $DIR/$tfile 0
31246         for ((i = 0; i < $num; i++)); do
31247                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31248                 local pids[$i]=$!
31249                 offset=$((offset + $bs))
31250         done
31251         for (( i=0; i < $num; i++ )); do
31252                 wait ${pids[$i]}
31253         done
31254         check_lsom_size $DIR/$tfile $size
31255
31256         $TRUNCATE $DIR/$tfile 0
31257         for ((i = 0; i < $num; i++)); do
31258                 offset=$((offset - $bs))
31259                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31260                 local pids[$i]=$!
31261         done
31262         for (( i=0; i < $num; i++ )); do
31263                 wait ${pids[$i]}
31264         done
31265         check_lsom_size $DIR/$tfile $size
31266
31267         # multi-client writes
31268         num=$(get_node_count ${CLIENTS//,/ })
31269         size=$(($num * $bs))
31270         offset=0
31271         i=0
31272
31273         echo "Test SOM for multi-client ($num) writes"
31274         $TRUNCATE $DIR/$tfile 0
31275         for client in ${CLIENTS//,/ }; do
31276                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31277                 local pids[$i]=$!
31278                 i=$((i + 1))
31279                 offset=$((offset + $bs))
31280         done
31281         for (( i=0; i < $num; i++ )); do
31282                 wait ${pids[$i]}
31283         done
31284         check_lsom_size $DIR/$tfile $offset
31285
31286         i=0
31287         $TRUNCATE $DIR/$tfile 0
31288         for client in ${CLIENTS//,/ }; do
31289                 offset=$((offset - $bs))
31290                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31291                 local pids[$i]=$!
31292                 i=$((i + 1))
31293         done
31294         for (( i=0; i < $num; i++ )); do
31295                 wait ${pids[$i]}
31296         done
31297         check_lsom_size $DIR/$tfile $size
31298
31299         # verify SOM blocks count
31300         echo "Verify SOM block count"
31301         $TRUNCATE $DIR/$tfile 0
31302         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31303                 error "failed to write file $tfile with fdatasync and fstat"
31304         check_lsom_data $DIR/$tfile
31305
31306         $TRUNCATE $DIR/$tfile 0
31307         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31308                 error "failed to write file $tfile with fdatasync"
31309         check_lsom_data $DIR/$tfile
31310
31311         $TRUNCATE $DIR/$tfile 0
31312         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31313                 error "failed to write file $tfile with sync IO"
31314         check_lsom_data $DIR/$tfile
31315
31316         # verify truncate
31317         echo "Test SOM for truncate"
31318         # use ftruncate to sync blocks on close request
31319         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31320         check_lsom_size $DIR/$tfile 16384
31321         check_lsom_data $DIR/$tfile
31322
31323         $TRUNCATE $DIR/$tfile 1234
31324         check_lsom_size $DIR/$tfile 1234
31325         # sync blocks on the MDT
31326         $MULTIOP $DIR/$tfile oc
31327         check_lsom_data $DIR/$tfile
31328 }
31329 run_test 806 "Verify Lazy Size on MDS"
31330
31331 test_807() {
31332         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31333         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31334                 skip "Need MDS version at least 2.11.52"
31335
31336         # Registration step
31337         changelog_register || error "changelog_register failed"
31338         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31339         changelog_users $SINGLEMDS | grep -q $cl_user ||
31340                 error "User $cl_user not found in changelog_users"
31341
31342         rm -rf $DIR/$tdir || error "rm $tdir failed"
31343         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31344         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31345         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31346         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31347                 error "truncate $tdir/trunc failed"
31348
31349         local bs=1048576
31350         echo "Test SOM for single-threaded write with fsync"
31351         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31352                 error "write $tfile failed"
31353         sync;sync;sync
31354
31355         # multi-client wirtes
31356         local num=$(get_node_count ${CLIENTS//,/ })
31357         local offset=0
31358         local i=0
31359
31360         echo "Test SOM for multi-client ($num) writes"
31361         touch $DIR/$tfile || error "touch $tfile failed"
31362         $TRUNCATE $DIR/$tfile 0
31363         for client in ${CLIENTS//,/ }; do
31364                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31365                 local pids[$i]=$!
31366                 i=$((i + 1))
31367                 offset=$((offset + $bs))
31368         done
31369         for (( i=0; i < $num; i++ )); do
31370                 wait ${pids[$i]}
31371         done
31372
31373         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31374         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31375         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31376         check_lsom_data $DIR/$tdir/trunc
31377         check_lsom_data $DIR/$tdir/single_dd
31378         check_lsom_data $DIR/$tfile
31379
31380         rm -rf $DIR/$tdir
31381         # Deregistration step
31382         changelog_deregister || error "changelog_deregister failed"
31383 }
31384 run_test 807 "verify LSOM syncing tool"
31385
31386 check_som_nologged()
31387 {
31388         local lines=$($LFS changelog $FSNAME-MDT0000 |
31389                 grep 'x=trusted.som' | wc -l)
31390         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31391 }
31392
31393 test_808() {
31394         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31395                 skip "Need MDS version at least 2.11.55"
31396
31397         # Registration step
31398         changelog_register || error "changelog_register failed"
31399
31400         touch $DIR/$tfile || error "touch $tfile failed"
31401         check_som_nologged
31402
31403         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31404                 error "write $tfile failed"
31405         check_som_nologged
31406
31407         $TRUNCATE $DIR/$tfile 1234
31408         check_som_nologged
31409
31410         $TRUNCATE $DIR/$tfile 1048576
31411         check_som_nologged
31412
31413         # Deregistration step
31414         changelog_deregister || error "changelog_deregister failed"
31415 }
31416 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31417
31418 check_som_nodata()
31419 {
31420         $LFS getsom $1
31421         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31422 }
31423
31424 test_809() {
31425         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31426                 skip "Need MDS version at least 2.11.56"
31427
31428         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31429                 error "failed to create DoM-only file $DIR/$tfile"
31430         touch $DIR/$tfile || error "touch $tfile failed"
31431         check_som_nodata $DIR/$tfile
31432
31433         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31434                 error "write $tfile failed"
31435         check_som_nodata $DIR/$tfile
31436
31437         $TRUNCATE $DIR/$tfile 1234
31438         check_som_nodata $DIR/$tfile
31439
31440         $TRUNCATE $DIR/$tfile 4097
31441         check_som_nodata $DIR/$file
31442 }
31443 run_test 809 "Verify no SOM xattr store for DoM-only files"
31444
31445 test_810() {
31446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31447         $GSS && skip_env "could not run with gss"
31448         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31449                 skip "OST < 2.12.58 doesn't align checksum"
31450
31451         set_checksums 1
31452         stack_trap "set_checksums $ORIG_CSUM" EXIT
31453         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31454
31455         local csum
31456         local before
31457         local after
31458         for csum in $CKSUM_TYPES; do
31459                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31460                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31461                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31462                         eval set -- $i
31463                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31464                         before=$(md5sum $DIR/$tfile)
31465                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31466                         after=$(md5sum $DIR/$tfile)
31467                         [ "$before" == "$after" ] ||
31468                                 error "$csum: $before != $after bs=$1 seek=$2"
31469                 done
31470         done
31471 }
31472 run_test 810 "partial page writes on ZFS (LU-11663)"
31473
31474 test_812a() {
31475         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31476                 skip "OST < 2.12.51 doesn't support this fail_loc"
31477         local old
31478
31479         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31480         $LCTL set_param osc.*.idle_timeout=10
31481         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31482
31483         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31484         # ensure ost1 is connected
31485         stat $DIR/$tfile >/dev/null || error "can't stat"
31486         wait_osc_import_state client ost1 FULL
31487         # no locks, no reqs to let the connection idle
31488         cancel_lru_locks osc
31489
31490         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31491 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31492         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31493         wait_osc_import_state client ost1 CONNECTING
31494         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31495
31496         stat $DIR/$tfile >/dev/null || error "can't stat file"
31497 }
31498 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31499
31500 test_812b() { # LU-12378
31501         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31502                 skip "OST < 2.12.51 doesn't support this fail_loc"
31503         local old
31504
31505         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31506         $LCTL set_param osc.*.idle_timeout=10
31507         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31508
31509         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31510         # ensure ost1 is connected
31511         stat $DIR/$tfile >/dev/null || error "can't stat"
31512         wait_osc_import_state client ost1 FULL
31513         # no locks, no reqs to let the connection idle
31514         cancel_lru_locks osc
31515
31516         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31517 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31518         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31519         wait_osc_import_state client ost1 CONNECTING
31520         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31521
31522         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31523         wait_osc_import_state client ost1 IDLE
31524 }
31525 run_test 812b "do not drop no resend request for idle connect"
31526
31527 test_812c() {
31528         local old
31529
31530         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31531
31532         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31533         $LFS getstripe $DIR/$tfile
31534         $LCTL set_param osc.*.idle_timeout=10
31535         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31536         # ensure ost1 is connected
31537         stat $DIR/$tfile >/dev/null || error "can't stat"
31538         wait_osc_import_state client ost1 FULL
31539         # no locks, no reqs to let the connection idle
31540         cancel_lru_locks osc
31541
31542 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31543         $LCTL set_param fail_loc=0x80000533
31544         sleep 15
31545         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31546 }
31547 run_test 812c "idle import vs lock enqueue race"
31548
31549 test_813() {
31550         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31551         [ -z "$file_heat_sav" ] && skip "no file heat support"
31552
31553         local readsample
31554         local writesample
31555         local readbyte
31556         local writebyte
31557         local readsample1
31558         local writesample1
31559         local readbyte1
31560         local writebyte1
31561
31562         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31563         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31564
31565         $LCTL set_param -n llite.*.file_heat=1
31566         echo "Turn on file heat"
31567         echo "Period second: $period_second, Decay percentage: $decay_pct"
31568
31569         echo "QQQQ" > $DIR/$tfile
31570         echo "QQQQ" > $DIR/$tfile
31571         echo "QQQQ" > $DIR/$tfile
31572         cat $DIR/$tfile > /dev/null
31573         cat $DIR/$tfile > /dev/null
31574         cat $DIR/$tfile > /dev/null
31575         cat $DIR/$tfile > /dev/null
31576
31577         local out=$($LFS heat_get $DIR/$tfile)
31578
31579         $LFS heat_get $DIR/$tfile
31580         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31581         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31582         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31583         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31584
31585         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31586         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31587         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31588         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31589
31590         sleep $((period_second + 3))
31591         echo "Sleep $((period_second + 3)) seconds..."
31592         # The recursion formula to calculate the heat of the file f is as
31593         # follow:
31594         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31595         # Where Hi is the heat value in the period between time points i*I and
31596         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31597         # to the weight of Ci.
31598         out=$($LFS heat_get $DIR/$tfile)
31599         $LFS heat_get $DIR/$tfile
31600         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31601         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31602         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31603         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31604
31605         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31606                 error "read sample ($readsample) is wrong"
31607         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31608                 error "write sample ($writesample) is wrong"
31609         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31610                 error "read bytes ($readbyte) is wrong"
31611         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31612                 error "write bytes ($writebyte) is wrong"
31613
31614         echo "QQQQ" > $DIR/$tfile
31615         echo "QQQQ" > $DIR/$tfile
31616         echo "QQQQ" > $DIR/$tfile
31617         cat $DIR/$tfile > /dev/null
31618         cat $DIR/$tfile > /dev/null
31619         cat $DIR/$tfile > /dev/null
31620         cat $DIR/$tfile > /dev/null
31621
31622         sleep $((period_second + 3))
31623         echo "Sleep $((period_second + 3)) seconds..."
31624
31625         out=$($LFS heat_get $DIR/$tfile)
31626         $LFS heat_get $DIR/$tfile
31627         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31628         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31629         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31630         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31631
31632         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31633                 4 * $decay_pct) / 100") -eq 1 ] ||
31634                 error "read sample ($readsample1) is wrong"
31635         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31636                 3 * $decay_pct) / 100") -eq 1 ] ||
31637                 error "write sample ($writesample1) is wrong"
31638         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31639                 20 * $decay_pct) / 100") -eq 1 ] ||
31640                 error "read bytes ($readbyte1) is wrong"
31641         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31642                 15 * $decay_pct) / 100") -eq 1 ] ||
31643                 error "write bytes ($writebyte1) is wrong"
31644
31645         echo "Turn off file heat for the file $DIR/$tfile"
31646         $LFS heat_set -o $DIR/$tfile
31647
31648         echo "QQQQ" > $DIR/$tfile
31649         echo "QQQQ" > $DIR/$tfile
31650         echo "QQQQ" > $DIR/$tfile
31651         cat $DIR/$tfile > /dev/null
31652         cat $DIR/$tfile > /dev/null
31653         cat $DIR/$tfile > /dev/null
31654         cat $DIR/$tfile > /dev/null
31655
31656         out=$($LFS heat_get $DIR/$tfile)
31657         $LFS heat_get $DIR/$tfile
31658         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31659         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31660         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31661         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31662
31663         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31664         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31665         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31666         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31667
31668         echo "Trun on file heat for the file $DIR/$tfile"
31669         $LFS heat_set -O $DIR/$tfile
31670
31671         echo "QQQQ" > $DIR/$tfile
31672         echo "QQQQ" > $DIR/$tfile
31673         echo "QQQQ" > $DIR/$tfile
31674         cat $DIR/$tfile > /dev/null
31675         cat $DIR/$tfile > /dev/null
31676         cat $DIR/$tfile > /dev/null
31677         cat $DIR/$tfile > /dev/null
31678
31679         out=$($LFS heat_get $DIR/$tfile)
31680         $LFS heat_get $DIR/$tfile
31681         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31682         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31683         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31684         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31685
31686         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31687         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31688         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31689         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31690
31691         $LFS heat_set -c $DIR/$tfile
31692         $LCTL set_param -n llite.*.file_heat=0
31693         echo "Turn off file heat support for the Lustre filesystem"
31694
31695         echo "QQQQ" > $DIR/$tfile
31696         echo "QQQQ" > $DIR/$tfile
31697         echo "QQQQ" > $DIR/$tfile
31698         cat $DIR/$tfile > /dev/null
31699         cat $DIR/$tfile > /dev/null
31700         cat $DIR/$tfile > /dev/null
31701         cat $DIR/$tfile > /dev/null
31702
31703         out=$($LFS heat_get $DIR/$tfile)
31704         $LFS heat_get $DIR/$tfile
31705         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31706         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31707         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31708         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31709
31710         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31711         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31712         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31713         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31714
31715         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31716         rm -f $DIR/$tfile
31717 }
31718 run_test 813 "File heat verfication"
31719
31720 test_814()
31721 {
31722         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31723         echo -n y >> $DIR/$tfile
31724         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31725         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31726 }
31727 run_test 814 "sparse cp works as expected (LU-12361)"
31728
31729 test_815()
31730 {
31731         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31732         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31733 }
31734 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31735
31736 test_816() {
31737         local ost1_imp=$(get_osc_import_name client ost1)
31738         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31739                          cut -d'.' -f2)
31740         local old
31741
31742         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31743         $LCTL set_param osc.*.idle_timeout=10
31744         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31745
31746         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31747         # ensure ost1 is connected
31748
31749         stat $DIR/$tfile >/dev/null || error "can't stat"
31750         wait_osc_import_state client ost1 FULL
31751         # no locks, no reqs to let the connection idle
31752         cancel_lru_locks osc
31753         lru_resize_disable osc
31754         local before
31755         local now
31756         before=$($LCTL get_param -n \
31757                  ldlm.namespaces.$imp_name.lru_size)
31758
31759         wait_osc_import_state client ost1 IDLE
31760         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31761         now=$($LCTL get_param -n \
31762               ldlm.namespaces.$imp_name.lru_size)
31763         [ $before == $now ] || error "lru_size changed $before != $now"
31764 }
31765 run_test 816 "do not reset lru_resize on idle reconnect"
31766
31767 cleanup_817() {
31768         umount $tmpdir
31769         exportfs -u localhost:$DIR/nfsexp
31770         rm -rf $DIR/nfsexp
31771 }
31772
31773 test_817() {
31774         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31775
31776         mkdir -p $DIR/nfsexp
31777         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31778                 error "failed to export nfs"
31779
31780         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31781         stack_trap cleanup_817 EXIT
31782
31783         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31784                 error "failed to mount nfs to $tmpdir"
31785
31786         cp /bin/true $tmpdir
31787         $DIR/nfsexp/true || error "failed to execute 'true' command"
31788 }
31789 run_test 817 "nfsd won't cache write lock for exec file"
31790
31791 test_818() {
31792         test_mkdir -i0 -c1 $DIR/$tdir
31793         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31794         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31795         stop $SINGLEMDS
31796
31797         # restore osp-syn threads
31798         stack_trap "fail $SINGLEMDS"
31799
31800         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31801         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31802         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31803                 error "start $SINGLEMDS failed"
31804         rm -rf $DIR/$tdir
31805
31806         local testid=$(echo $TESTNAME | tr '_' ' ')
31807
31808         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31809                 grep "run LFSCK" || error "run LFSCK is not suggested"
31810 }
31811 run_test 818 "unlink with failed llog"
31812
31813 test_819a() {
31814         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31815         cancel_lru_locks osc
31816         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31817         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31818         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31819         rm -f $TDIR/$tfile
31820 }
31821 run_test 819a "too big niobuf in read"
31822
31823 test_819b() {
31824         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31825         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31826         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31827         cancel_lru_locks osc
31828         sleep 1
31829         rm -f $TDIR/$tfile
31830 }
31831 run_test 819b "too big niobuf in write"
31832
31833
31834 function test_820_start_ost() {
31835         sleep 5
31836
31837         for num in $(seq $OSTCOUNT); do
31838                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31839         done
31840 }
31841
31842 test_820() {
31843         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31844
31845         mkdir $DIR/$tdir
31846         umount_client $MOUNT || error "umount failed"
31847         for num in $(seq $OSTCOUNT); do
31848                 stop ost$num
31849         done
31850
31851         # mount client with no active OSTs
31852         # so that the client can't initialize max LOV EA size
31853         # from OSC notifications
31854         mount_client $MOUNT || error "mount failed"
31855         # delay OST starting to keep this 0 max EA size for a while
31856         test_820_start_ost &
31857
31858         # create a directory on MDS2
31859         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31860                 error "Failed to create directory"
31861         # open intent should update default EA size
31862         # see mdc_update_max_ea_from_body()
31863         # notice this is the very first RPC to MDS2
31864         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31865         ret=$?
31866         echo $out
31867         # With SSK, this situation can lead to -EPERM being returned.
31868         # In that case, simply retry.
31869         if [ $ret -ne 0 ] && $SHARED_KEY; then
31870                 if echo "$out" | grep -q "not permitted"; then
31871                         cp /etc/services $DIR/$tdir/mds2
31872                         ret=$?
31873                 fi
31874         fi
31875         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31876 }
31877 run_test 820 "update max EA from open intent"
31878
31879 test_823() {
31880         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31881         local OST_MAX_PRECREATE=20000
31882
31883         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31884                 skip "Need MDS version at least 2.14.56"
31885
31886         save_lustre_params mds1 \
31887                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31888         do_facet $SINGLEMDS "$LCTL set_param -n \
31889                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31890         do_facet $SINGLEMDS "$LCTL set_param -n \
31891                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31892
31893         stack_trap "restore_lustre_params < $p; rm $p"
31894
31895         do_facet $SINGLEMDS "$LCTL set_param -n \
31896                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31897
31898         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31899                       osp.$FSNAME-OST0000*MDT0000.create_count")
31900         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31901                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31902         local expect_count=$(((($max/2)/256) * 256))
31903
31904         log "setting create_count to 100200:"
31905         log " -result- count: $count with max: $max, expecting: $expect_count"
31906
31907         [[ $count -eq expect_count ]] ||
31908                 error "Create count not set to max precreate."
31909 }
31910 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31911
31912 test_831() {
31913         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31914                 skip "Need MDS version 2.14.56"
31915
31916         local sync_changes=$(do_facet $SINGLEMDS \
31917                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31918
31919         [ "$sync_changes" -gt 100 ] &&
31920                 skip "Sync changes $sync_changes > 100 already"
31921
31922         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31923
31924         $LFS mkdir -i 0 $DIR/$tdir
31925         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31926
31927         save_lustre_params mds1 \
31928                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31929         save_lustre_params mds1 \
31930                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31931
31932         do_facet mds1 "$LCTL set_param -n \
31933                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31934                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31935         stack_trap "restore_lustre_params < $p" EXIT
31936
31937         createmany -o $DIR/$tdir/f- 1000
31938         unlinkmany $DIR/$tdir/f- 1000 &
31939         local UNLINK_PID=$!
31940
31941         while sleep 1; do
31942                 sync_changes=$(do_facet mds1 \
31943                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31944                 # the check in the code is racy, fail the test
31945                 # if the value above the limit by 10.
31946                 [ $sync_changes -gt 110 ] && {
31947                         kill -2 $UNLINK_PID
31948                         wait
31949                         error "osp changes throttling failed, $sync_changes>110"
31950                 }
31951                 kill -0 $UNLINK_PID 2> /dev/null || break
31952         done
31953         wait
31954 }
31955 run_test 831 "throttling unlink/setattr queuing on OSP"
31956
31957 test_832() {
31958         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31959         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31960                 skip "Need MDS version 2.15.52+"
31961         is_rmentry_supported || skip "rm_entry not supported"
31962
31963         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31964         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31965         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31966                 error "mkdir remote_dir failed"
31967         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31968                 error "mkdir striped_dir failed"
31969         touch $DIR/$tdir/file || error "touch file failed"
31970         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31971         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31972 }
31973 run_test 832 "lfs rm_entry"
31974
31975 test_833() {
31976         local file=$DIR/$tfile
31977
31978         stack_trap "rm -f $file" EXIT
31979         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31980
31981         local wpid
31982         local rpid
31983         local rpid2
31984
31985         # Buffered I/O write
31986         (
31987                 while [ ! -e $DIR/sanity.833.lck ]; do
31988                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31989                                 error "failed to write $file"
31990                         sleep 0.$((RANDOM % 4 + 1))
31991                 done
31992         )&
31993         wpid=$!
31994
31995         # Buffered I/O read
31996         (
31997                 while [ ! -e $DIR/sanity.833.lck ]; do
31998                         dd if=$file of=/dev/null bs=1M count=50 ||
31999                                 error "failed to read $file"
32000                         sleep 0.$((RANDOM % 4 + 1))
32001                 done
32002         )&
32003         rpid=$!
32004
32005         # Direct I/O read
32006         (
32007                 while [ ! -e $DIR/sanity.833.lck ]; do
32008                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
32009                                 error "failed to read $file in direct I/O mode"
32010                         sleep 0.$((RANDOM % 4 + 1))
32011                 done
32012         )&
32013         rpid2=$!
32014
32015         sleep 30
32016         touch $DIR/sanity.833.lck
32017         wait $wpid || error "$?: buffered write failed"
32018         wait $rpid || error "$?: buffered read failed"
32019         wait $rpid2 || error "$?: direct read failed"
32020 }
32021 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
32022
32023 test_842() {
32024         local oss1=$(facet_host ost1)
32025
32026         # Try to insert the module.  This will leave results in dmesg
32027         now=$(date +%s)
32028         log "STAMP $now" > /dev/kmsg
32029         do_rpc_nodes $oss1 load_module kunit/ldlm_extent ||
32030                 error "$oss1 load_module ldlm_extent failed"
32031
32032         do_node $oss1 dmesg | sed -n -e "1,/STAMP $now/d" -e '/ldlm_extent:/p'
32033         do_node $oss1 rmmod -v ldlm_extent ||
32034                 error "rmmod failed (may trigger a failure in a later test)"
32035 }
32036 run_test 842 "Measure ldlm_extent performance"
32037
32038 test_850() {
32039         local dir=$DIR/$tdir
32040         local file=$dir/$tfile
32041         local statsfile=$dir/all_job_stats.txt
32042
32043         test_mkdir -p $dir || error "failed to create dir $dir"
32044         echo "abcdefg" > $file || error "failed to create file $file"
32045
32046         # read job_stats in the living system
32047         lljobstat -n 1 ||
32048                 error "failed to run lljobstat on living system"
32049
32050         $LCTL get_param *.*.job_stats > $statsfile
32051         lljobstat --statsfile=$statsfile ||
32052                 error "failed to run lljobstat on file $statsfile"
32053 }
32054 run_test 850 "lljobstat can parse living and aggregated job_stats"
32055
32056 test_851() {
32057         local dir=$DIR/$tdir
32058         local file=$dir/f_test_851_$$
32059         local report=/tmp/report_test_851_$$
32060         local fanotify_prog=monitor_lustrefs
32061         local pid
32062
32063         test_mkdir $dir || error "failed to create dir $dir"
32064
32065         $fanotify_prog $DIR > $report &
32066         pid=$!
32067
32068         sleep 1
32069         if ! kill -0 $pid; then
32070                 error "failed to start $fanoify_prog"
32071         fi
32072
32073         stack_trap "kill $pid"
32074         stack_trap "rm -f $report"
32075
32076         echo "1234567890" > $file
32077         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32078                 error "fanotify did not report anything after 30 seconds"
32079         grep -a -E "open.*:$file:" $report ||
32080                 error "no open event for writing $file"
32081         grep -a -E "write.*:$file:" $report ||
32082                 error "no write event for writing $file"
32083         grep -a -E "close.*:$file:" $report ||
32084                 error "no close event for writing $file"
32085
32086         > $report
32087         cat $file
32088         wait_update_cond localhost "stat -c %s $report" "-gt" "0" 30 ||
32089                 error "fanotify did not report anything after 30 seconds"
32090         grep -a -E "open.*:$file:" $report ||
32091                 error "no open event for reading $file"
32092         grep -a -E "read.*:$file:" $report ||
32093                 error "no write event for reading $file"
32094         grep -a -E "close.*:$file:" $report ||
32095                 error "no close event for reading $file"
32096 }
32097 run_test 851 "fanotify can monitor open/read/write/close events for lustre fs"
32098
32099 #
32100 # tests that do cleanup/setup should be run at the end
32101 #
32102
32103 test_900() {
32104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32105         local ls
32106
32107         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
32108         $LCTL set_param fail_loc=0x903
32109
32110         cancel_lru_locks MGC
32111
32112         FAIL_ON_ERROR=true cleanup
32113         FAIL_ON_ERROR=true setup
32114 }
32115 run_test 900 "umount should not race with any mgc requeue thread"
32116
32117 # LUS-6253/LU-11185
32118 test_901() {
32119         local old
32120         local count
32121         local oldc
32122         local newc
32123         local olds
32124         local news
32125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
32126
32127         # some get_param have a bug to handle dot in param name
32128         cancel_lru_locks MGC
32129         old=$(mount -t lustre | wc -l)
32130         # 1 config+sptlrpc
32131         # 2 params
32132         # 3 nodemap
32133         # 4 IR
32134         old=$((old * 4))
32135         oldc=0
32136         count=0
32137         while [ $old -ne $oldc ]; do
32138                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32139                 sleep 1
32140                 ((count++))
32141                 if [ $count -ge $TIMEOUT ]; then
32142                         error "too large timeout"
32143                 fi
32144         done
32145         umount_client $MOUNT || error "umount failed"
32146         mount_client $MOUNT || error "mount failed"
32147         cancel_lru_locks MGC
32148         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
32149
32150         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
32151
32152         return 0
32153 }
32154 run_test 901 "don't leak a mgc lock on client umount"
32155
32156 # LU-13377
32157 test_902() {
32158         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
32159                 skip "client does not have LU-13377 fix"
32160         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
32161         $LCTL set_param fail_loc=0x1415
32162         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
32163         cancel_lru_locks osc
32164         rm -f $DIR/$tfile
32165 }
32166 run_test 902 "test short write doesn't hang lustre"
32167
32168 # LU-14711
32169 test_903() {
32170         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
32171         echo "blah" > $DIR/${tfile}-2
32172         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
32173         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
32174         $LCTL set_param fail_loc=0x417 fail_val=20
32175
32176         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
32177         sleep 1 # To start the destroy
32178         wait_destroy_complete 150 || error "Destroy taking too long"
32179         cat $DIR/$tfile > /dev/null || error "Evicted"
32180 }
32181 run_test 903 "Test long page discard does not cause evictions"
32182
32183 test_904() {
32184         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
32185         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
32186                 grep -q project || skip "skip project quota not supported"
32187
32188         local testfile="$DIR/$tdir/$tfile"
32189         local xattr="trusted.projid"
32190         local projid
32191         local mdts=$(comma_list $(mdts_nodes))
32192         local saved=$(do_facet mds1 $LCTL get_param -n \
32193                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
32194
32195         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
32196         stack_trap "do_nodes $mdts $LCTL set_param \
32197                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
32198
32199         mkdir -p $DIR/$tdir
32200         touch $testfile
32201         #hide projid xattr on server
32202         $LFS project -p 1 $testfile ||
32203                 error "set $testfile project id failed"
32204         getfattr -m - $testfile | grep $xattr &&
32205                 error "do not show trusted.projid when disabled on server"
32206         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
32207         #should be hidden when projid is 0
32208         $LFS project -p 0 $testfile ||
32209                 error "set $testfile project id failed"
32210         getfattr -m - $testfile | grep $xattr &&
32211                 error "do not show trusted.projid with project ID 0"
32212
32213         #still can getxattr explicitly
32214         projid=$(getfattr -n $xattr $testfile |
32215                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32216         [ $projid == "0" ] ||
32217                 error "projid expected 0 not $projid"
32218
32219         #set the projid via setxattr
32220         setfattr -n $xattr -v "1000" $testfile ||
32221                 error "setattr failed with $?"
32222         projid=($($LFS project $testfile))
32223         [ ${projid[0]} == "1000" ] ||
32224                 error "projid expected 1000 not $projid"
32225
32226         #check the new projid via getxattr
32227         $LFS project -p 1001 $testfile ||
32228                 error "set $testfile project id failed"
32229         getfattr -m - $testfile | grep $xattr ||
32230                 error "should show trusted.projid when project ID != 0"
32231         projid=$(getfattr -n $xattr $testfile |
32232                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32233         [ $projid == "1001" ] ||
32234                 error "projid expected 1001 not $projid"
32235
32236         #try to set invalid projid
32237         setfattr -n $xattr -v "4294967295" $testfile &&
32238                 error "set invalid projid should fail"
32239
32240         #remove the xattr means setting projid to 0
32241         setfattr -x $xattr $testfile ||
32242                 error "setfattr failed with $?"
32243         projid=($($LFS project $testfile))
32244         [ ${projid[0]} == "0" ] ||
32245                 error "projid expected 0 not $projid"
32246
32247         #should be hidden when parent has inherit flag and same projid
32248         $LFS project -srp 1002 $DIR/$tdir ||
32249                 error "set $tdir project id failed"
32250         getfattr -m - $testfile | grep $xattr &&
32251                 error "do not show trusted.projid with inherit flag"
32252
32253         #still can getxattr explicitly
32254         projid=$(getfattr -n $xattr $testfile |
32255                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
32256         [ $projid == "1002" ] ||
32257                 error "projid expected 1002 not $projid"
32258 }
32259 run_test 904 "virtual project ID xattr"
32260
32261 # LU-8582
32262 test_905() {
32263         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
32264                 skip "need OST version >= 2.15.50.220 for fail_loc"
32265
32266         remote_ost_nodsh && skip "remote OST with nodsh"
32267         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
32268
32269         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
32270
32271         #define OBD_FAIL_OST_OPCODE 0x253
32272         # OST_LADVISE = 21
32273         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32274         $LFS ladvise -a willread $DIR/$tfile &&
32275                 error "unexpected success of ladvise with fault injection"
32276         $LFS ladvise -a willread $DIR/$tfile |&
32277                 grep -q "Operation not supported"
32278         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32279 }
32280 run_test 905 "bad or new opcode should not stuck client"
32281
32282 test_906() {
32283         grep -q io_uring_setup /proc/kallsyms ||
32284                 skip "Client OS does not support io_uring I/O engine"
32285         io_uring_probe || skip "kernel does not support io_uring fully"
32286         which fio || skip_env "no fio installed"
32287         fio --enghelp | grep -q io_uring ||
32288                 skip_env "fio does not support io_uring I/O engine"
32289
32290         local file=$DIR/$tfile
32291         local ioengine="io_uring"
32292         local numjobs=2
32293         local size=50M
32294
32295         fio --name=seqwrite --ioengine=$ioengine        \
32296                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32297                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32298                 error "fio seqwrite $file failed"
32299
32300         fio --name=seqread --ioengine=$ioengine \
32301                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32302                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32303                 error "fio seqread $file failed"
32304
32305         rm -f $file || error "rm -f $file failed"
32306 }
32307 run_test 906 "Simple test for io_uring I/O engine via fio"
32308
32309 test_907() {
32310         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32311
32312         # set stripe size to max rpc size
32313         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32314         $LFS getstripe $DIR/$tfile
32315 #define OBD_FAIL_OST_EROFS               0x216
32316         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32317
32318         local bs=$((max_pages * PAGE_SIZE / 16))
32319
32320         # write full one stripe and one block
32321         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32322
32323         rm $DIR/$tfile || error "rm failed"
32324 }
32325 run_test 907 "write rpc error during unlink"
32326
32327 complete_test $SECONDS
32328 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32329 check_and_cleanup_lustre
32330 if [ "$I_MOUNTED" != "yes" ]; then
32331         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32332 fi
32333 exit_status