Whamcloud - gitweb
LU-17482 llite: short read could mess up next read offset
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 SOCKETSERVER=${SOCKETSERVER:-socketserver}
23 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
24 MEMHOG=${MEMHOG:-memhog}
25 DIRECTIO=${DIRECTIO:-directio}
26 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
27 DEF_STRIPE_COUNT=-1
28 CHECK_GRANT=${CHECK_GRANT:-"yes"}
29 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
30
31 TRACE=${TRACE:-""}
32 LUSTRE=${LUSTRE:-$(dirname $0)/..}
33 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
34 . $LUSTRE/tests/test-framework.sh
35 init_test_env "$@"
36
37 init_logging
38
39 ALWAYS_EXCEPT="$SANITY_EXCEPT "
40 always_except LU-9693  42a 42c
41 always_except LU-6493  42b
42 always_except LU-16515 118c 118d
43 always_except LU-8411  407
44
45 if $SHARED_KEY; then
46         always_except LU-14181 64e 64f
47         always_except LU-17127 39o
48 fi
49
50 # skip the grant tests for ARM until they are fixed
51 if [[ $(uname -m) = aarch64 ]]; then
52         always_except LU-11671 45
53 fi
54
55 # skip nfs tests on kernels >= 4.12.0 until they are fixed
56 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
57         always_except LU-12661 817
58 fi
59 # skip cgroup tests on RHEL8.1 kernels until they are fixed
60 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
61       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
62         always_except LU-13063 411a
63 fi
64
65 # skip cgroup tests for kernels < v4.18.0
66 if (( $LINUX_VERSION_CODE < $(version_code 4.18.0) )); then
67         always_except LU-13063 411b
68 fi
69
70 #                                  5              12     8   12  15   (min)"
71 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
72
73 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
74         #                                               13    (min)"
75         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
76 fi
77
78 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
79         always_except LU-1941 130b 130c 130d 130e 130f 130g
80         always_except LU-9054 312
81 fi
82
83 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
84
85 # Get the SLES distro version
86 #
87 # Returns a version string that should only be used in comparing
88 # strings returned by version_code()
89 sles_version_code()
90 {
91         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
92
93         # All SuSE Linux versions have one decimal. version_code expects two
94         local sles_version=$version.0
95         version_code $sles_version
96 }
97
98 # Check if we are running on Ubuntu or SLES so we can make decisions on
99 # what tests to run
100 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
101         sles_version=$(sles_version_code)
102         (( $sles_version >= $(version_code 11.4.0) )) ||
103                 always_except LU-4341 170
104
105         (( $sles_version >= $(version_code 12.0.0) )) ||
106                 always_except LU-3703 234
107 elif [ -r /etc/redhat-release ]; then
108         rhel_version=$(cat /etc/redhat-release |
109                 sed -e 's/^[^0-9.]*//g' | sed -e 's/[ ].*//')
110         if (( $(version_code $rhel_version) >= $(version_code 9.3.0) )); then
111                 # disable test_906 temporarily until rhel9.3 solves the
112                 # failure on fio io_uring I/O engine.
113                 always_except LU-17289 906
114         fi
115 elif [ -r /etc/os-release ]; then
116         if grep -qi ubuntu /etc/os-release; then
117                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
118                                                 -e 's/^VERSION=//p' \
119                                                 /etc/os-release |
120                                                 awk '{ print $1 }'))
121
122                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
123                         always_except LU-10366 410
124                 fi
125         fi
126 fi
127
128 build_test_filter
129 FAIL_ON_ERROR=false
130
131 cleanup() {
132         echo -n "cln.."
133         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
134         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
135 }
136 setup() {
137         echo -n "mnt.."
138         load_modules
139         setupall || exit 10
140         echo "done"
141 }
142
143 check_swap_layouts_support()
144 {
145         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
146                 skip "Does not support layout lock."
147 }
148
149 check_swap_layout_no_dom()
150 {
151         local FOLDER=$1
152         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
153         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
154 }
155
156 check_and_setup_lustre
157 DIR=${DIR:-$MOUNT}
158 assert_DIR
159
160 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
161
162 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
163 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
164 rm -rf $DIR/[Rdfs][0-9]*
165
166 # $RUNAS_ID may get set incorrectly somewhere else
167 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
168         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
169
170 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
171
172 if [ "${ONLY}" = "MOUNT" ] ; then
173         echo "Lustre is up, please go on"
174         exit
175 fi
176
177 echo "preparing for tests involving mounts"
178 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
179 touch $EXT2_DEV
180 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
181 echo # add a newline after mke2fs.
182
183 umask 077
184
185 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
186
187 # ensure all internal functions know we want full debug
188 export PTLDEBUG=all
189 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
190
191 test_0a() {
192         touch $DIR/$tfile
193         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
194         rm $DIR/$tfile
195         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
196 }
197 run_test 0a "touch; rm ====================="
198
199 test_0b() {
200         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
201         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
202 }
203 run_test 0b "chmod 0755 $DIR ============================="
204
205 test_0c() {
206         $LCTL get_param mdc.*.import | grep "state: FULL" ||
207                 error "import not FULL"
208         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
209                 error "bad target"
210 }
211 run_test 0c "check import proc"
212
213 test_0d() { # LU-3397
214         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
215                 skip "proc exports not supported before 2.10.57"
216
217         local mgs_exp="mgs.MGS.exports"
218         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
219         local exp_client_nid
220         local exp_client_version
221         local exp_val
222         local imp_val
223         local temp_imp=$DIR/$tfile.import
224         local temp_exp=$DIR/$tfile.export
225
226         # save mgc import file to $temp_imp
227         $LCTL get_param mgc.*.import | tee $temp_imp
228         # Check if client uuid is found in MGS export
229         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
230                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
231                         $client_uuid ] &&
232                         break;
233         done
234         # save mgs export file to $temp_exp
235         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
236
237         # Compare the value of field "connect_flags"
238         imp_val=$(grep "connect_flags" $temp_imp)
239         exp_val=$(grep "connect_flags" $temp_exp)
240         [ "$exp_val" == "$imp_val" ] ||
241                 error "export flags '$exp_val' != import flags '$imp_val'"
242
243         # Compare client versions.  Only compare top-3 fields for compatibility
244         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
245         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
246         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
247         [ "$exp_val" == "$imp_val" ] ||
248                 error "exp version '$exp_client_version'($exp_val) != " \
249                         "'$(lustre_build_version client)'($imp_val)"
250 }
251 run_test 0d "check export proc ============================="
252
253 test_0e() { # LU-13417
254         (( $MDSCOUNT > 1 )) ||
255                 skip "We need at least 2 MDTs for this test"
256
257         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
258                 skip "Need server version at least 2.14.51"
259
260         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
261         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
262
263         [ $default_lmv_count -eq 1 ] ||
264                 error "$MOUNT default stripe count $default_lmv_count"
265
266         [ $default_lmv_index -eq -1 ] ||
267                 error "$MOUNT default stripe index $default_lmv_index"
268
269         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
270         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
271
272         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
273         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
274
275         [ $mdt_index1 -eq $mdt_index2 ] &&
276                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
277
278         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
279 }
280 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
281
282 test_0f() { # LU-17471
283         (( $MDS1_VERSION < $(version_code 2.17.53) )) ||
284                 skip "MDS >= 2.17.53 removes /proc/.../brw_stats symlink"
285         (( $MDS1_VERSION < $(version_code 2.14.55-100-g8a84c7f9c7) ||
286            $MDS1_VERSION > $(version_code 2.15.60-25) )) ||
287                 skip "MDS was missing /proc/.../brw_stats value"
288
289         local path="lustre/osd-$FSTYPE/$FSNAME-MDT0000/brw_stats"
290         local out_proc=$(do_facet mds1 grep snapshot_time /proc/fs/$path)
291
292         [[ -n "$out_proc" ]] || error "brw_stats /proc/fs/$path not found"
293 }
294 run_test 0f "Symlink to /sys/kernel/debug/*/*/brw_stats should work properly"
295
296 test_1() {
297         test_mkdir $DIR/$tdir
298         test_mkdir $DIR/$tdir/d2
299         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
300         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
301         rmdir $DIR/$tdir/d2
302         rmdir $DIR/$tdir
303         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
304 }
305 run_test 1 "mkdir; remkdir; rmdir"
306
307 test_2() {
308         test_mkdir $DIR/$tdir
309         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
310         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
311         rm -r $DIR/$tdir
312         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
313 }
314 run_test 2 "mkdir; touch; rmdir; check file"
315
316 test_3() {
317         test_mkdir $DIR/$tdir
318         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
319         touch $DIR/$tdir/$tfile
320         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
321         rm -r $DIR/$tdir
322         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
323 }
324 run_test 3 "mkdir; touch; rmdir; check dir"
325
326 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
327 test_4() {
328         test_mkdir -i 1 $DIR/$tdir
329
330         touch $DIR/$tdir/$tfile ||
331                 error "Create file under remote directory failed"
332
333         rmdir $DIR/$tdir &&
334                 error "Expect error removing in-use dir $DIR/$tdir"
335
336         test -d $DIR/$tdir || error "Remote directory disappeared"
337
338         rm -rf $DIR/$tdir || error "remove remote dir error"
339 }
340 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
341
342 test_5() {
343         test_mkdir $DIR/$tdir
344         test_mkdir $DIR/$tdir/d2
345         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
346         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
347         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
348 }
349 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
350
351 test_6a() {
352         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
353         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
354         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
355                 error "$tfile does not have perm 0666 or UID $UID"
356         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
357         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
358                 error "$tfile should be 0666 and owned by UID $UID"
359 }
360 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
361
362 test_6c() {
363         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
364
365         touch $DIR/$tfile
366         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
367         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
368                 error "$tfile should be owned by UID $RUNAS_ID"
369         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
370         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
371                 error "$tfile should be owned by UID $RUNAS_ID"
372 }
373 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
374
375 test_6e() {
376         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
377
378         touch $DIR/$tfile
379         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
380         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
381                 error "$tfile should be owned by GID $UID"
382         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
383         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
384                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
385 }
386 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
387
388 test_6g() {
389         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
390
391         test_mkdir $DIR/$tdir
392         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
393         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
394         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
395         test_mkdir $DIR/$tdir/d/subdir
396         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
397                 error "$tdir/d/subdir should be GID $RUNAS_GID"
398         if [[ $MDSCOUNT -gt 1 ]]; then
399                 # check remote dir sgid inherite
400                 $LFS mkdir -i 0 $DIR/$tdir.local ||
401                         error "mkdir $tdir.local failed"
402                 chmod g+s $DIR/$tdir.local ||
403                         error "chmod $tdir.local failed"
404                 chgrp $RUNAS_GID $DIR/$tdir.local ||
405                         error "chgrp $tdir.local failed"
406                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
407                         error "mkdir $tdir.remote failed"
408                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
409                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
410                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
411                         error "$tdir.remote should be mode 02755"
412         fi
413 }
414 run_test 6g "verify new dir in sgid dir inherits group"
415
416 test_6h() { # bug 7331
417         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
418
419         touch $DIR/$tfile || error "touch failed"
420         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
421         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
422                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
423         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
424                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
425 }
426 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
427
428 test_7a() {
429         test_mkdir $DIR/$tdir
430         $MCREATE $DIR/$tdir/$tfile
431         chmod 0666 $DIR/$tdir/$tfile
432         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
433                 error "$tdir/$tfile should be mode 0666"
434 }
435 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
436
437 test_7b() {
438         if [ ! -d $DIR/$tdir ]; then
439                 test_mkdir $DIR/$tdir
440         fi
441         $MCREATE $DIR/$tdir/$tfile
442         echo -n foo > $DIR/$tdir/$tfile
443         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
444         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
445 }
446 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
447
448 test_8() {
449         test_mkdir $DIR/$tdir
450         touch $DIR/$tdir/$tfile
451         chmod 0666 $DIR/$tdir/$tfile
452         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
453                 error "$tfile mode not 0666"
454 }
455 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
456
457 test_9() {
458         test_mkdir $DIR/$tdir
459         test_mkdir $DIR/$tdir/d2
460         test_mkdir $DIR/$tdir/d2/d3
461         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
462 }
463 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
464
465 test_10() {
466         test_mkdir $DIR/$tdir
467         test_mkdir $DIR/$tdir/d2
468         touch $DIR/$tdir/d2/$tfile
469         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
470                 error "$tdir/d2/$tfile not a file"
471 }
472 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
473
474 test_11() {
475         test_mkdir $DIR/$tdir
476         test_mkdir $DIR/$tdir/d2
477         chmod 0666 $DIR/$tdir/d2
478         chmod 0705 $DIR/$tdir/d2
479         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
480                 error "$tdir/d2 mode not 0705"
481 }
482 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
483
484 test_12() {
485         test_mkdir $DIR/$tdir
486         touch $DIR/$tdir/$tfile
487         chmod 0666 $DIR/$tdir/$tfile
488         chmod 0654 $DIR/$tdir/$tfile
489         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
490                 error "$tdir/d2 mode not 0654"
491 }
492 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
493
494 test_13() {
495         test_mkdir $DIR/$tdir
496         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
497         >  $DIR/$tdir/$tfile
498         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
499                 error "$tdir/$tfile size not 0 after truncate"
500 }
501 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
502
503 test_14() {
504         test_mkdir $DIR/$tdir
505         touch $DIR/$tdir/$tfile
506         rm $DIR/$tdir/$tfile
507         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
508 }
509 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
510
511 test_15() {
512         test_mkdir $DIR/$tdir
513         touch $DIR/$tdir/$tfile
514         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
515         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
516                 error "$tdir/${tfile_2} not a file after rename"
517         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
518 }
519 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
520
521 test_16() {
522         test_mkdir $DIR/$tdir
523         touch $DIR/$tdir/$tfile
524         rm -rf $DIR/$tdir/$tfile
525         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
526 }
527 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
528
529 test_17a() {
530         test_mkdir $DIR/$tdir
531         touch $DIR/$tdir/$tfile
532         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
533         ls -l $DIR/$tdir
534         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
535                 error "$tdir/l-exist not a symlink"
536         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
537                 error "$tdir/l-exist not referencing a file"
538         rm -f $DIR/$tdir/l-exist
539         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
540 }
541 run_test 17a "symlinks: create, remove (real)"
542
543 test_17b() {
544         test_mkdir $DIR/$tdir
545         ln -s no-such-file $DIR/$tdir/l-dangle
546         ls -l $DIR/$tdir
547         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
548                 error "$tdir/l-dangle not referencing no-such-file"
549         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
550                 error "$tdir/l-dangle not referencing non-existent file"
551         rm -f $DIR/$tdir/l-dangle
552         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
553 }
554 run_test 17b "symlinks: create, remove (dangling)"
555
556 test_17c() { # bug 3440 - don't save failed open RPC for replay
557         test_mkdir $DIR/$tdir
558         ln -s foo $DIR/$tdir/$tfile
559         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
560 }
561 run_test 17c "symlinks: open dangling (should return error)"
562
563 test_17d() {
564         test_mkdir $DIR/$tdir
565         ln -s foo $DIR/$tdir/$tfile
566         touch $DIR/$tdir/$tfile || error "creating to new symlink"
567 }
568 run_test 17d "symlinks: create dangling"
569
570 test_17e() {
571         test_mkdir $DIR/$tdir
572         local foo=$DIR/$tdir/$tfile
573         ln -s $foo $foo || error "create symlink failed"
574         ls -l $foo || error "ls -l failed"
575         ls $foo && error "ls not failed" || true
576 }
577 run_test 17e "symlinks: create recursive symlink (should return error)"
578
579 test_17f() {
580         test_mkdir $DIR/$tdir
581         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
582         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
583         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
584         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
585         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
586         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
587         ls -l  $DIR/$tdir
588 }
589 run_test 17f "symlinks: long and very long symlink name"
590
591 # str_repeat(S, N) generate a string that is string S repeated N times
592 str_repeat() {
593         local s=$1
594         local n=$2
595         local ret=''
596         while [ $((n -= 1)) -ge 0 ]; do
597                 ret=$ret$s
598         done
599         echo $ret
600 }
601
602 # Long symlinks and LU-2241
603 test_17g() {
604         test_mkdir $DIR/$tdir
605         local TESTS="59 60 61 4094 4095"
606
607         # Fix for inode size boundary in 2.1.4
608         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
609                 TESTS="4094 4095"
610
611         # Patch not applied to 2.2 or 2.3 branches
612         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
613         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
614                 TESTS="4094 4095"
615
616         for i in $TESTS; do
617                 local SYMNAME=$(str_repeat 'x' $i)
618                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
619                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
620         done
621 }
622 run_test 17g "symlinks: really long symlink name and inode boundaries"
623
624 test_17h() { #bug 17378
625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
626         remote_mds_nodsh && skip "remote MDS with nodsh"
627
628         local mdt_idx
629
630         test_mkdir $DIR/$tdir
631         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
632         $LFS setstripe -c -1 $DIR/$tdir
633         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
634         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
635         touch $DIR/$tdir/$tfile || true
636 }
637 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
638
639 test_17i() { #bug 20018
640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
641         remote_mds_nodsh && skip "remote MDS with nodsh"
642
643         local foo=$DIR/$tdir/$tfile
644         local mdt_idx
645
646         test_mkdir -c1 $DIR/$tdir
647         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
648         ln -s $foo $foo || error "create symlink failed"
649 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
650         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
651         ls -l $foo && error "error not detected"
652         return 0
653 }
654 run_test 17i "don't panic on short symlink (should return error)"
655
656 test_17k() { #bug 22301
657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
658         [[ -z "$(which rsync 2>/dev/null)" ]] &&
659                 skip "no rsync command"
660         rsync --help | grep -q xattr ||
661                 skip_env "$(rsync --version | head -n1) does not support xattrs"
662         test_mkdir $DIR/$tdir
663         test_mkdir $DIR/$tdir.new
664         touch $DIR/$tdir/$tfile
665         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
666         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
667                 error "rsync failed with xattrs enabled"
668 }
669 run_test 17k "symlinks: rsync with xattrs enabled"
670
671 test_17l() { # LU-279
672         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
673                 skip "no getfattr command"
674
675         test_mkdir $DIR/$tdir
676         touch $DIR/$tdir/$tfile
677         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
678         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
679                 # -h to not follow symlinks. -m '' to list all the xattrs.
680                 # grep to remove first line: '# file: $path'.
681                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
682                 do
683                         lgetxattr_size_check $path $xattr ||
684                                 error "lgetxattr_size_check $path $xattr failed"
685                 done
686         done
687 }
688 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
689
690 # LU-1540
691 test_17m() {
692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
693         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
694         remote_mds_nodsh && skip "remote MDS with nodsh"
695         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
696         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
697                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
698
699         local short_sym="0123456789"
700         local wdir=$DIR/$tdir
701         local i
702
703         test_mkdir $wdir
704         long_sym=$short_sym
705         # create a long symlink file
706         for ((i = 0; i < 4; ++i)); do
707                 long_sym=${long_sym}${long_sym}
708         done
709
710         echo "create 512 short and long symlink files under $wdir"
711         for ((i = 0; i < 256; ++i)); do
712                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
713                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
714         done
715
716         echo "erase them"
717         rm -f $wdir/*
718         sync
719         wait_delete_completed
720
721         echo "recreate the 512 symlink files with a shorter string"
722         for ((i = 0; i < 512; ++i)); do
723                 # rewrite the symlink file with a shorter string
724                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
725                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
726         done
727
728         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
729
730         echo "stop and checking mds${mds_index}:"
731         # e2fsck should not return error
732         stop mds${mds_index}
733         local devname=$(mdsdevname $mds_index)
734         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
735         rc=$?
736
737         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
738                 error "start mds${mds_index} failed"
739         df $MOUNT > /dev/null 2>&1
740         [ $rc -eq 0 ] ||
741                 error "e2fsck detected error for short/long symlink: rc=$rc"
742         rm -f $wdir/*
743 }
744 run_test 17m "run e2fsck against MDT which contains short/long symlink"
745
746 check_fs_consistency_17n() {
747         local mdt_index
748         local rc=0
749
750         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
751         # so it only check MDT1/MDT2 instead of all of MDTs.
752         for mdt_index in 1 2; do
753                 # e2fsck should not return error
754                 stop mds${mdt_index}
755                 local devname=$(mdsdevname $mdt_index)
756                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
757                         rc=$((rc + $?))
758
759                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
760                         error "mount mds$mdt_index failed"
761                 df $MOUNT > /dev/null 2>&1
762         done
763         return $rc
764 }
765
766 test_17n() {
767         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
769         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
770         remote_mds_nodsh && skip "remote MDS with nodsh"
771         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
772         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
773                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
774
775         local i
776
777         test_mkdir $DIR/$tdir
778         for ((i=0; i<10; i++)); do
779                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
780                         error "create remote dir error $i"
781                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
782                         error "create files under remote dir failed $i"
783         done
784
785         check_fs_consistency_17n ||
786                 error "e2fsck report error after create files under remote dir"
787
788         for ((i = 0; i < 10; i++)); do
789                 rm -rf $DIR/$tdir/remote_dir_${i} ||
790                         error "destroy remote dir error $i"
791         done
792
793         check_fs_consistency_17n ||
794                 error "e2fsck report error after unlink files under remote dir"
795
796         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
797                 skip "lustre < 2.4.50 does not support migrate mv"
798
799         for ((i = 0; i < 10; i++)); do
800                 mkdir -p $DIR/$tdir/remote_dir_${i}
801                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
802                         error "create files under remote dir failed $i"
803                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
804                         error "migrate remote dir error $i"
805         done
806         check_fs_consistency_17n || error "e2fsck report error after migration"
807
808         for ((i = 0; i < 10; i++)); do
809                 rm -rf $DIR/$tdir/remote_dir_${i} ||
810                         error "destroy remote dir error $i"
811         done
812
813         check_fs_consistency_17n || error "e2fsck report error after unlink"
814 }
815 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
816
817 test_17o() {
818         remote_mds_nodsh && skip "remote MDS with nodsh"
819         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
820                 skip "Need MDS version at least 2.3.64"
821
822         local wdir=$DIR/${tdir}o
823         local mdt_index
824         local rc=0
825
826         test_mkdir $wdir
827         touch $wdir/$tfile
828         mdt_index=$($LFS getstripe -m $wdir/$tfile)
829         mdt_index=$((mdt_index + 1))
830
831         cancel_lru_locks mdc
832         #fail mds will wait the failover finish then set
833         #following fail_loc to avoid interfer the recovery process.
834         fail mds${mdt_index}
835
836         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
837         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
838         ls -l $wdir/$tfile && rc=1
839         do_facet mds${mdt_index} lctl set_param fail_loc=0
840         [[ $rc -eq 0 ]] || error "stat file should fail"
841 }
842 run_test 17o "stat file with incompat LMA feature"
843
844 test_18() {
845         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
846         ls $DIR || error "Failed to ls $DIR: $?"
847 }
848 run_test 18 "touch .../f ; ls ... =============================="
849
850 test_19a() {
851         touch $DIR/$tfile
852         ls -l $DIR
853         rm $DIR/$tfile
854         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
855 }
856 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
857
858 test_19b() {
859         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
860 }
861 run_test 19b "ls -l .../f19 (should return error) =============="
862
863 test_19c() {
864         [ $RUNAS_ID -eq $UID ] &&
865                 skip_env "RUNAS_ID = UID = $UID -- skipping"
866
867         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
868 }
869 run_test 19c "$RUNAS touch .../f19 (should return error) =="
870
871 test_19d() {
872         cat $DIR/f19 && error || true
873 }
874 run_test 19d "cat .../f19 (should return error) =============="
875
876 test_20() {
877         touch $DIR/$tfile
878         rm $DIR/$tfile
879         touch $DIR/$tfile
880         rm $DIR/$tfile
881         touch $DIR/$tfile
882         rm $DIR/$tfile
883         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
884 }
885 run_test 20 "touch .../f ; ls -l ..."
886
887 test_21() {
888         test_mkdir $DIR/$tdir
889         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
890         ln -s dangle $DIR/$tdir/link
891         echo foo >> $DIR/$tdir/link
892         cat $DIR/$tdir/dangle
893         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
894         $CHECKSTAT -f -t file $DIR/$tdir/link ||
895                 error "$tdir/link not linked to a file"
896 }
897 run_test 21 "write to dangling link"
898
899 test_22() {
900         local wdir=$DIR/$tdir
901         test_mkdir $wdir
902         chown $RUNAS_ID:$RUNAS_GID $wdir
903         (cd $wdir || error "cd $wdir failed";
904                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
905                 $RUNAS tar xf -)
906         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
907         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
908         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
909                 error "checkstat -u failed"
910 }
911 run_test 22 "unpack tar archive as non-root user"
912
913 # was test_23
914 test_23a() {
915         test_mkdir $DIR/$tdir
916         local file=$DIR/$tdir/$tfile
917
918         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
919         openfile -f O_CREAT:O_EXCL $file &&
920                 error "$file recreate succeeded" || true
921 }
922 run_test 23a "O_CREAT|O_EXCL in subdir"
923
924 test_23b() { # bug 18988
925         test_mkdir $DIR/$tdir
926         local file=$DIR/$tdir/$tfile
927
928         rm -f $file
929         echo foo > $file || error "write filed"
930         echo bar >> $file || error "append filed"
931         $CHECKSTAT -s 8 $file || error "wrong size"
932         rm $file
933 }
934 run_test 23b "O_APPEND check"
935
936 # LU-9409, size with O_APPEND and tiny writes
937 test_23c() {
938         local file=$DIR/$tfile
939
940         # single dd
941         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
942         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
943         rm -f $file
944
945         # racing tiny writes
946         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
947         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
948         wait
949         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
950         rm -f $file
951
952         #racing tiny & normal writes
953         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
954         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
955         wait
956         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
957         rm -f $file
958
959         #racing tiny & normal writes 2, ugly numbers
960         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
961         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
962         wait
963         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
964         rm -f $file
965 }
966 run_test 23c "O_APPEND size checks for tiny writes"
967
968 # LU-11069 file offset is correct after appending writes
969 test_23d() {
970         local file=$DIR/$tfile
971         local offset
972
973         echo CentaurHauls > $file
974         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
975         if ((offset != 26)); then
976                 error "wrong offset, expected 26, got '$offset'"
977         fi
978 }
979 run_test 23d "file offset is correct after appending writes"
980
981 # rename sanity
982 test_24a() {
983         echo '-- same directory rename'
984         test_mkdir $DIR/$tdir
985         touch $DIR/$tdir/$tfile.1
986         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
987         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
988 }
989 run_test 24a "rename file to non-existent target"
990
991 test_24b() {
992         test_mkdir $DIR/$tdir
993         touch $DIR/$tdir/$tfile.{1,2}
994         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
995         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
996         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
997 }
998 run_test 24b "rename file to existing target"
999
1000 test_24c() {
1001         test_mkdir $DIR/$tdir
1002         test_mkdir $DIR/$tdir/d$testnum.1
1003         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1004         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1005         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1006 }
1007 run_test 24c "rename directory to non-existent target"
1008
1009 test_24d() {
1010         test_mkdir -c1 $DIR/$tdir
1011         test_mkdir -c1 $DIR/$tdir/d$testnum.1
1012         test_mkdir -c1 $DIR/$tdir/d$testnum.2
1013         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
1014         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
1015         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
1016 }
1017 run_test 24d "rename directory to existing target"
1018
1019 test_24e() {
1020         echo '-- cross directory renames --'
1021         test_mkdir $DIR/R5a
1022         test_mkdir $DIR/R5b
1023         touch $DIR/R5a/f
1024         mv $DIR/R5a/f $DIR/R5b/g
1025         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1026         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1027 }
1028 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1029
1030 test_24f() {
1031         test_mkdir $DIR/R6a
1032         test_mkdir $DIR/R6b
1033         touch $DIR/R6a/f $DIR/R6b/g
1034         mv $DIR/R6a/f $DIR/R6b/g
1035         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1036         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1037 }
1038 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1039
1040 test_24g() {
1041         test_mkdir $DIR/R7a
1042         test_mkdir $DIR/R7b
1043         test_mkdir $DIR/R7a/d
1044         mv $DIR/R7a/d $DIR/R7b/e
1045         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1046         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1047 }
1048 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1049
1050 test_24h() {
1051         test_mkdir -c1 $DIR/R8a
1052         test_mkdir -c1 $DIR/R8b
1053         test_mkdir -c1 $DIR/R8a/d
1054         test_mkdir -c1 $DIR/R8b/e
1055         mrename $DIR/R8a/d $DIR/R8b/e
1056         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1057         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1058 }
1059 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1060
1061 test_24i() {
1062         echo "-- rename error cases"
1063         test_mkdir $DIR/R9
1064         test_mkdir $DIR/R9/a
1065         touch $DIR/R9/f
1066         mrename $DIR/R9/f $DIR/R9/a
1067         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1068         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1069         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1070 }
1071 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1072
1073 test_24j() {
1074         test_mkdir $DIR/R10
1075         mrename $DIR/R10/f $DIR/R10/g
1076         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1077         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1078         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1079 }
1080 run_test 24j "source does not exist ============================"
1081
1082 test_24k() {
1083         test_mkdir $DIR/R11a
1084         test_mkdir $DIR/R11a/d
1085         touch $DIR/R11a/f
1086         mv $DIR/R11a/f $DIR/R11a/d
1087         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1088         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1089 }
1090 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1091
1092 # bug 2429 - rename foo foo foo creates invalid file
1093 test_24l() {
1094         f="$DIR/f24l"
1095         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1096 }
1097 run_test 24l "Renaming a file to itself ========================"
1098
1099 test_24m() {
1100         f="$DIR/f24m"
1101         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1102         # on ext3 this does not remove either the source or target files
1103         # though the "expected" operation would be to remove the source
1104         $CHECKSTAT -t file ${f} || error "${f} missing"
1105         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1106 }
1107 run_test 24m "Renaming a file to a hard link to itself ========="
1108
1109 test_24n() {
1110     f="$DIR/f24n"
1111     # this stats the old file after it was renamed, so it should fail
1112     touch ${f}
1113     $CHECKSTAT ${f} || error "${f} missing"
1114     mv ${f} ${f}.rename
1115     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1116     $CHECKSTAT -a ${f} || error "${f} exists"
1117 }
1118 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1119
1120 test_24o() {
1121         test_mkdir $DIR/$tdir
1122         rename_many -s random -v -n 10 $DIR/$tdir
1123 }
1124 run_test 24o "rename of files during htree split"
1125
1126 test_24p() {
1127         test_mkdir $DIR/R12a
1128         test_mkdir $DIR/R12b
1129         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1130         mrename $DIR/R12a $DIR/R12b
1131         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1132         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1133         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1134         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1135 }
1136 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1137
1138 cleanup_multiop_pause() {
1139         trap 0
1140         kill -USR1 $MULTIPID
1141 }
1142
1143 test_24q() {
1144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1145
1146         test_mkdir $DIR/R13a
1147         test_mkdir $DIR/R13b
1148         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1149         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1150         MULTIPID=$!
1151
1152         trap cleanup_multiop_pause EXIT
1153         mrename $DIR/R13a $DIR/R13b
1154         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1155         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1156         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1157         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1158         cleanup_multiop_pause
1159         wait $MULTIPID || error "multiop close failed"
1160 }
1161 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1162
1163 test_24r() { #bug 3789
1164         test_mkdir $DIR/R14a
1165         test_mkdir $DIR/R14a/b
1166         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1167         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1168         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1169 }
1170 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1171
1172 test_24s() {
1173         test_mkdir $DIR/R15a
1174         test_mkdir $DIR/R15a/b
1175         test_mkdir $DIR/R15a/b/c
1176         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1177         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1178         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1179 }
1180 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1181
1182 test_24t() {
1183         test_mkdir $DIR/R16a
1184         test_mkdir $DIR/R16a/b
1185         test_mkdir $DIR/R16a/b/c
1186         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1187         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1188         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1189 }
1190 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1191
1192 test_24u() { # bug12192
1193         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1194         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1195 }
1196 run_test 24u "create stripe file"
1197
1198 simple_cleanup_common() {
1199         local createmany=$1
1200         local rc=0
1201
1202         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1203
1204         local start=$SECONDS
1205
1206         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1207         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1208         rc=$?
1209         wait_delete_completed
1210         echo "cleanup time $((SECONDS - start))"
1211         return $rc
1212 }
1213
1214 max_pages_per_rpc() {
1215         local mdtname="$(printf "MDT%04x" ${1:-0})"
1216         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1217 }
1218
1219 test_24v() {
1220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1221
1222         local nrfiles=${COUNT:-100000}
1223         local fname="$DIR/$tdir/$tfile"
1224
1225         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1226         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1227
1228         test_mkdir "$(dirname $fname)"
1229         # assume MDT0000 has the fewest inodes
1230         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1231         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1232         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1233
1234         stack_trap "simple_cleanup_common $nrfiles"
1235
1236         createmany -m "$fname" $nrfiles
1237
1238         cancel_lru_locks mdc
1239         lctl set_param mdc.*.stats clear
1240
1241         # was previously test_24D: LU-6101
1242         # readdir() returns correct number of entries after cursor reload
1243         local num_ls=$(ls $DIR/$tdir | wc -l)
1244         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1245         local num_all=$(ls -a $DIR/$tdir | wc -l)
1246         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1247                 [ $num_all -ne $((nrfiles + 2)) ]; then
1248                         error "Expected $nrfiles files, got $num_ls " \
1249                                 "($num_uniq unique $num_all .&..)"
1250         fi
1251         # LU-5 large readdir
1252         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1253         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1254         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1255         # take into account of overhead in lu_dirpage header and end mark in
1256         # each page, plus one in rpc_num calculation.
1257         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1258         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1259         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1260         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1261         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1262         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1263         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1264         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1265                 error "large readdir doesn't take effect: " \
1266                       "$mds_readpage should be about $rpc_max"
1267 }
1268 run_test 24v "list large directory (test hash collision, b=17560)"
1269
1270 test_24w() { # bug21506
1271         SZ1=234852
1272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1273         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1274         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1275         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1276         [[ "$SZ1" -eq "$SZ2" ]] ||
1277                 error "Error reading at the end of the file $tfile"
1278 }
1279 run_test 24w "Reading a file larger than 4Gb"
1280
1281 test_24x() {
1282         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1284         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1285                 skip "Need MDS version at least 2.7.56"
1286
1287         local MDTIDX=1
1288         local remote_dir=$DIR/$tdir/remote_dir
1289
1290         test_mkdir $DIR/$tdir
1291         $LFS mkdir -i $MDTIDX $remote_dir ||
1292                 error "create remote directory failed"
1293
1294         test_mkdir $DIR/$tdir/src_dir
1295         touch $DIR/$tdir/src_file
1296         test_mkdir $remote_dir/tgt_dir
1297         touch $remote_dir/tgt_file
1298
1299         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1300                 error "rename dir cross MDT failed!"
1301
1302         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1303                 error "rename file cross MDT failed!"
1304
1305         touch $DIR/$tdir/ln_file
1306         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1307                 error "ln file cross MDT failed"
1308
1309         rm -rf $DIR/$tdir || error "Can not delete directories"
1310 }
1311 run_test 24x "cross MDT rename/link"
1312
1313 test_24y() {
1314         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1316
1317         local remote_dir=$DIR/$tdir/remote_dir
1318         local mdtidx=1
1319
1320         test_mkdir $DIR/$tdir
1321         $LFS mkdir -i $mdtidx $remote_dir ||
1322                 error "create remote directory failed"
1323
1324         test_mkdir $remote_dir/src_dir
1325         touch $remote_dir/src_file
1326         test_mkdir $remote_dir/tgt_dir
1327         touch $remote_dir/tgt_file
1328
1329         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1330                 error "rename subdir in the same remote dir failed!"
1331
1332         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1333                 error "rename files in the same remote dir failed!"
1334
1335         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1336                 error "link files in the same remote dir failed!"
1337
1338         rm -rf $DIR/$tdir || error "Can not delete directories"
1339 }
1340 run_test 24y "rename/link on the same dir should succeed"
1341
1342 test_24z() {
1343         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1344         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1345                 skip "Need MDS version at least 2.12.51"
1346
1347         local index
1348
1349         for index in 0 1; do
1350                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1351                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1352         done
1353
1354         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1355
1356         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1357         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1358
1359         local mdts=$(comma_list $(mdts_nodes))
1360
1361         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1362         stack_trap "do_nodes $mdts $LCTL \
1363                 set_param mdt.*.enable_remote_rename=1" EXIT
1364
1365         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1366
1367         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1368         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1369 }
1370 run_test 24z "cross-MDT rename is done as cp"
1371
1372 test_24A() { # LU-3182
1373         local NFILES=5000
1374
1375         test_mkdir $DIR/$tdir
1376         stack_trap "simple_cleanup_common $NFILES"
1377         createmany -m $DIR/$tdir/$tfile $NFILES
1378         local t=$(ls $DIR/$tdir | wc -l)
1379         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1380         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1381
1382         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1383                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1384 }
1385 run_test 24A "readdir() returns correct number of entries."
1386
1387 test_24B() { # LU-4805
1388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1389
1390         local count
1391
1392         test_mkdir $DIR/$tdir
1393         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1394                 error "create striped dir failed"
1395
1396         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1397         [ $count -eq 2 ] || error "Expected 2, got $count"
1398
1399         touch $DIR/$tdir/striped_dir/a
1400
1401         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1402         [ $count -eq 3 ] || error "Expected 3, got $count"
1403
1404         touch $DIR/$tdir/striped_dir/.f
1405
1406         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1407         [ $count -eq 4 ] || error "Expected 4, got $count"
1408
1409         rm -rf $DIR/$tdir || error "Can not delete directories"
1410 }
1411 run_test 24B "readdir for striped dir return correct number of entries"
1412
1413 test_24C() {
1414         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1415
1416         mkdir $DIR/$tdir
1417         mkdir $DIR/$tdir/d0
1418         mkdir $DIR/$tdir/d1
1419
1420         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1421                 error "create striped dir failed"
1422
1423         cd $DIR/$tdir/d0/striped_dir
1424
1425         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1426         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1427         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1428
1429         [ "$d0_ino" = "$parent_ino" ] ||
1430                 error ".. wrong, expect $d0_ino, get $parent_ino"
1431
1432         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1433                 error "mv striped dir failed"
1434
1435         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1436
1437         [ "$d1_ino" = "$parent_ino" ] ||
1438                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1439 }
1440 run_test 24C "check .. in striped dir"
1441
1442 test_24E() {
1443         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1444         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1445
1446         mkdir -p $DIR/$tdir
1447         mkdir $DIR/$tdir/src_dir
1448         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1449                 error "create remote source failed"
1450
1451         touch $DIR/$tdir/src_dir/src_child/a
1452
1453         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1454                 error "create remote target dir failed"
1455
1456         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1457                 error "create remote target child failed"
1458
1459         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1460                 error "rename dir cross MDT failed!"
1461
1462         find $DIR/$tdir
1463
1464         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1465                 error "src_child still exists after rename"
1466
1467         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1468                 error "missing file(a) after rename"
1469
1470         rm -rf $DIR/$tdir || error "Can not delete directories"
1471 }
1472 run_test 24E "cross MDT rename/link"
1473
1474 test_24F () {
1475         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1476
1477         local repeats=1000
1478         [ "$SLOW" = "no" ] && repeats=100
1479
1480         mkdir -p $DIR/$tdir
1481
1482         echo "$repeats repeats"
1483         for ((i = 0; i < repeats; i++)); do
1484                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1485                 touch $DIR/$tdir/test/a || error "touch fails"
1486                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1487                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1488         done
1489
1490         true
1491 }
1492 run_test 24F "hash order vs readdir (LU-11330)"
1493
1494 test_24G () {
1495         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1496
1497         local ino1
1498         local ino2
1499
1500         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1501         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1502         touch $DIR/$tdir-0/f1 || error "touch f1"
1503         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1504         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1505         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1506         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1507         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1508 }
1509 run_test 24G "migrate symlink in rename"
1510
1511 test_24H() {
1512         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1513         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1514                 skip "MDT1 should be on another node"
1515
1516         test_mkdir -i 1 -c 1 $DIR/$tdir
1517 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1518         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1519         touch $DIR/$tdir/$tfile || error "touch failed"
1520 }
1521 run_test 24H "repeat FLD_QUERY rpc"
1522
1523 test_25a() {
1524         echo '== symlink sanity ============================================='
1525
1526         test_mkdir $DIR/d25
1527         ln -s d25 $DIR/s25
1528         touch $DIR/s25/foo ||
1529                 error "File creation in symlinked directory failed"
1530 }
1531 run_test 25a "create file in symlinked directory ==============="
1532
1533 test_25b() {
1534         [ ! -d $DIR/d25 ] && test_25a
1535         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1536 }
1537 run_test 25b "lookup file in symlinked directory ==============="
1538
1539 test_26a() {
1540         test_mkdir $DIR/d26
1541         test_mkdir $DIR/d26/d26-2
1542         ln -s d26/d26-2 $DIR/s26
1543         touch $DIR/s26/foo || error "File creation failed"
1544 }
1545 run_test 26a "multiple component symlink ======================="
1546
1547 test_26b() {
1548         test_mkdir -p $DIR/$tdir/d26-2
1549         ln -s $tdir/d26-2/foo $DIR/s26-2
1550         touch $DIR/s26-2 || error "File creation failed"
1551 }
1552 run_test 26b "multiple component symlink at end of lookup ======"
1553
1554 test_26c() {
1555         test_mkdir $DIR/d26.2
1556         touch $DIR/d26.2/foo
1557         ln -s d26.2 $DIR/s26.2-1
1558         ln -s s26.2-1 $DIR/s26.2-2
1559         ln -s s26.2-2 $DIR/s26.2-3
1560         chmod 0666 $DIR/s26.2-3/foo
1561 }
1562 run_test 26c "chain of symlinks"
1563
1564 # recursive symlinks (bug 439)
1565 test_26d() {
1566         ln -s d26-3/foo $DIR/d26-3
1567 }
1568 run_test 26d "create multiple component recursive symlink"
1569
1570 test_26e() {
1571         [ ! -h $DIR/d26-3 ] && test_26d
1572         rm $DIR/d26-3
1573 }
1574 run_test 26e "unlink multiple component recursive symlink"
1575
1576 # recursive symlinks (bug 7022)
1577 test_26f() {
1578         test_mkdir $DIR/$tdir
1579         test_mkdir $DIR/$tdir/$tfile
1580         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1581         test_mkdir -p lndir/bar1
1582         test_mkdir $DIR/$tdir/$tfile/$tfile
1583         cd $tfile                || error "cd $tfile failed"
1584         ln -s .. dotdot          || error "ln dotdot failed"
1585         ln -s dotdot/lndir lndir || error "ln lndir failed"
1586         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1587         output=`ls $tfile/$tfile/lndir/bar1`
1588         [ "$output" = bar1 ] && error "unexpected output"
1589         rm -r $tfile             || error "rm $tfile failed"
1590         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1591 }
1592 run_test 26f "rm -r of a directory which has recursive symlink"
1593
1594 test_27a() {
1595         test_mkdir $DIR/$tdir
1596         $LFS getstripe $DIR/$tdir
1597         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1598         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1599         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1600 }
1601 run_test 27a "one stripe file"
1602
1603 test_27b() {
1604         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1605
1606         test_mkdir $DIR/$tdir
1607         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1608         $LFS getstripe -c $DIR/$tdir/$tfile
1609         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1610                 error "two-stripe file doesn't have two stripes"
1611
1612         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1613 }
1614 run_test 27b "create and write to two stripe file"
1615
1616 # 27c family tests specific striping, setstripe -o
1617 test_27ca() {
1618         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1619         test_mkdir -p $DIR/$tdir
1620         local osts="1"
1621
1622         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1623         $LFS getstripe -i $DIR/$tdir/$tfile
1624         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1625                 error "stripe not on specified OST"
1626
1627         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1628 }
1629 run_test 27ca "one stripe on specified OST"
1630
1631 test_27cb() {
1632         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1633         test_mkdir -p $DIR/$tdir
1634         local osts="1,0"
1635         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1636         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1637         echo "$getstripe"
1638
1639         # Strip getstripe output to a space separated list of OSTs
1640         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1641                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1642         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1643                 error "stripes not on specified OSTs"
1644
1645         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1646 }
1647 run_test 27cb "two stripes on specified OSTs"
1648
1649 test_27cc() {
1650         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1651         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1652                 skip "server does not support overstriping"
1653
1654         test_mkdir -p $DIR/$tdir
1655         local osts="0,0"
1656         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1657         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1658         echo "$getstripe"
1659
1660         # Strip getstripe output to a space separated list of OSTs
1661         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1662                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1663         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1664                 error "stripes not on specified OSTs"
1665
1666         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1667 }
1668 run_test 27cc "two stripes on the same OST"
1669
1670 test_27cd() {
1671         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1672         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1673                 skip "server does not support overstriping"
1674         test_mkdir -p $DIR/$tdir
1675         local osts="0,1,1,0"
1676         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1677         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1678         echo "$getstripe"
1679
1680         # Strip getstripe output to a space separated list of OSTs
1681         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1682                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1683         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1684                 error "stripes not on specified OSTs"
1685
1686         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1687 }
1688 run_test 27cd "four stripes on two OSTs"
1689
1690 test_27ce() {
1691         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1692                 skip_env "too many osts, skipping"
1693         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1694                 skip "server does not support overstriping"
1695         # We do one more stripe than we have OSTs
1696         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1697                 skip_env "ea_inode feature disabled"
1698
1699         test_mkdir -p $DIR/$tdir
1700         local osts=""
1701         for i in $(seq 0 $OSTCOUNT);
1702         do
1703                 osts=$osts"0"
1704                 if [ $i -ne $OSTCOUNT ]; then
1705                         osts=$osts","
1706                 fi
1707         done
1708         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1709         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1710         echo "$getstripe"
1711
1712         # Strip getstripe output to a space separated list of OSTs
1713         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1714                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1715         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1716                 error "stripes not on specified OSTs"
1717
1718         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1719 }
1720 run_test 27ce "more stripes than OSTs with -o"
1721
1722 test_27cf() {
1723         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1724         local pid=0
1725
1726         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1727         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1728         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1729         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1730                 error "failed to set $osp_proc=0"
1731
1732         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1733         pid=$!
1734         sleep 1
1735         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1736         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1737                 error "failed to set $osp_proc=1"
1738         wait $pid
1739         [[ $pid -ne 0 ]] ||
1740                 error "should return error due to $osp_proc=0"
1741 }
1742 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1743
1744 test_27cg() {
1745         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1746                 skip "server does not support overstriping"
1747         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1748         large_xattr_enabled || skip_env "ea_inode feature disabled"
1749
1750         local osts="0"
1751
1752         for ((i=1;i<1000;i++)); do
1753                 osts+=",$((i % OSTCOUNT))"
1754         done
1755
1756         local mdts=$(comma_list $(mdts_nodes))
1757         local before=$(do_nodes $mdts \
1758                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1759                 awk '/many credits/{print $3}' |
1760                 calc_sum)
1761
1762         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1763         $LFS getstripe $DIR/$tfile | grep stripe
1764
1765         rm -f $DIR/$tfile || error "can't unlink"
1766
1767         after=$(do_nodes $mdts \
1768                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1769                 awk '/many credits/{print $3}' |
1770                 calc_sum)
1771
1772         (( before == after )) ||
1773                 error "too many credits happened: $after > $before"
1774 }
1775 run_test 27cg "1000 shouldn't cause too many credits"
1776
1777 test_27d() {
1778         test_mkdir $DIR/$tdir
1779         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1780                 error "setstripe failed"
1781         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1782         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1783 }
1784 run_test 27d "create file with default settings"
1785
1786 test_27e() {
1787         # LU-5839 adds check for existed layout before setting it
1788         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1789                 skip "Need MDS version at least 2.7.56"
1790
1791         test_mkdir $DIR/$tdir
1792         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1793         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1794         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1795 }
1796 run_test 27e "setstripe existing file (should return error)"
1797
1798 test_27f() {
1799         test_mkdir $DIR/$tdir
1800         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1801                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1802         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1803                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1804         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1805         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1806 }
1807 run_test 27f "setstripe with bad stripe size (should return error)"
1808
1809 test_27g() {
1810         test_mkdir $DIR/$tdir
1811         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1812         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1813                 error "$DIR/$tdir/$tfile has object"
1814 }
1815 run_test 27g "$LFS getstripe with no objects"
1816
1817 test_27ga() {
1818         test_mkdir $DIR/$tdir
1819         touch $DIR/$tdir/$tfile || error "touch failed"
1820         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1821         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1822         local rc=$?
1823         (( rc == 2 )) || error "getstripe did not return ENOENT"
1824
1825         local err_msg=$($LFS getstripe $DIR/$tdir/typo $DIR/$tdir/$tfile \
1826                         2>&1 > /dev/null)
1827         [[ $err_msg =~ "typo" ]] ||
1828                 error "expected message with correct filename, got '$err_msg'"
1829 }
1830 run_test 27ga "$LFS getstripe with missing file (should return error)"
1831
1832 test_27i() {
1833         test_mkdir $DIR/$tdir
1834         touch $DIR/$tdir/$tfile || error "touch failed"
1835         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1836                 error "missing objects"
1837 }
1838 run_test 27i "$LFS getstripe with some objects"
1839
1840 test_27j() {
1841         test_mkdir $DIR/$tdir
1842         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1843                 error "setstripe failed" || true
1844 }
1845 run_test 27j "setstripe with bad stripe offset (should return error)"
1846
1847 test_27k() { # bug 2844
1848         test_mkdir $DIR/$tdir
1849         local file=$DIR/$tdir/$tfile
1850         local ll_max_blksize=$((4 * 1024 * 1024))
1851         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1852         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1853         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1854         dd if=/dev/zero of=$file bs=4k count=1
1855         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1856         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1857 }
1858 run_test 27k "limit i_blksize for broken user apps"
1859
1860 test_27l() {
1861         mcreate $DIR/$tfile || error "creating file"
1862         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1863                 error "setstripe should have failed" || true
1864 }
1865 run_test 27l "check setstripe permissions (should return error)"
1866
1867 test_27m() {
1868         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1869
1870         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1871                 skip_env "multiple clients -- skipping"
1872
1873         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1874                    head -n1)
1875         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1876                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1877         fi
1878         stack_trap simple_cleanup_common
1879         test_mkdir $DIR/$tdir
1880         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1881         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1882                 error "dd should fill OST0"
1883         i=2
1884         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1885                 i=$((i + 1))
1886                 [ $i -gt 256 ] && break
1887         done
1888         i=$((i + 1))
1889         touch $DIR/$tdir/$tfile.$i
1890         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1891             awk '{print $1}'| grep -w "0") ] &&
1892                 error "OST0 was full but new created file still use it"
1893         i=$((i + 1))
1894         touch $DIR/$tdir/$tfile.$i
1895         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1896             awk '{print $1}'| grep -w "0") ] &&
1897                 error "OST0 was full but new created file still use it" || true
1898 }
1899 run_test 27m "create file while OST0 was full"
1900
1901 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1902 # if the OST isn't full anymore.
1903 reset_enospc() {
1904         local ostidx=${1:-""}
1905         local delay
1906         local ready
1907         local get_prealloc
1908
1909         local list=$(comma_list $(osts_nodes))
1910         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1911
1912         do_nodes $list lctl set_param fail_loc=0
1913         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1914         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1915                 awk '{print $1 * 2;exit;}')
1916         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1917                         grep -v \"^0$\""
1918         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1919 }
1920
1921 test_27n() {
1922         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1924         remote_mds_nodsh && skip "remote MDS with nodsh"
1925         remote_ost_nodsh && skip "remote OST with nodsh"
1926
1927         reset_enospc
1928         rm -f $DIR/$tdir/$tfile
1929         exhaust_precreations 0 0x80000215
1930         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1931         touch $DIR/$tdir/$tfile || error "touch failed"
1932         $LFS getstripe $DIR/$tdir/$tfile
1933         reset_enospc
1934 }
1935 run_test 27n "create file with some full OSTs"
1936
1937 test_27o() {
1938         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1940         remote_mds_nodsh && skip "remote MDS with nodsh"
1941         remote_ost_nodsh && skip "remote OST with nodsh"
1942
1943         reset_enospc
1944         rm -f $DIR/$tdir/$tfile
1945         exhaust_all_precreations 0x215
1946
1947         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1948
1949         reset_enospc
1950         rm -rf $DIR/$tdir/*
1951 }
1952 run_test 27o "create file with all full OSTs (should error)"
1953
1954 function create_and_checktime() {
1955         local fname=$1
1956         local loops=$2
1957         local i
1958
1959         for ((i=0; i < $loops; i++)); do
1960                 local start=$SECONDS
1961                 multiop $fname-$i Oc
1962                 ((SECONDS-start < TIMEOUT)) ||
1963                         error "creation took " $((SECONDS-$start)) && return 1
1964         done
1965 }
1966
1967 test_27oo() {
1968         local mdts=$(comma_list $(mdts_nodes))
1969
1970         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1971                 skip "Need MDS version at least 2.13.57"
1972
1973         local f0=$DIR/${tfile}-0
1974         local f1=$DIR/${tfile}-1
1975
1976         wait_delete_completed
1977
1978         # refill precreated objects
1979         $LFS setstripe -i0 -c1 $f0
1980
1981         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1982         # force QoS allocation policy
1983         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1984         stack_trap "do_nodes $mdts $LCTL set_param \
1985                 lov.*.qos_threshold_rr=$saved" EXIT
1986         sleep_maxage
1987
1988         # one OST is unavailable, but still have few objects preallocated
1989         stop ost1
1990         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1991                 rm -rf $f1 $DIR/$tdir*" EXIT
1992
1993         for ((i=0; i < 7; i++)); do
1994                 mkdir $DIR/$tdir$i || error "can't create dir"
1995                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1996                         error "can't set striping"
1997         done
1998         for ((i=0; i < 7; i++)); do
1999                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
2000         done
2001         wait
2002 }
2003 run_test 27oo "don't let few threads to reserve too many objects"
2004
2005 test_27p() {
2006         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2008         remote_mds_nodsh && skip "remote MDS with nodsh"
2009         remote_ost_nodsh && skip "remote OST with nodsh"
2010
2011         reset_enospc
2012         rm -f $DIR/$tdir/$tfile
2013         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
2014
2015         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
2016         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
2017         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2018
2019         exhaust_precreations 0 0x80000215
2020         echo foo >> $DIR/$tdir/$tfile || error "append failed"
2021         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2022         $LFS getstripe $DIR/$tdir/$tfile
2023
2024         reset_enospc
2025 }
2026 run_test 27p "append to a truncated file with some full OSTs"
2027
2028 test_27q() {
2029         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2030         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2031         remote_mds_nodsh && skip "remote MDS with nodsh"
2032         remote_ost_nodsh && skip "remote OST with nodsh"
2033
2034         reset_enospc
2035         rm -f $DIR/$tdir/$tfile
2036
2037         mkdir_on_mdt0 $DIR/$tdir
2038         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2039         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2040                 error "truncate $DIR/$tdir/$tfile failed"
2041         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2042
2043         exhaust_all_precreations 0x215
2044
2045         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2046         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2047
2048         reset_enospc
2049 }
2050 run_test 27q "append to truncated file with all OSTs full (should error)"
2051
2052 test_27r() {
2053         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2055         remote_mds_nodsh && skip "remote MDS with nodsh"
2056         remote_ost_nodsh && skip "remote OST with nodsh"
2057
2058         reset_enospc
2059         rm -f $DIR/$tdir/$tfile
2060         exhaust_precreations 0 0x80000215
2061
2062         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2063
2064         reset_enospc
2065 }
2066 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2067
2068 test_27s() { # bug 10725
2069         test_mkdir $DIR/$tdir
2070         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2071         local stripe_count=0
2072         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2073         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2074                 error "stripe width >= 2^32 succeeded" || true
2075
2076 }
2077 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2078
2079 test_27t() { # bug 10864
2080         WDIR=$(pwd)
2081         WLFS=$(which lfs)
2082         cd $DIR
2083         touch $tfile
2084         $WLFS getstripe $tfile
2085         cd $WDIR
2086 }
2087 run_test 27t "check that utils parse path correctly"
2088
2089 test_27u() { # bug 4900
2090         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2091         remote_mds_nodsh && skip "remote MDS with nodsh"
2092
2093         local index
2094         local list=$(comma_list $(mdts_nodes))
2095
2096 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2097         do_nodes $list $LCTL set_param fail_loc=0x139
2098         test_mkdir -p $DIR/$tdir
2099         stack_trap "simple_cleanup_common 1000"
2100         createmany -o $DIR/$tdir/$tfile 1000
2101         do_nodes $list $LCTL set_param fail_loc=0
2102
2103         TLOG=$TMP/$tfile.getstripe
2104         $LFS getstripe $DIR/$tdir > $TLOG
2105         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2106         [[ $OBJS -gt 0 ]] &&
2107                 error "$OBJS objects created on OST-0. See $TLOG" ||
2108                 rm -f $TLOG
2109 }
2110 run_test 27u "skip object creation on OSC w/o objects"
2111
2112 test_27v() { # bug 4900
2113         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2115         remote_mds_nodsh && skip "remote MDS with nodsh"
2116         remote_ost_nodsh && skip "remote OST with nodsh"
2117
2118         exhaust_all_precreations 0x215
2119         reset_enospc
2120
2121         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2122
2123         touch $DIR/$tdir/$tfile
2124         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2125         # all except ost1
2126         for (( i=1; i < OSTCOUNT; i++ )); do
2127                 do_facet ost$i lctl set_param fail_loc=0x705
2128         done
2129         local START=`date +%s`
2130         createmany -o $DIR/$tdir/$tfile 32
2131
2132         local FINISH=`date +%s`
2133         local TIMEOUT=`lctl get_param -n timeout`
2134         local PROCESS=$((FINISH - START))
2135         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2136                error "$FINISH - $START >= $TIMEOUT / 2"
2137         sleep $((TIMEOUT / 2 - PROCESS))
2138         reset_enospc
2139 }
2140 run_test 27v "skip object creation on slow OST"
2141
2142 test_27w() { # bug 10997
2143         test_mkdir $DIR/$tdir
2144         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2145         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2146                 error "stripe size $size != 65536" || true
2147         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2148                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2149 }
2150 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2151
2152 test_27wa() {
2153         [[ $OSTCOUNT -lt 2 ]] &&
2154                 skip_env "skipping multiple stripe count/offset test"
2155
2156         test_mkdir $DIR/$tdir
2157         for i in $(seq 1 $OSTCOUNT); do
2158                 offset=$((i - 1))
2159                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2160                         error "setstripe -c $i -i $offset failed"
2161                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2162                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2163                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2164                 [ $index -ne $offset ] &&
2165                         error "stripe offset $index != $offset" || true
2166         done
2167 }
2168 run_test 27wa "check $LFS setstripe -c -i options"
2169
2170 test_27x() {
2171         remote_ost_nodsh && skip "remote OST with nodsh"
2172         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2174
2175         OFFSET=$(($OSTCOUNT - 1))
2176         OSTIDX=0
2177         local OST=$(ostname_from_index $OSTIDX)
2178
2179         test_mkdir $DIR/$tdir
2180         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2181         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2182         sleep_maxage
2183         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2184         for i in $(seq 0 $OFFSET); do
2185                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2186                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2187                 error "OST0 was degraded but new created file still use it"
2188         done
2189         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2190 }
2191 run_test 27x "create files while OST0 is degraded"
2192
2193 test_27y() {
2194         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2195         remote_mds_nodsh && skip "remote MDS with nodsh"
2196         remote_ost_nodsh && skip "remote OST with nodsh"
2197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2198
2199         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2200         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2201                 osp.$mdtosc.prealloc_last_id)
2202         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2203                 osp.$mdtosc.prealloc_next_id)
2204         local fcount=$((last_id - next_id))
2205         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2206         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2207
2208         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2209                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2210         local OST_DEACTIVE_IDX=-1
2211         local OSC
2212         local OSTIDX
2213         local OST
2214
2215         for OSC in $MDS_OSCS; do
2216                 OST=$(osc_to_ost $OSC)
2217                 OSTIDX=$(index_from_ostuuid $OST)
2218                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2219                         OST_DEACTIVE_IDX=$OSTIDX
2220                 fi
2221                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2222                         echo $OSC "is Deactivated:"
2223                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2224                 fi
2225         done
2226
2227         OSTIDX=$(index_from_ostuuid $OST)
2228         test_mkdir $DIR/$tdir
2229         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2230
2231         for OSC in $MDS_OSCS; do
2232                 OST=$(osc_to_ost $OSC)
2233                 OSTIDX=$(index_from_ostuuid $OST)
2234                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2235                         echo $OST "is degraded:"
2236                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2237                                                 obdfilter.$OST.degraded=1
2238                 fi
2239         done
2240
2241         sleep_maxage
2242         createmany -o $DIR/$tdir/$tfile $fcount
2243
2244         for OSC in $MDS_OSCS; do
2245                 OST=$(osc_to_ost $OSC)
2246                 OSTIDX=$(index_from_ostuuid $OST)
2247                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2248                         echo $OST "is recovered from degraded:"
2249                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2250                                                 obdfilter.$OST.degraded=0
2251                 else
2252                         do_facet $SINGLEMDS lctl --device %$OSC activate
2253                 fi
2254         done
2255
2256         # all osp devices get activated, hence -1 stripe count restored
2257         local stripe_count=0
2258
2259         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2260         # devices get activated.
2261         sleep_maxage
2262         $LFS setstripe -c -1 $DIR/$tfile
2263         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2264         rm -f $DIR/$tfile
2265         [ $stripe_count -ne $OSTCOUNT ] &&
2266                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2267         return 0
2268 }
2269 run_test 27y "create files while OST0 is degraded and the rest inactive"
2270
2271 check_seq_oid()
2272 {
2273         log "check file $1"
2274
2275         lmm_count=$($LFS getstripe -c $1)
2276         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2277         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2278
2279         local old_ifs="$IFS"
2280         IFS=$'[:]'
2281         fid=($($LFS path2fid $1))
2282         IFS="$old_ifs"
2283
2284         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2285         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2286
2287         # compare lmm_seq and lu_fid->f_seq
2288         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2289         # compare lmm_object_id and lu_fid->oid
2290         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2291
2292         # check the trusted.fid attribute of the OST objects of the file
2293         local have_obdidx=false
2294         local stripe_nr=0
2295         $LFS getstripe $1 | while read obdidx oid hex seq; do
2296                 # skip lines up to and including "obdidx"
2297                 [ -z "$obdidx" ] && break
2298                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2299                 $have_obdidx || continue
2300
2301                 local ost=$((obdidx + 1))
2302                 local dev=$(ostdevname $ost)
2303                 local oid_hex
2304
2305                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2306
2307                 seq=$(echo $seq | sed -e "s/^0x//g")
2308                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2309                         oid_hex=$(echo $oid)
2310                 else
2311                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2312                 fi
2313                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2314
2315                 local ff=""
2316                 #
2317                 # Don't unmount/remount the OSTs if we don't need to do that.
2318                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2319                 # update too, until that use mount/ll_decode_filter_fid/mount.
2320                 # Re-enable when debugfs will understand new filter_fid.
2321                 #
2322                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2323                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2324                                 $dev 2>/dev/null" | grep "parent=")
2325                 fi
2326                 if [ -z "$ff" ]; then
2327                         stop ost$ost
2328                         mount_fstype ost$ost
2329                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2330                                 $(facet_mntpt ost$ost)/$obj_file)
2331                         unmount_fstype ost$ost
2332                         start ost$ost $dev $OST_MOUNT_OPTS
2333                         clients_up
2334                 fi
2335
2336                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2337
2338                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2339
2340                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2341                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2342                 #
2343                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2344                 #       stripe_size=1048576 component_id=1 component_start=0 \
2345                 #       component_end=33554432
2346                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2347                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2348                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2349                 local ff_pstripe
2350                 if grep -q 'stripe=' <<<$ff; then
2351                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2352                 else
2353                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2354                         # into f_ver in this case.  See comment on ff_parent.
2355                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2356                 fi
2357
2358                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2359                 [ $ff_pseq = $lmm_seq ] ||
2360                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2361                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2362                 [ $ff_poid = $lmm_oid ] ||
2363                         error "FF parent OID $ff_poid != $lmm_oid"
2364                 (($ff_pstripe == $stripe_nr)) ||
2365                         error "FF stripe $ff_pstripe != $stripe_nr"
2366
2367                 stripe_nr=$((stripe_nr + 1))
2368                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2369                         continue
2370                 if grep -q 'stripe_count=' <<<$ff; then
2371                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2372                                             -e 's/ .*//' <<<$ff)
2373                         [ $lmm_count = $ff_scnt ] ||
2374                                 error "FF stripe count $lmm_count != $ff_scnt"
2375                 fi
2376         done
2377 }
2378
2379 test_27z() {
2380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2381         remote_ost_nodsh && skip "remote OST with nodsh"
2382
2383         test_mkdir $DIR/$tdir
2384         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2385                 { error "setstripe -c -1 failed"; return 1; }
2386         # We need to send a write to every object to get parent FID info set.
2387         # This _should_ also work for setattr, but does not currently.
2388         # touch $DIR/$tdir/$tfile-1 ||
2389         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2390                 { error "dd $tfile-1 failed"; return 2; }
2391         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2392                 { error "setstripe -c -1 failed"; return 3; }
2393         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2394                 { error "dd $tfile-2 failed"; return 4; }
2395
2396         # make sure write RPCs have been sent to OSTs
2397         sync; sleep 5; sync
2398
2399         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2400         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2401 }
2402 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2403
2404 test_27A() { # b=19102
2405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2406
2407         save_layout_restore_at_exit $MOUNT
2408         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2409         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2410                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2411         local default_size=$($LFS getstripe -S $MOUNT)
2412         local default_offset=$($LFS getstripe -i $MOUNT)
2413         local dsize=$(do_facet $SINGLEMDS \
2414                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2415         [ $default_size -eq $dsize ] ||
2416                 error "stripe size $default_size != $dsize"
2417         [ $default_offset -eq -1 ] ||
2418                 error "stripe offset $default_offset != -1"
2419 }
2420 run_test 27A "check filesystem-wide default LOV EA values"
2421
2422 test_27B() { # LU-2523
2423         test_mkdir $DIR/$tdir
2424         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2425         touch $DIR/$tdir/f0
2426         # open f1 with O_LOV_DELAY_CREATE
2427         # rename f0 onto f1
2428         # call setstripe ioctl on open file descriptor for f1
2429         # close
2430         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2431                 $DIR/$tdir/f0
2432
2433         rm -f $DIR/$tdir/f1
2434         # open f1 with O_LOV_DELAY_CREATE
2435         # unlink f1
2436         # call setstripe ioctl on open file descriptor for f1
2437         # close
2438         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2439
2440         # Allow multiop to fail in imitation of NFS's busted semantics.
2441         true
2442 }
2443 run_test 27B "call setstripe on open unlinked file/rename victim"
2444
2445 # 27C family tests full striping and overstriping
2446 test_27Ca() { #LU-2871
2447         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2448
2449         declare -a ost_idx
2450         local index
2451         local found
2452         local i
2453         local j
2454
2455         test_mkdir $DIR/$tdir
2456         cd $DIR/$tdir
2457         for i in $(seq 0 $((OSTCOUNT - 1))); do
2458                 # set stripe across all OSTs starting from OST$i
2459                 $LFS setstripe -i $i -c -1 $tfile$i
2460                 # get striping information
2461                 ost_idx=($($LFS getstripe $tfile$i |
2462                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2463                 echo "OST Index: ${ost_idx[*]}"
2464
2465                 # check the layout
2466                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2467                         error "${#ost_idx[@]} != $OSTCOUNT"
2468
2469                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2470                         found=0
2471                         for j in "${ost_idx[@]}"; do
2472                                 if [ $index -eq $j ]; then
2473                                         found=1
2474                                         break
2475                                 fi
2476                         done
2477                         [ $found = 1 ] ||
2478                                 error "Can not find $index in ${ost_idx[*]}"
2479                 done
2480         done
2481 }
2482 run_test 27Ca "check full striping across all OSTs"
2483
2484 test_27Cb() {
2485         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2486                 skip "server does not support overstriping"
2487         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2488                 skip_env "too many osts, skipping"
2489
2490         test_mkdir -p $DIR/$tdir
2491         local setcount=$(($OSTCOUNT * 2))
2492         [ $setcount -lt 160 ] || large_xattr_enabled ||
2493                 skip_env "ea_inode feature disabled"
2494
2495         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2496                 error "setstripe failed"
2497
2498         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2499         [ $count -eq $setcount ] ||
2500                 error "stripe count $count, should be $setcount"
2501
2502         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2503                 error "overstriped should be set in pattern"
2504
2505         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2506                 error "dd failed"
2507 }
2508 run_test 27Cb "more stripes than OSTs with -C"
2509
2510 test_27Cc() {
2511         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2512                 skip "server does not support overstriping"
2513         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2514
2515         test_mkdir -p $DIR/$tdir
2516         local setcount=$(($OSTCOUNT - 1))
2517
2518         [ $setcount -lt 160 ] || large_xattr_enabled ||
2519                 skip_env "ea_inode feature disabled"
2520
2521         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2522                 error "setstripe failed"
2523
2524         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2525         [ $count -eq $setcount ] ||
2526                 error "stripe count $count, should be $setcount"
2527
2528         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2529                 error "overstriped should not be set in pattern"
2530
2531         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2532                 error "dd failed"
2533 }
2534 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2535
2536 test_27Cd() {
2537         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2538                 skip "server does not support overstriping"
2539         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2540         large_xattr_enabled || skip_env "ea_inode feature disabled"
2541
2542         force_new_seq_all
2543
2544         test_mkdir -p $DIR/$tdir
2545         local setcount=$LOV_MAX_STRIPE_COUNT
2546
2547         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2548                 error "setstripe failed"
2549
2550         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2551         [ $count -eq $setcount ] ||
2552                 error "stripe count $count, should be $setcount"
2553
2554         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2555                 error "overstriped should be set in pattern"
2556
2557         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2558                 error "dd failed"
2559
2560         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2561 }
2562 run_test 27Cd "test maximum stripe count"
2563
2564 test_27Ce() {
2565         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2566                 skip "server does not support overstriping"
2567         test_mkdir -p $DIR/$tdir
2568
2569         pool_add $TESTNAME || error "Pool creation failed"
2570         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2571
2572         local setcount=8
2573
2574         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2575                 error "setstripe failed"
2576
2577         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2578         [ $count -eq $setcount ] ||
2579                 error "stripe count $count, should be $setcount"
2580
2581         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2582                 error "overstriped should be set in pattern"
2583
2584         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2585                 error "dd failed"
2586
2587         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2588 }
2589 run_test 27Ce "test pool with overstriping"
2590
2591 test_27Cf() {
2592         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2593                 skip "server does not support overstriping"
2594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2595                 skip_env "too many osts, skipping"
2596
2597         test_mkdir -p $DIR/$tdir
2598
2599         local setcount=$(($OSTCOUNT * 2))
2600         [ $setcount -lt 160 ] || large_xattr_enabled ||
2601                 skip_env "ea_inode feature disabled"
2602
2603         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2604                 error "setstripe failed"
2605
2606         echo 1 > $DIR/$tdir/$tfile
2607
2608         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2609         [ $count -eq $setcount ] ||
2610                 error "stripe count $count, should be $setcount"
2611
2612         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2613                 error "overstriped should be set in pattern"
2614
2615         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2616                 error "dd failed"
2617
2618         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2619 }
2620 run_test 27Cf "test default inheritance with overstriping"
2621
2622 test_27Cg() {
2623         (( MDS1_VERSION >= $(version_code v2_15_55-80-gd96b98ee6b) )) ||
2624                 skip "need MDS version at least v2_15_55-80-gd96b98ee6b for fix"
2625
2626         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2627         (( $? != 0 )) || error "must be an error for not existent OST#"
2628 }
2629 run_test 27Cg "test setstripe with wrong OST idx"
2630
2631 test_27Ci() {
2632         local tf=$DIR/$tfile
2633
2634         stack_trap "rm -f $DIR/$tfile"
2635
2636         $LFS setstripe -E1M $tf || error "create $tf failed"
2637         $LFS setstripe -Eeof --component-add -C 100 $tf ||
2638                 error "add component failed"
2639
2640         $LFS getstripe -I2 $tf | awk '/lmm_pattern/ { print $2 }' |
2641                 grep "overstriped" || {
2642                 $LFS getstripe $tf
2643                 echo "lose overstriping setting"
2644         }
2645         sc=$($LFS getstripe -I2 --stripe-count $tf)
2646         (( $sc == 100 )) || {
2647                 $LFS getstripe $tf
2648                 echo "lose overstriping setting"
2649         }
2650
2651         stack_trap "rm -f $tf"
2652         dd if=/dev/zero of=$tf bs=1M count=10 || error "write $tf"
2653         sc=$($LFS getstripe -I2 --stripe-count $tf)
2654         (( $sc == 100 )) || {
2655                 $LFS getstripe $tf
2656                 echo "lose overstriping setting after instantiation"
2657         }
2658 }
2659 run_test 27Ci "add an overstriping component"
2660
2661 test_27D() {
2662         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2663         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2664         remote_mds_nodsh && skip "remote MDS with nodsh"
2665
2666         local POOL=${POOL:-testpool}
2667         local first_ost=0
2668         local last_ost=$(($OSTCOUNT - 1))
2669         local ost_step=1
2670         local ost_list=$(seq $first_ost $ost_step $last_ost)
2671         local ost_range="$first_ost $last_ost $ost_step"
2672
2673         test_mkdir $DIR/$tdir
2674         pool_add $POOL || error "pool_add failed"
2675         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2676
2677         local skip27D
2678         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2679                 skip27D+="-s 29"
2680         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2681                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2682                         skip27D+=" -s 30,31"
2683         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2684           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2685                 skip27D+=" -s 32,33"
2686         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2687                 skip27D+=" -s 34"
2688         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2689                 error "llapi_layout_test failed"
2690
2691         destroy_test_pools || error "destroy test pools failed"
2692 }
2693 run_test 27D "validate llapi_layout API"
2694
2695 # Verify that default_easize is increased from its initial value after
2696 # accessing a widely striped file.
2697 test_27E() {
2698         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2699         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2700                 skip "client does not have LU-3338 fix"
2701
2702         # 72 bytes is the minimum space required to store striping
2703         # information for a file striped across one OST:
2704         # (sizeof(struct lov_user_md_v3) +
2705         #  sizeof(struct lov_user_ost_data_v1))
2706         local min_easize=72
2707         $LCTL set_param -n llite.*.default_easize $min_easize ||
2708                 error "lctl set_param failed"
2709         local easize=$($LCTL get_param -n llite.*.default_easize)
2710
2711         [ $easize -eq $min_easize ] ||
2712                 error "failed to set default_easize"
2713
2714         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2715                 error "setstripe failed"
2716         # In order to ensure stat() call actually talks to MDS we need to
2717         # do something drastic to this file to shake off all lock, e.g.
2718         # rename it (kills lookup lock forcing cache cleaning)
2719         mv $DIR/$tfile $DIR/${tfile}-1
2720         ls -l $DIR/${tfile}-1
2721         rm $DIR/${tfile}-1
2722
2723         easize=$($LCTL get_param -n llite.*.default_easize)
2724
2725         [ $easize -gt $min_easize ] ||
2726                 error "default_easize not updated"
2727 }
2728 run_test 27E "check that default extended attribute size properly increases"
2729
2730 test_27F() { # LU-5346/LU-7975
2731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2732         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2733         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2734                 skip "Need MDS version at least 2.8.51"
2735         remote_ost_nodsh && skip "remote OST with nodsh"
2736
2737         test_mkdir $DIR/$tdir
2738         rm -f $DIR/$tdir/f0
2739         $LFS setstripe -c 2 $DIR/$tdir
2740
2741         # stop all OSTs to reproduce situation for LU-7975 ticket
2742         for num in $(seq $OSTCOUNT); do
2743                 stop ost$num
2744         done
2745
2746         # open/create f0 with O_LOV_DELAY_CREATE
2747         # truncate f0 to a non-0 size
2748         # close
2749         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2750
2751         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2752         # open/write it again to force delayed layout creation
2753         cat /etc/hosts > $DIR/$tdir/f0 &
2754         catpid=$!
2755
2756         # restart OSTs
2757         for num in $(seq $OSTCOUNT); do
2758                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2759                         error "ost$num failed to start"
2760         done
2761
2762         wait $catpid || error "cat failed"
2763
2764         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2765         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2766                 error "wrong stripecount"
2767
2768 }
2769 run_test 27F "Client resend delayed layout creation with non-zero size"
2770
2771 test_27G() { #LU-10629
2772         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2773                 skip "Need MDS version at least 2.11.51"
2774         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2775         remote_mds_nodsh && skip "remote MDS with nodsh"
2776         local POOL=${POOL:-testpool}
2777         local ostrange="0 0 1"
2778
2779         test_mkdir $DIR/$tdir
2780         touch $DIR/$tdir/$tfile.nopool
2781         pool_add $POOL || error "pool_add failed"
2782         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2783         $LFS setstripe -p $POOL $DIR/$tdir
2784
2785         local pool=$($LFS getstripe -p $DIR/$tdir)
2786
2787         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2788         touch $DIR/$tdir/$tfile.default
2789         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2790         $LFS find $DIR/$tdir -type f --pool $POOL
2791         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2792         [[ "$found" == "2" ]] ||
2793                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2794
2795         $LFS setstripe -d $DIR/$tdir
2796
2797         pool=$($LFS getstripe -p -d $DIR/$tdir)
2798
2799         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2800 }
2801 run_test 27G "Clear OST pool from stripe"
2802
2803 test_27H() {
2804         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2805                 skip "Need MDS version newer than 2.11.54"
2806         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2807         test_mkdir $DIR/$tdir
2808         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2809         touch $DIR/$tdir/$tfile
2810         $LFS getstripe -c $DIR/$tdir/$tfile
2811         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2812                 error "two-stripe file doesn't have two stripes"
2813
2814         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2815         $LFS getstripe -y $DIR/$tdir/$tfile
2816         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2817              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2818                 error "expected l_ost_idx: [02]$ not matched"
2819
2820         # make sure ost list has been cleared
2821         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2822         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2823                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2824         touch $DIR/$tdir/f3
2825         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2826 }
2827 run_test 27H "Set specific OSTs stripe"
2828
2829 test_27I() {
2830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2831         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2832         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2833                 skip "Need MDS version newer than 2.12.52"
2834         local pool=$TESTNAME
2835         local ostrange="1 1 1"
2836
2837         save_layout_restore_at_exit $MOUNT
2838         $LFS setstripe -c 2 -i 0 $MOUNT
2839         pool_add $pool || error "pool_add failed"
2840         pool_add_targets $pool $ostrange ||
2841                 error "pool_add_targets failed"
2842         test_mkdir $DIR/$tdir
2843         $LFS setstripe -p $pool $DIR/$tdir
2844         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2845         $LFS getstripe $DIR/$tdir/$tfile
2846 }
2847 run_test 27I "check that root dir striping does not break parent dir one"
2848
2849 test_27J() {
2850         (( $MDS1_VERSION > $(version_code 2.12.51) )) ||
2851                 skip "Need MDS version newer than 2.12.51"
2852
2853         # skip basic ops on file with foreign LOV tests on 5.12-6.2 kernels
2854         # until the filemap_read() issue is fixed by v6.2-rc4-61-g5956592ce337
2855         (( $LINUX_VERSION_CODE < $(version_code 5.12.0) ||
2856            $LINUX_VERSION_CODE >= $(version_code 6.2.0) )) ||
2857                 skip "Need kernel < 5.12.0 or >= 6.2.0 for filemap_read() fix"
2858
2859         test_mkdir $DIR/$tdir
2860         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2861         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2862
2863         # create foreign file (raw way)
2864         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2865                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2866
2867         ! $LFS setstripe --foreign --flags foo \
2868                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2869                         error "creating $tfile with '--flags foo' should fail"
2870
2871         ! $LFS setstripe --foreign --flags 0xffffffff \
2872                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2873                         error "creating $tfile w/ 0xffffffff flags should fail"
2874
2875         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2876                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2877
2878         # verify foreign file (raw way)
2879         parse_foreign_file -f $DIR/$tdir/$tfile |
2880                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2881                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2882         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2883                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2884         parse_foreign_file -f $DIR/$tdir/$tfile |
2885                 grep "lov_foreign_size: 73" ||
2886                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2887         parse_foreign_file -f $DIR/$tdir/$tfile |
2888                 grep "lov_foreign_type: 1" ||
2889                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2890         parse_foreign_file -f $DIR/$tdir/$tfile |
2891                 grep "lov_foreign_flags: 0x0000DA08" ||
2892                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2893         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2894                 grep "lov_foreign_value: 0x" |
2895                 sed -e 's/lov_foreign_value: 0x//')
2896         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2897         [[ $lov = ${lov2// /} ]] ||
2898                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2899
2900         # create foreign file (lfs + API)
2901         $LFS setstripe --foreign=none --flags 0xda08 \
2902                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2903                 error "$DIR/$tdir/${tfile}2: create failed"
2904
2905         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2906                 grep "lfm_magic:.*0x0BD70BD0" ||
2907                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2908         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2909         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2910                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2911         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2912                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2913         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2914                 grep "lfm_flags:.*0x0000DA08" ||
2915                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2916         $LFS getstripe $DIR/$tdir/${tfile}2 |
2917                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2918                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2919
2920         # modify striping should fail
2921         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2922                 error "$DIR/$tdir/$tfile: setstripe should fail"
2923         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2924                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2925
2926         # R/W should fail
2927         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2928         cat $DIR/$tdir/${tfile}2 &&
2929                 error "$DIR/$tdir/${tfile}2: read should fail"
2930         cat /etc/passwd > $DIR/$tdir/$tfile &&
2931                 error "$DIR/$tdir/$tfile: write should fail"
2932         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2933                 error "$DIR/$tdir/${tfile}2: write should fail"
2934
2935         # chmod should work
2936         chmod 222 $DIR/$tdir/$tfile ||
2937                 error "$DIR/$tdir/$tfile: chmod failed"
2938         chmod 222 $DIR/$tdir/${tfile}2 ||
2939                 error "$DIR/$tdir/${tfile}2: chmod failed"
2940
2941         # chown should work
2942         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2943                 error "$DIR/$tdir/$tfile: chown failed"
2944         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2945                 error "$DIR/$tdir/${tfile}2: chown failed"
2946
2947         # rename should work
2948         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2949                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2950         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2951                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2952
2953         #remove foreign file
2954         rm $DIR/$tdir/${tfile}.new ||
2955                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2956         rm $DIR/$tdir/${tfile}2.new ||
2957                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2958 }
2959 run_test 27J "basic ops on file with foreign LOV"
2960
2961 test_27K() {
2962         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2963                 skip "Need MDS version newer than 2.12.49"
2964
2965         test_mkdir $DIR/$tdir
2966         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2967         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2968
2969         # create foreign dir (raw way)
2970         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2971                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2972
2973         ! $LFS setdirstripe --foreign --flags foo \
2974                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2975                         error "creating $tdir with '--flags foo' should fail"
2976
2977         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2978                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2979                         error "creating $tdir w/ 0xffffffff flags should fail"
2980
2981         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2982                 error "create_foreign_dir FAILED"
2983
2984         # verify foreign dir (raw way)
2985         parse_foreign_dir -d $DIR/$tdir/$tdir |
2986                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2987                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2988         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2989                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2990         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2991                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2992         parse_foreign_dir -d $DIR/$tdir/$tdir |
2993                 grep "lmv_foreign_flags: 55813$" ||
2994                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2995         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2996                 grep "lmv_foreign_value: 0x" |
2997                 sed 's/lmv_foreign_value: 0x//')
2998         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2999                 sed 's/ //g')
3000         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
3001
3002         # create foreign dir (lfs + API)
3003         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
3004                 $DIR/$tdir/${tdir}2 ||
3005                 error "$DIR/$tdir/${tdir}2: create failed"
3006
3007         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
3008
3009         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3010                 grep "lfm_magic:.*0x0CD50CD0" ||
3011                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
3012         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
3013         # - sizeof(lfm_type) - sizeof(lfm_flags)
3014         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
3015                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
3016         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
3017                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
3018         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
3019                 grep "lfm_flags:.*0x0000DA05" ||
3020                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
3021         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
3022                 grep "lfm_value.*${uuid1}@${uuid2}" ||
3023                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
3024
3025         # file create in dir should fail
3026         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3027         touch $DIR/$tdir/${tdir}2/$tfile &&
3028                 error "$DIR/${tdir}2: file create should fail"
3029
3030         # chmod should work
3031         chmod 777 $DIR/$tdir/$tdir ||
3032                 error "$DIR/$tdir: chmod failed"
3033         chmod 777 $DIR/$tdir/${tdir}2 ||
3034                 error "$DIR/${tdir}2: chmod failed"
3035
3036         # chown should work
3037         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
3038                 error "$DIR/$tdir: chown failed"
3039         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
3040                 error "$DIR/${tdir}2: chown failed"
3041
3042         # rename should work
3043         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3044                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
3045         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
3046                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
3047
3048         #remove foreign dir
3049         rmdir $DIR/$tdir/${tdir}.new ||
3050                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
3051         rmdir $DIR/$tdir/${tdir}2.new ||
3052                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
3053 }
3054 run_test 27K "basic ops on dir with foreign LMV"
3055
3056 test_27L() {
3057         remote_mds_nodsh && skip "remote MDS with nodsh"
3058
3059         local POOL=${POOL:-$TESTNAME}
3060
3061         pool_add $POOL || error "pool_add failed"
3062
3063         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3064                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3065                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3066 }
3067 run_test 27L "lfs pool_list gives correct pool name"
3068
3069 test_27M() {
3070         (( $MDS1_VERSION >= $(version_code 2.12.57) )) ||
3071                 skip "Need MDS version >= than 2.12.57"
3072         remote_mds_nodsh && skip "remote MDS with nodsh"
3073         (( $OSTCOUNT > 1 )) || skip "need > 1 OST"
3074
3075         # Set default striping on directory
3076         local setcount=4
3077         local stripe_opt
3078         local mdts=$(comma_list $(mdts_nodes))
3079
3080         # if we run against a 2.12 server which lacks overstring support
3081         # then the connect_flag will not report overstriping, even if client
3082         # is 2.14+
3083         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3084                 stripe_opt="-C $setcount"
3085         elif (( $OSTCOUNT >= $setcount )); then
3086                 stripe_opt="-c $setcount"
3087         else
3088                 skip "server does not support overstriping"
3089         fi
3090
3091         test_mkdir $DIR/$tdir
3092
3093         # Validate existing append_* params and ensure restore
3094         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3095         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3096         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3097
3098         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3099         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3100         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3101
3102         $LFS setstripe $stripe_opt $DIR/$tdir
3103
3104         echo 1 > $DIR/$tdir/${tfile}.1
3105         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3106         (( $count == $setcount )) ||
3107                 error "(1) stripe count $count, should be $setcount"
3108
3109         local appendcount=$orig_count
3110         echo 1 >> $DIR/$tdir/${tfile}.2_append
3111         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3112         (( $count == $appendcount )) ||
3113                 error "(2)stripe count $count, should be $appendcount for append"
3114
3115         # Disable O_APPEND striping, verify it works
3116         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3117
3118         # Should now get the default striping, which is 4
3119         setcount=4
3120         echo 1 >> $DIR/$tdir/${tfile}.3_append
3121         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3122         (( $count == $setcount )) ||
3123                 error "(3) stripe count $count, should be $setcount"
3124
3125         # Try changing the stripe count for append files
3126         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3127
3128         # Append striping is now 2 (directory default is still 4)
3129         appendcount=2
3130         echo 1 >> $DIR/$tdir/${tfile}.4_append
3131         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3132         (( $count == $appendcount )) ||
3133                 error "(4) stripe count $count, should be $appendcount for append"
3134
3135         # Test append stripe count of -1
3136         # Exercise LU-16872 patch with specific striping, only if MDS has fix
3137         (( $MDS1_VERSION > $(version_code 2.15.56.46) )) &&
3138                 $LFS setstripe -o 0,$((OSTCOUNT - 1)) $DIR/$tdir &&
3139                 touch $DIR/$tdir/$tfile.specific.{1..128}
3140         stack_trap "rm -f $DIR/$tdir/$tfile.*"
3141
3142         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3143         appendcount=$OSTCOUNT
3144         echo 1 >> $DIR/$tdir/${tfile}.5
3145         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3146         (( $count == $appendcount )) ||
3147                 error "(5) stripe count $count, should be $appendcount for append"
3148
3149         # Set append striping back to default of 1
3150         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3151
3152         # Try a new default striping, PFL + DOM
3153         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3154
3155         # Create normal DOM file, DOM returns stripe count == 0
3156         setcount=0
3157         touch $DIR/$tdir/${tfile}.6
3158         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3159         (( $count == $setcount )) ||
3160                 error "(6) stripe count $count, should be $setcount"
3161
3162         # Show
3163         appendcount=1
3164         echo 1 >> $DIR/$tdir/${tfile}.7_append
3165         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3166         (( $count == $appendcount )) ||
3167                 error "(7) stripe count $count, should be $appendcount for append"
3168
3169         # Clean up DOM layout
3170         $LFS setstripe -d $DIR/$tdir
3171
3172         save_layout_restore_at_exit $MOUNT
3173         # Now test that append striping works when layout is from root
3174         $LFS setstripe -c 2 $MOUNT
3175         # Make a special directory for this
3176         mkdir $DIR/${tdir}/${tdir}.2
3177
3178         # Verify for normal file
3179         setcount=2
3180         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3181         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3182         (( $count == $setcount )) ||
3183                 error "(8) stripe count $count, should be $setcount"
3184
3185         appendcount=1
3186         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3187         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3188         (( $count == $appendcount )) ||
3189                 error "(9) stripe count $count, should be $appendcount for append"
3190
3191         # Now test O_APPEND striping with pools
3192         pool_add $TESTNAME || error "pool creation failed"
3193         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3194         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3195
3196         echo 1 >> $DIR/$tdir/${tfile}.10_append
3197
3198         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3199         [[ "$pool" == "$TESTNAME" ]] || error "(10) incorrect pool: $pool"
3200
3201         # Check that count is still correct
3202         appendcount=1
3203         echo 1 >> $DIR/$tdir/${tfile}.11_append
3204         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3205         (( $count == $appendcount )) ||
3206                 error "(11) stripe count $count, should be $appendcount for append"
3207
3208         # Disable O_APPEND stripe count, verify pool works separately
3209         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3210
3211         echo 1 >> $DIR/$tdir/${tfile}.12_append
3212
3213         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3214         [[ "$pool" == "$TESTNAME" ]] || error "(12) incorrect pool: $pool"
3215
3216         # Remove pool setting, verify it's not applied
3217         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3218
3219         echo 1 >> $DIR/$tdir/${tfile}.13_append
3220
3221         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3222         [[ -z "$pool" ]] || error "(13) pool found: $pool"
3223 }
3224 run_test 27M "test O_APPEND striping"
3225
3226 test_27N() {
3227         combined_mgs_mds && skip "needs separate MGS/MDT"
3228
3229         pool_add $TESTNAME || error "pool_add failed"
3230         do_facet mgs "$LCTL pool_list $FSNAME" |
3231                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3232                 error "lctl pool_list on MGS failed"
3233 }
3234 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3235
3236 clean_foreign_symlink() {
3237         trap 0
3238         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3239         for i in $DIR/$tdir/* ; do
3240                 $LFS unlink_foreign $i || true
3241         done
3242 }
3243
3244 test_27O() {
3245         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3246                 skip "Need MDS version newer than 2.12.51"
3247
3248         test_mkdir $DIR/$tdir
3249         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3250         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3251
3252         trap clean_foreign_symlink EXIT
3253
3254         # enable foreign_symlink behaviour
3255         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3256
3257         # foreign symlink LOV format is a partial path by default
3258
3259         # create foreign file (lfs + API)
3260         $LFS setstripe --foreign=symlink --flags 0xda05 \
3261                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3262                 error "$DIR/$tdir/${tfile}: create failed"
3263
3264         $LFS getstripe -v $DIR/$tdir/${tfile} |
3265                 grep "lfm_magic:.*0x0BD70BD0" ||
3266                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3267         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3268                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3269         $LFS getstripe -v $DIR/$tdir/${tfile} |
3270                 grep "lfm_flags:.*0x0000DA05" ||
3271                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3272         $LFS getstripe $DIR/$tdir/${tfile} |
3273                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3274                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3275
3276         # modify striping should fail
3277         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3278                 error "$DIR/$tdir/$tfile: setstripe should fail"
3279
3280         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3281         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3282         cat /etc/passwd > $DIR/$tdir/$tfile &&
3283                 error "$DIR/$tdir/$tfile: write should fail"
3284
3285         # rename should succeed
3286         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3287                 error "$DIR/$tdir/$tfile: rename has failed"
3288
3289         #remove foreign_symlink file should fail
3290         rm $DIR/$tdir/${tfile}.new &&
3291                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3292
3293         #test fake symlink
3294         mkdir /tmp/${uuid1} ||
3295                 error "/tmp/${uuid1}: mkdir has failed"
3296         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3297                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3298         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3299         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3300                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3301         #read should succeed now
3302         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3303                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3304         #write should succeed now
3305         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3306                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3307         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3308                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3309         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3310                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3311
3312         #check that getstripe still works
3313         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3314                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3315
3316         # chmod should still succeed
3317         chmod 644 $DIR/$tdir/${tfile}.new ||
3318                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3319
3320         # chown should still succeed
3321         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3322                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3323
3324         # rename should still succeed
3325         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3326                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3327
3328         #remove foreign_symlink file should still fail
3329         rm $DIR/$tdir/${tfile} &&
3330                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3331
3332         #use special ioctl() to unlink foreign_symlink file
3333         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3334                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3335
3336 }
3337 run_test 27O "basic ops on foreign file of symlink type"
3338
3339 test_27P() {
3340         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3341                 skip "Need MDS version newer than 2.12.49"
3342
3343         test_mkdir $DIR/$tdir
3344         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3345         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3346
3347         trap clean_foreign_symlink EXIT
3348
3349         # enable foreign_symlink behaviour
3350         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3351
3352         # foreign symlink LMV format is a partial path by default
3353
3354         # create foreign dir (lfs + API)
3355         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3356                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3357                 error "$DIR/$tdir/${tdir}: create failed"
3358
3359         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3360
3361         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3362                 grep "lfm_magic:.*0x0CD50CD0" ||
3363                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3364         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3365                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3366         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3367                 grep "lfm_flags:.*0x0000DA05" ||
3368                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3369         $LFS getdirstripe $DIR/$tdir/${tdir} |
3370                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3371                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3372
3373         # file create in dir should fail
3374         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3375         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3376
3377         # rename should succeed
3378         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3379                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3380
3381         #remove foreign_symlink dir should fail
3382         rmdir $DIR/$tdir/${tdir}.new &&
3383                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3384
3385         #test fake symlink
3386         mkdir -p /tmp/${uuid1}/${uuid2} ||
3387                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3388         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3389                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3390         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3391         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3392                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3393         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3394                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3395
3396         #check that getstripe fails now that foreign_symlink enabled
3397         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3398                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3399
3400         # file create in dir should work now
3401         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3402                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3403         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3404                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3405         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3406                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3407
3408         # chmod should still succeed
3409         chmod 755 $DIR/$tdir/${tdir}.new ||
3410                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3411
3412         # chown should still succeed
3413         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3414                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3415
3416         # rename should still succeed
3417         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3418                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3419
3420         #remove foreign_symlink dir should still fail
3421         rmdir $DIR/$tdir/${tdir} &&
3422                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3423
3424         #use special ioctl() to unlink foreign_symlink file
3425         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3426                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3427
3428         #created file should still exist
3429         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3430                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3431         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3432                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3433 }
3434 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3435
3436 test_27Q() {
3437         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3438         stack_trap "rm -f $TMP/$tfile*"
3439
3440         test_mkdir $DIR/$tdir-1
3441         test_mkdir $DIR/$tdir-2
3442
3443         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3444         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3445
3446         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3447         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3448
3449         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3450         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3451
3452         # Create some bad symlinks and ensure that we don't loop
3453         # forever or something. These should return ELOOP (40) and
3454         # ENOENT (2) but I don't want to test for that because there's
3455         # always some weirdo architecture that needs to ruin
3456         # everything by defining these error numbers differently.
3457
3458         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3459         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3460
3461         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3462         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3463
3464         return 0
3465 }
3466 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3467
3468 test_27R() {
3469         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3470                 skip "need MDS 2.14.55 or later"
3471         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3472
3473         local testdir="$DIR/$tdir"
3474         test_mkdir -p $testdir
3475         stack_trap "rm -rf $testdir"
3476         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3477
3478         local f1="$testdir/f1"
3479         touch $f1 || error "failed to touch $f1"
3480         local count=$($LFS getstripe -c $f1)
3481         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3482
3483         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3484         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3485
3486         local maxcount=$(($OSTCOUNT - 1))
3487         local mdts=$(comma_list $(mdts_nodes))
3488         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3489         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3490
3491         local f2="$testdir/f2"
3492         touch $f2 || error "failed to touch $f2"
3493         local count=$($LFS getstripe -c $f2)
3494         (( $count == $maxcount )) || error "wrong stripe count"
3495 }
3496 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3497
3498 test_27T() {
3499         [ $(facet_host client) == $(facet_host ost1) ] &&
3500                 skip "need ost1 and client on different nodes"
3501
3502 #define OBD_FAIL_OSC_NO_GRANT            0x411
3503         $LCTL set_param fail_loc=0x20000411 fail_val=1
3504 #define OBD_FAIL_OST_ENOSPC              0x215
3505         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3506         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3507         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3508                 error "multiop failed"
3509 }
3510 run_test 27T "no eio on close on partial write due to enosp"
3511
3512 test_27U() {
3513         local dir=$DIR/$tdir
3514         local file=$dir/$tfile
3515         local append_pool=${TESTNAME}-append
3516         local normal_pool=${TESTNAME}-normal
3517         local pool
3518         local stripe_count
3519         local stripe_count2
3520         local mdts=$(comma_list $(mdts_nodes))
3521
3522         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3523                 skip "Need MDS version at least 2.15.51 for append pool feature"
3524
3525         # Validate existing append_* params and ensure restore
3526         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3527         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3528         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3529
3530         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3531         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3532         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3533
3534         pool_add $append_pool || error "pool creation failed"
3535         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3536
3537         pool_add $normal_pool || error "pool creation failed"
3538         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3539
3540         test_mkdir $dir
3541         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3542
3543         echo XXX >> $file.1
3544         $LFS getstripe $file.1
3545
3546         pool=$($LFS getstripe -p $file.1)
3547         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3548
3549         stripe_count2=$($LFS getstripe -c $file.1)
3550         ((stripe_count2 == stripe_count)) ||
3551                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3552
3553         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3554
3555         echo XXX >> $file.2
3556         $LFS getstripe $file.2
3557
3558         pool=$($LFS getstripe -p $file.2)
3559         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3560
3561         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3562
3563         echo XXX >> $file.3
3564         $LFS getstripe $file.3
3565
3566         stripe_count2=$($LFS getstripe -c $file.3)
3567         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3568 }
3569 run_test 27U "append pool and stripe count work with composite default layout"
3570
3571 test_27V() {
3572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3573         (( $OSTCOUNT >= 4 )) || skip_env "needs >= 4 OSTs"
3574
3575         local dir=$DIR/$tdir
3576         local osp_param=osp.$FSNAME-OST0000-osc-MDT0000.max_create_count
3577         local lod_param=lod.$FSNAME-MDT0000-mdtlov.qos_threshold_rr
3578         local saved_max=$(do_facet mds1 $LCTL get_param -n $osp_param)
3579         local saved_qos=$(do_facet mds1 $LCTL get_param -n $lod_param)
3580         local pid
3581
3582         stack_trap "do_facet mds1 $LCTL set_param $osp_param=$saved_max"
3583
3584         do_facet mds1 $LCTL set_param $lod_param=0
3585         stack_trap "do_facet mds1 $LCTL set_param $lod_param=$saved_qos"
3586
3587         $LFS setdirstripe --mdt-count=1 --mdt-index=0 $dir
3588         stack_trap "rm -rf $dir"
3589
3590         # exercise race in LU-16981 with deactivating OST while creating a file
3591         (
3592                 while true; do
3593                         do_facet mds1 $LCTL set_param $osp_param=0 > /dev/null
3594                         sleep 0.1
3595                         do_facet mds1 \
3596                                 $LCTL set_param $osp_param=$saved_max > /dev/null
3597                 done
3598         ) &
3599
3600         pid=$!
3601         stack_trap "kill -9 $pid"
3602
3603         # errors here are OK so ignore them (just don't want to crash)
3604         $LFS setstripe -c -1 $dir/f.{1..200} 2> /dev/null
3605
3606         return 0
3607 }
3608 run_test 27V "creating widely striped file races with deactivating OST"
3609
3610 # createtest also checks that device nodes are created and
3611 # then visible correctly (#2091)
3612 test_28() { # bug 2091
3613         test_mkdir $DIR/d28
3614         $CREATETEST $DIR/d28/ct || error "createtest failed"
3615 }
3616 run_test 28 "create/mknod/mkdir with bad file types ============"
3617
3618 test_29() {
3619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3620
3621         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3622                 disable_opencache
3623                 stack_trap "restore_opencache"
3624         }
3625
3626         sync; sleep 1; sync # flush out any dirty pages from previous tests
3627         cancel_lru_locks
3628         test_mkdir $DIR/d29
3629         touch $DIR/d29/foo
3630         log 'first d29'
3631         ls -l $DIR/d29
3632
3633         local locks_orig=$(total_used_locks mdc)
3634         (( $locks_orig != 0 )) || error "No mdc lock count"
3635
3636         local locks_unused_orig=$(total_unused_locks mdc)
3637
3638         log 'second d29'
3639         ls -l $DIR/d29
3640         log 'done'
3641
3642         local locks_current=$(total_used_locks mdc)
3643
3644         local locks_unused_current=$(total_unused_locks mdc)
3645
3646         if (( $locks_current > $locks_orig )); then
3647                 $LCTL set_param -n ldlm.dump_namespaces ""
3648                 error "CURRENT: $locks_current > $locks_orig"
3649         fi
3650         if (( $locks_unused_current > $locks_unused_orig )); then
3651                 error "UNUSED: $locks_unused_current > $locks_unused_orig"
3652         fi
3653 }
3654 run_test 29 "IT_GETATTR regression  ============================"
3655
3656 test_30a() { # was test_30
3657         cp $(which ls) $DIR || cp /bin/ls $DIR
3658         $DIR/ls / || error "Can't execute binary from lustre"
3659         rm $DIR/ls
3660 }
3661 run_test 30a "execute binary from Lustre (execve) =============="
3662
3663 test_30b() {
3664         cp `which ls` $DIR || cp /bin/ls $DIR
3665         chmod go+rx $DIR/ls
3666         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3667         rm $DIR/ls
3668 }
3669 run_test 30b "execute binary from Lustre as non-root ==========="
3670
3671 test_30c() { # b=22376
3672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3673
3674         cp $(which ls) $DIR || cp /bin/ls $DIR
3675         chmod a-rw $DIR/ls
3676         cancel_lru_locks mdc
3677         cancel_lru_locks osc
3678         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3679         rm -f $DIR/ls
3680 }
3681 run_test 30c "execute binary from Lustre without read perms ===="
3682
3683 test_30d() {
3684         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3685
3686         for i in {1..10}; do
3687                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3688                 local PID=$!
3689                 sleep 1
3690                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3691                 wait $PID || error "executing dd from Lustre failed"
3692                 rm -f $DIR/$tfile
3693         done
3694
3695         rm -f $DIR/dd
3696 }
3697 run_test 30d "execute binary from Lustre while clear locks"
3698
3699 test_31a() {
3700         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3701         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3702 }
3703 run_test 31a "open-unlink file =================================="
3704
3705 test_31b() {
3706         touch $DIR/f31 || error "touch $DIR/f31 failed"
3707         ln $DIR/f31 $DIR/f31b || error "ln failed"
3708         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3709         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3710 }
3711 run_test 31b "unlink file with multiple links while open ======="
3712
3713 test_31c() {
3714         touch $DIR/f31 || error "touch $DIR/f31 failed"
3715         ln $DIR/f31 $DIR/f31c || error "ln failed"
3716         multiop_bg_pause $DIR/f31 O_uc ||
3717                 error "multiop_bg_pause for $DIR/f31 failed"
3718         MULTIPID=$!
3719         $MULTIOP $DIR/f31c Ouc
3720         kill -USR1 $MULTIPID
3721         wait $MULTIPID
3722 }
3723 run_test 31c "open-unlink file with multiple links ============="
3724
3725 test_31d() {
3726         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3727         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3728 }
3729 run_test 31d "remove of open directory ========================="
3730
3731 test_31e() { # bug 2904
3732         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3733 }
3734 run_test 31e "remove of open non-empty directory ==============="
3735
3736 test_31f() { # bug 4554
3737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3738
3739         set -vx
3740         test_mkdir $DIR/d31f
3741         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3742         cp /etc/hosts $DIR/d31f
3743         ls -l $DIR/d31f
3744         $LFS getstripe $DIR/d31f/hosts
3745         multiop_bg_pause $DIR/d31f D_c || return 1
3746         MULTIPID=$!
3747
3748         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3749         test_mkdir $DIR/d31f
3750         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3751         cp /etc/hosts $DIR/d31f
3752         ls -l $DIR/d31f
3753         $LFS getstripe $DIR/d31f/hosts
3754         multiop_bg_pause $DIR/d31f D_c || return 1
3755         MULTIPID2=$!
3756
3757         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3758         wait $MULTIPID || error "first opendir $MULTIPID failed"
3759
3760         sleep 6
3761
3762         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3763         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3764         set +vx
3765 }
3766 run_test 31f "remove of open directory with open-unlink file ==="
3767
3768 test_31g() {
3769         echo "-- cross directory link --"
3770         test_mkdir -c1 $DIR/${tdir}ga
3771         test_mkdir -c1 $DIR/${tdir}gb
3772         touch $DIR/${tdir}ga/f
3773         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3774         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3775         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3776         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3777         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3778 }
3779 run_test 31g "cross directory link==============="
3780
3781 test_31h() {
3782         echo "-- cross directory link --"
3783         test_mkdir -c1 $DIR/${tdir}
3784         test_mkdir -c1 $DIR/${tdir}/dir
3785         touch $DIR/${tdir}/f
3786         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3787         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3788         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3789         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3790         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3791 }
3792 run_test 31h "cross directory link under child==============="
3793
3794 test_31i() {
3795         echo "-- cross directory link --"
3796         test_mkdir -c1 $DIR/$tdir
3797         test_mkdir -c1 $DIR/$tdir/dir
3798         touch $DIR/$tdir/dir/f
3799         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3800         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3801         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3802         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3803         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3804 }
3805 run_test 31i "cross directory link under parent==============="
3806
3807 test_31j() {
3808         test_mkdir -c1 -p $DIR/$tdir
3809         test_mkdir -c1 -p $DIR/$tdir/dir1
3810         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3811         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3812         link $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "link to the same dir"
3813         return 0
3814 }
3815 run_test 31j "link for directory"
3816
3817 test_31k() {
3818         test_mkdir -c1 -p $DIR/$tdir
3819         touch $DIR/$tdir/s
3820         touch $DIR/$tdir/exist
3821         link $DIR/$tdir/s $DIR/$tdir/t || error "link"
3822         link $DIR/$tdir/s $DIR/$tdir/exist && error "link to exist file"
3823         link $DIR/$tdir/s $DIR/$tdir/s && error "link to the same file"
3824         link $DIR/$tdir/s $DIR/$tdir && error "link to parent dir"
3825         link $DIR/$tdir $DIR/$tdir/s && error "link parent dir to target"
3826         link $DIR/$tdir/not-exist $DIR/$tdir/foo && error "link non-existing to new"
3827         link $DIR/$tdir/not-exist $DIR/$tdir/s && error "link non-existing to exist"
3828         return 0
3829 }
3830 run_test 31k "link to file: the same, non-existing, dir"
3831
3832 test_31l() {
3833         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3834
3835         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3836         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3837                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3838
3839         touch $DIR/$tfile || error "create failed"
3840         mkdir $DIR/$tdir || error "mkdir failed"
3841         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3842 }
3843 run_test 31l "link to file: target dir has trailing slash"
3844
3845 test_31m() {
3846         mkdir $DIR/d31m
3847         touch $DIR/d31m/s
3848         mkdir $DIR/d31m2
3849         touch $DIR/d31m2/exist
3850         link $DIR/d31m/s $DIR/d31m2/t || error "link"
3851         link $DIR/d31m/s $DIR/d31m2/exist && error "link to exist file"
3852         link $DIR/d31m/s $DIR/d31m2 && error "link to parent dir"
3853         link $DIR/d31m2 $DIR/d31m/s && error "link parent dir to target"
3854         link $DIR/d31m/not-exist $DIR/d31m2/foo && error "link non-existing to new"
3855         link $DIR/d31m/not-exist $DIR/d31m2/s && error "link non-existing to exist"
3856         return 0
3857 }
3858 run_test 31m "link to file: the same, non-existing, dir"
3859
3860 test_31n() {
3861         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3862         nlink=$(stat --format=%h $DIR/$tfile)
3863         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3864         local fd=$(free_fd)
3865         local cmd="exec $fd<$DIR/$tfile"
3866         eval $cmd
3867         cmd="exec $fd<&-"
3868         trap "eval $cmd" EXIT
3869         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3870         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3871         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3872         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3873         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3874         eval $cmd
3875 }
3876 run_test 31n "check link count of unlinked file"
3877
3878 link_one() {
3879         local tempfile=$(mktemp $1_XXXXXX)
3880         link $tempfile $1 2> /dev/null &&
3881                 echo "$BASHPID: link $tempfile to $1 succeeded"
3882         unlink $tempfile
3883 }
3884
3885 test_31o() { # LU-2901
3886         test_mkdir $DIR/$tdir
3887         for LOOP in $(seq 100); do
3888                 rm -f $DIR/$tdir/$tfile*
3889                 for THREAD in $(seq 8); do
3890                         link_one $DIR/$tdir/$tfile.$LOOP &
3891                 done
3892                 wait
3893                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3894                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3895                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3896                         break || true
3897         done
3898 }
3899 run_test 31o "duplicate hard links with same filename"
3900
3901 test_31p() {
3902         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3903
3904         test_mkdir $DIR/$tdir
3905         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3906         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3907
3908         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3909                 error "open unlink test1 failed"
3910         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3911                 error "open unlink test2 failed"
3912
3913         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3914                 error "test1 still exists"
3915         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3916                 error "test2 still exists"
3917 }
3918 run_test 31p "remove of open striped directory"
3919
3920 test_31q() {
3921         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3922
3923         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3924         index=$($LFS getdirstripe -i $DIR/$tdir)
3925         [ $index -eq 3 ] || error "first stripe index $index != 3"
3926         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3927         [ $index -eq 1 ] || error "second stripe index $index != 1"
3928
3929         # when "-c <stripe_count>" is set, the number of MDTs specified after
3930         # "-i" should equal to the stripe count
3931         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3932 }
3933 run_test 31q "create striped directory on specific MDTs"
3934
3935 #LU-14949
3936 test_31r() {
3937         touch $DIR/$tfile.target
3938         touch $DIR/$tfile.source
3939
3940         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3941         $LCTL set_param fail_loc=0x1419 fail_val=3
3942         cat $DIR/$tfile.target &
3943         CATPID=$!
3944
3945         # Guarantee open is waiting before we get here
3946         sleep 1
3947         mv $DIR/$tfile.source $DIR/$tfile.target
3948
3949         wait $CATPID
3950         RC=$?
3951         if [[ $RC -ne 0 ]]; then
3952                 error "open with cat failed, rc=$RC"
3953         fi
3954 }
3955 run_test 31r "open-rename(replace) race"
3956
3957 cleanup_test32_mount() {
3958         local rc=0
3959         trap 0
3960         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3961         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3962         losetup -d $loopdev || true
3963         rm -rf $DIR/$tdir
3964         return $rc
3965 }
3966
3967 test_32a() {
3968         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3969
3970         echo "== more mountpoints and symlinks ================="
3971         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3972         trap cleanup_test32_mount EXIT
3973         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3974         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3975                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3976         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3977                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3978         cleanup_test32_mount
3979 }
3980 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3981
3982 test_32b() {
3983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3984
3985         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3986         trap cleanup_test32_mount EXIT
3987         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3988         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3989                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3990         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3991                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3992         cleanup_test32_mount
3993 }
3994 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3995
3996 test_32c() {
3997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3998
3999         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4000         trap cleanup_test32_mount EXIT
4001         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4002         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4003                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4004         test_mkdir -p $DIR/$tdir/d2/test_dir
4005         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4006                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
4007         cleanup_test32_mount
4008 }
4009 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
4010
4011 test_32d() {
4012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4013
4014         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4015         trap cleanup_test32_mount EXIT
4016         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4017         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4018                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4019         test_mkdir -p $DIR/$tdir/d2/test_dir
4020         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
4021                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
4022         cleanup_test32_mount
4023 }
4024 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
4025
4026 test_32e() {
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         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
4033         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
4034 }
4035 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
4036
4037 test_32f() {
4038         rm -fr $DIR/$tdir
4039         test_mkdir -p $DIR/$tdir/tmp
4040         local tmp_dir=$DIR/$tdir/tmp
4041         ln -s $DIR/$tdir $tmp_dir/symlink11
4042         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
4043         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
4044         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
4045 }
4046 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
4047
4048 test_32g() {
4049         local tmp_dir=$DIR/$tdir/tmp
4050         test_mkdir -p $tmp_dir
4051         test_mkdir $DIR/${tdir}2
4052         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4053         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4054         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
4055         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
4056         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
4057         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
4058 }
4059 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4060
4061 test_32h() {
4062         rm -fr $DIR/$tdir $DIR/${tdir}2
4063         tmp_dir=$DIR/$tdir/tmp
4064         test_mkdir -p $tmp_dir
4065         test_mkdir $DIR/${tdir}2
4066         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
4067         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
4068         ls $tmp_dir/symlink12 || error "listing symlink12"
4069         ls $DIR/$tdir/symlink02  || error "listing symlink02"
4070 }
4071 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
4072
4073 test_32i() {
4074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4075
4076         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4077         trap cleanup_test32_mount EXIT
4078         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4079         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4080                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4081         touch $DIR/$tdir/test_file
4082         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
4083                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
4084         cleanup_test32_mount
4085 }
4086 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4087
4088 test_32j() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4092         trap cleanup_test32_mount EXIT
4093         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4094         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4095                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4096         touch $DIR/$tdir/test_file
4097         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4098                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4099         cleanup_test32_mount
4100 }
4101 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4102
4103 test_32k() {
4104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4105
4106         rm -fr $DIR/$tdir
4107         trap cleanup_test32_mount EXIT
4108         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4109         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4110                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4111         test_mkdir -p $DIR/$tdir/d2
4112         touch $DIR/$tdir/d2/test_file || error "touch failed"
4113         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4114                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4115         cleanup_test32_mount
4116 }
4117 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4118
4119 test_32l() {
4120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4121
4122         rm -fr $DIR/$tdir
4123         trap cleanup_test32_mount EXIT
4124         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4125         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4126                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4127         test_mkdir -p $DIR/$tdir/d2
4128         touch $DIR/$tdir/d2/test_file || error "touch failed"
4129         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4130                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4131         cleanup_test32_mount
4132 }
4133 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4134
4135 test_32m() {
4136         rm -fr $DIR/d32m
4137         test_mkdir -p $DIR/d32m/tmp
4138         TMP_DIR=$DIR/d32m/tmp
4139         ln -s $DIR $TMP_DIR/symlink11
4140         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4141         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4142                 error "symlink11 not a link"
4143         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4144                 error "symlink01 not a link"
4145 }
4146 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4147
4148 test_32n() {
4149         rm -fr $DIR/d32n
4150         test_mkdir -p $DIR/d32n/tmp
4151         TMP_DIR=$DIR/d32n/tmp
4152         ln -s $DIR $TMP_DIR/symlink11
4153         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4154         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4155         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4156 }
4157 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4158
4159 test_32o() {
4160         touch $DIR/$tfile
4161         test_mkdir -p $DIR/d32o/tmp
4162         TMP_DIR=$DIR/d32o/tmp
4163         ln -s $DIR/$tfile $TMP_DIR/symlink12
4164         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4165         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4166                 error "symlink12 not a link"
4167         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4168         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4169                 error "$DIR/d32o/tmp/symlink12 not file type"
4170         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4171                 error "$DIR/d32o/symlink02 not file type"
4172 }
4173 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4174
4175 test_32p() {
4176         log 32p_1
4177         rm -fr $DIR/d32p
4178         log 32p_2
4179         rm -f $DIR/$tfile
4180         log 32p_3
4181         touch $DIR/$tfile
4182         log 32p_4
4183         test_mkdir -p $DIR/d32p/tmp
4184         log 32p_5
4185         TMP_DIR=$DIR/d32p/tmp
4186         log 32p_6
4187         ln -s $DIR/$tfile $TMP_DIR/symlink12
4188         log 32p_7
4189         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4190         log 32p_8
4191         cat $DIR/d32p/tmp/symlink12 ||
4192                 error "Can't open $DIR/d32p/tmp/symlink12"
4193         log 32p_9
4194         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4195         log 32p_10
4196 }
4197 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4198
4199 test_32q() {
4200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4201
4202         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4203         trap cleanup_test32_mount EXIT
4204         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4205         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4206         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4207                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4208         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4209         cleanup_test32_mount
4210 }
4211 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4212
4213 test_32r() {
4214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4215
4216         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4217         trap cleanup_test32_mount EXIT
4218         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4219         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4220         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4221                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4222         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4223         cleanup_test32_mount
4224 }
4225 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4226
4227 test_33aa() {
4228         rm -f $DIR/$tfile
4229         touch $DIR/$tfile
4230         chmod 444 $DIR/$tfile
4231         chown $RUNAS_ID $DIR/$tfile
4232         log 33_1
4233         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4234         log 33_2
4235 }
4236 run_test 33aa "write file with mode 444 (should return error)"
4237
4238 test_33a() {
4239         rm -fr $DIR/$tdir
4240         test_mkdir $DIR/$tdir
4241         chown $RUNAS_ID $DIR/$tdir
4242         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4243                 error "$RUNAS create $tdir/$tfile failed"
4244         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4245                 error "open RDWR" || true
4246 }
4247 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4248
4249 test_33b() {
4250         rm -fr $DIR/$tdir
4251         test_mkdir $DIR/$tdir
4252         chown $RUNAS_ID $DIR/$tdir
4253         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4254 }
4255 run_test 33b "test open file with malformed flags (No panic)"
4256
4257 test_33c() {
4258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4259         remote_ost_nodsh && skip "remote OST with nodsh"
4260
4261         local ostnum
4262         local ostname
4263         local write_bytes
4264         local all_zeros
4265
4266         all_zeros=true
4267         test_mkdir $DIR/$tdir
4268         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4269
4270         sync
4271         for ostnum in $(seq $OSTCOUNT); do
4272                 # test-framework's OST numbering is one-based, while Lustre's
4273                 # is zero-based
4274                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4275                 # check if at least some write_bytes stats are counted
4276                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4277                               obdfilter.$ostname.stats |
4278                               awk '/^write_bytes/ {print $7}' )
4279                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4280                 if (( ${write_bytes:-0} > 0 )); then
4281                         all_zeros=false
4282                         break
4283                 fi
4284         done
4285
4286         $all_zeros || return 0
4287
4288         # Write four bytes
4289         echo foo > $DIR/$tdir/bar
4290         # Really write them
4291         sync
4292
4293         # Total up write_bytes after writing.  We'd better find non-zeros.
4294         for ostnum in $(seq $OSTCOUNT); do
4295                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4296                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4297                               obdfilter/$ostname/stats |
4298                               awk '/^write_bytes/ {print $7}' )
4299                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4300                 if (( ${write_bytes:-0} > 0 )); then
4301                         all_zeros=false
4302                         break
4303                 fi
4304         done
4305
4306         if $all_zeros; then
4307                 for ostnum in $(seq $OSTCOUNT); do
4308                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4309                         echo "Check write_bytes is in obdfilter.*.stats:"
4310                         do_facet ost$ostnum lctl get_param -n \
4311                                 obdfilter.$ostname.stats
4312                 done
4313                 error "OST not keeping write_bytes stats (b=22312)"
4314         fi
4315 }
4316 run_test 33c "test write_bytes stats"
4317
4318 test_33d() {
4319         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4321
4322         local MDTIDX=1
4323         local remote_dir=$DIR/$tdir/remote_dir
4324
4325         test_mkdir $DIR/$tdir
4326         $LFS mkdir -i $MDTIDX $remote_dir ||
4327                 error "create remote directory failed"
4328
4329         touch $remote_dir/$tfile
4330         chmod 444 $remote_dir/$tfile
4331         chown $RUNAS_ID $remote_dir/$tfile
4332
4333         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4334
4335         chown $RUNAS_ID $remote_dir
4336         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4337                                         error "create" || true
4338         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4339                                     error "open RDWR" || true
4340         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4341 }
4342 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4343
4344 test_33e() {
4345         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4346
4347         mkdir $DIR/$tdir
4348
4349         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4350         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4351         mkdir $DIR/$tdir/local_dir
4352
4353         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4354         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4355         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4356
4357         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4358                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4359
4360         rmdir $DIR/$tdir/* || error "rmdir failed"
4361
4362         umask 777
4363         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4364         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4365         mkdir $DIR/$tdir/local_dir
4366
4367         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4368         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4369         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4370
4371         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4372                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4373
4374         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4375
4376         umask 000
4377         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4378         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4379         mkdir $DIR/$tdir/local_dir
4380
4381         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4382         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4383         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4384
4385         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4386                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4387 }
4388 run_test 33e "mkdir and striped directory should have same mode"
4389
4390 cleanup_33f() {
4391         trap 0
4392         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4393 }
4394
4395 test_33f() {
4396         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4397         remote_mds_nodsh && skip "remote MDS with nodsh"
4398
4399         mkdir $DIR/$tdir
4400         chmod go+rwx $DIR/$tdir
4401         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4402         trap cleanup_33f EXIT
4403
4404         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4405                 error "cannot create striped directory"
4406
4407         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4408                 error "cannot create files in striped directory"
4409
4410         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4411                 error "cannot remove files in striped directory"
4412
4413         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4414                 error "cannot remove striped directory"
4415
4416         cleanup_33f
4417 }
4418 run_test 33f "nonroot user can create, access, and remove a striped directory"
4419
4420 test_33g() {
4421         mkdir -p $DIR/$tdir/dir2
4422
4423         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4424         echo $err
4425         [[ $err =~ "exists" ]] || error "Not exists error"
4426 }
4427 run_test 33g "nonroot user create already existing root created file"
4428
4429 sub_33h() {
4430         local hash_type=$1
4431         local count=250
4432
4433         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4434                 error "lfs mkdir -H $hash_type $tdir failed"
4435         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4436
4437         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4438         local index2
4439         local fname
4440
4441         for fname in $DIR/$tdir/$tfile.bak \
4442                      $DIR/$tdir/$tfile.SAV \
4443                      $DIR/$tdir/$tfile.orig \
4444                      $DIR/$tdir/$tfile~; do
4445                 touch $fname || error "touch $fname failed"
4446                 index2=$($LFS getstripe -m $fname)
4447                 (( $index == $index2 )) ||
4448                         error "$fname MDT index mismatch $index != $index2"
4449         done
4450
4451         local failed=0
4452         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4453         local pattern
4454
4455         for pattern in ${patterns[*]}; do
4456                 echo "pattern $pattern"
4457                 fname=$DIR/$tdir/$pattern
4458                 for (( i = 0; i < $count; i++ )); do
4459                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4460                                 error "mktemp $DIR/$tdir/$pattern failed"
4461                         index2=$($LFS getstripe -m $fname)
4462                         (( $index == $index2 )) && continue
4463
4464                         failed=$((failed + 1))
4465                         echo "$fname MDT index mismatch $index != $index2"
4466                 done
4467         done
4468
4469         echo "$failed/$count MDT index mismatches, expect ~2-4"
4470         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4471
4472         local same=0
4473         local expect
4474
4475         # verify that "crush" is still broken with all files on same MDT,
4476         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4477         [[ "$hash_type" == "crush" ]] && expect=$count ||
4478                 expect=$((count / MDSCOUNT))
4479
4480         # crush2 doesn't put all-numeric suffixes on the same MDT,
4481         # filename like $tfile.12345678 should *not* be considered temp
4482         for pattern in ${patterns[*]}; do
4483                 local base=${pattern%%X*}
4484                 local suff=${pattern#$base}
4485
4486                 echo "pattern $pattern"
4487                 for (( i = 0; i < $count; i++ )); do
4488                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4489                         touch $fname || error "touch $fname failed"
4490                         index2=$($LFS getstripe -m $fname)
4491                         (( $index != $index2 )) && continue
4492
4493                         same=$((same + 1))
4494                 done
4495         done
4496
4497         # the number of "bad" hashes is random, as it depends on the random
4498         # filenames generated by "mktemp".  Allow some margin in the results.
4499         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4500         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4501            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4502                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4503         same=0
4504
4505         # crush2 doesn't put suffixes with special characters on the same MDT
4506         # filename like $tfile.txt.1234 should *not* be considered temp
4507         for pattern in ${patterns[*]}; do
4508                 local base=${pattern%%X*}
4509                 local suff=${pattern#$base}
4510
4511                 pattern=$base...${suff/XXX}
4512                 echo "pattern=$pattern"
4513                 for (( i = 0; i < $count; i++ )); do
4514                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4515                                 error "touch $fname failed"
4516                         index2=$($LFS getstripe -m $fname)
4517                         (( $index != $index2 )) && continue
4518
4519                         same=$((same + 1))
4520                 done
4521         done
4522
4523         # the number of "bad" hashes is random, as it depends on the random
4524         # filenames generated by "mktemp".  Allow some margin in the results.
4525         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4526         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4527            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4528                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4529 }
4530
4531 test_33h() {
4532         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4533         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4534                 skip "Need MDS version at least 2.13.50"
4535
4536         sub_33h crush
4537 }
4538 run_test 33h "temp file is located on the same MDT as target (crush)"
4539
4540 test_33hh() {
4541         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4542         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4543         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4544                 skip "Need MDS version at least 2.15.0 for crush2"
4545
4546         sub_33h crush2
4547 }
4548 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4549
4550 test_33i()
4551 {
4552         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4553
4554         local FNAME=$(str_repeat 'f' 250)
4555
4556         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4557         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4558
4559         local count
4560         local total
4561
4562         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4563
4564         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4565
4566         lctl --device %$MDC deactivate
4567         stack_trap "lctl --device %$MDC activate"
4568         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4569         total=$(\ls -l $DIR/$tdir | wc -l)
4570         # "ls -l" will list total in the first line
4571         total=$((total - 1))
4572         (( total + count == 1000 )) ||
4573                 error "ls list $total files, $count files on MDT1"
4574 }
4575 run_test 33i "striped directory can be accessed when one MDT is down"
4576
4577 test_33j() {
4578         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4579
4580         mkdir -p $DIR/$tdir/
4581
4582         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4583                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4584
4585         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4586                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4587
4588         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4589                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4590
4591         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4592                 error "-D was not specified, but still failed"
4593 }
4594 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4595
4596 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4597 test_34a() {
4598         rm -f $DIR/f34
4599         $MCREATE $DIR/f34 || error "mcreate failed"
4600         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4601                 error "getstripe failed"
4602         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4603         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4604                 error "getstripe failed"
4605         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4606                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4607 }
4608 run_test 34a "truncate file that has not been opened ==========="
4609
4610 test_34b() {
4611         [ ! -f $DIR/f34 ] && test_34a
4612         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4613                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4614         $OPENFILE -f O_RDONLY $DIR/f34
4615         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4616                 error "getstripe failed"
4617         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4618                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4619 }
4620 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4621
4622 test_34c() {
4623         [ ! -f $DIR/f34 ] && test_34a
4624         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4625                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4626         $OPENFILE -f O_RDWR $DIR/f34
4627         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4628                 error "$LFS getstripe failed"
4629         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4630                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4631 }
4632 run_test 34c "O_RDWR opening file-with-size works =============="
4633
4634 test_34d() {
4635         [ ! -f $DIR/f34 ] && test_34a
4636         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4637                 error "dd failed"
4638         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4639                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4640         rm $DIR/f34
4641 }
4642 run_test 34d "write to sparse file ============================="
4643
4644 test_34e() {
4645         rm -f $DIR/f34e
4646         $MCREATE $DIR/f34e || error "mcreate failed"
4647         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4648         $CHECKSTAT -s 1000 $DIR/f34e ||
4649                 error "Size of $DIR/f34e not equal to 1000 bytes"
4650         $OPENFILE -f O_RDWR $DIR/f34e
4651         $CHECKSTAT -s 1000 $DIR/f34e ||
4652                 error "Size of $DIR/f34e not equal to 1000 bytes"
4653 }
4654 run_test 34e "create objects, some with size and some without =="
4655
4656 test_34f() { # bug 6242, 6243
4657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4658
4659         SIZE34F=48000
4660         rm -f $DIR/f34f
4661         $MCREATE $DIR/f34f || error "mcreate failed"
4662         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4663         dd if=$DIR/f34f of=$TMP/f34f
4664         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4665         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4666         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4667         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4668         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4669 }
4670 run_test 34f "read from a file with no objects until EOF ======="
4671
4672 test_34g() {
4673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4674
4675         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4676                 error "dd failed"
4677         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4678         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4679                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4680         cancel_lru_locks osc
4681         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4682                 error "wrong size after lock cancel"
4683
4684         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4685         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4686                 error "expanding truncate failed"
4687         cancel_lru_locks osc
4688         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4689                 error "wrong expanded size after lock cancel"
4690 }
4691 run_test 34g "truncate long file ==============================="
4692
4693 test_34h() {
4694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4695
4696         local gid=10
4697         local sz=1000
4698
4699         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4700         sync # Flush the cache so that multiop below does not block on cache
4701              # flush when getting the group lock
4702         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4703         MULTIPID=$!
4704
4705         # Since just timed wait is not good enough, let's do a sync write
4706         # that way we are sure enough time for a roundtrip + processing
4707         # passed + 2 seconds of extra margin.
4708         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4709         rm $DIR/${tfile}-1
4710         sleep 2
4711
4712         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4713                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4714                 kill -9 $MULTIPID
4715         fi
4716         wait $MULTIPID
4717         local nsz=`stat -c %s $DIR/$tfile`
4718         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4719 }
4720 run_test 34h "ftruncate file under grouplock should not block"
4721
4722 test_35a() {
4723         cp /bin/sh $DIR/f35a
4724         chmod 444 $DIR/f35a
4725         chown $RUNAS_ID $DIR/f35a
4726         $RUNAS $DIR/f35a && error || true
4727         rm $DIR/f35a
4728 }
4729 run_test 35a "exec file with mode 444 (should return and not leak)"
4730
4731 test_36a() {
4732         rm -f $DIR/f36
4733         utime $DIR/f36 || error "utime failed for MDS"
4734 }
4735 run_test 36a "MDS utime check (mknod, utime)"
4736
4737 test_36b() {
4738         echo "" > $DIR/f36
4739         utime $DIR/f36 || error "utime failed for OST"
4740 }
4741 run_test 36b "OST utime check (open, utime)"
4742
4743 test_36c() {
4744         rm -f $DIR/d36/f36
4745         test_mkdir $DIR/d36
4746         chown $RUNAS_ID $DIR/d36
4747         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4748 }
4749 run_test 36c "non-root MDS utime check (mknod, utime)"
4750
4751 test_36d() {
4752         [ ! -d $DIR/d36 ] && test_36c
4753         echo "" > $DIR/d36/f36
4754         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4755 }
4756 run_test 36d "non-root OST utime check (open, utime)"
4757
4758 test_36e() {
4759         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4760
4761         test_mkdir $DIR/$tdir
4762         touch $DIR/$tdir/$tfile
4763         $RUNAS utime $DIR/$tdir/$tfile &&
4764                 error "utime worked, expected failure" || true
4765 }
4766 run_test 36e "utime on non-owned file (should return error)"
4767
4768 subr_36fh() {
4769         local fl="$1"
4770         local LANG_SAVE=$LANG
4771         local LC_LANG_SAVE=$LC_LANG
4772         export LANG=C LC_LANG=C # for date language
4773
4774         DATESTR="Dec 20  2000"
4775         test_mkdir $DIR/$tdir
4776         lctl set_param fail_loc=$fl
4777         date; date +%s
4778         cp /etc/hosts $DIR/$tdir/$tfile
4779         sync & # write RPC generated with "current" inode timestamp, but delayed
4780         sleep 1
4781         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4782         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4783         cancel_lru_locks $OSC
4784         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4785         date; date +%s
4786         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4787                 echo "BEFORE: $LS_BEFORE" && \
4788                 echo "AFTER : $LS_AFTER" && \
4789                 echo "WANT  : $DATESTR" && \
4790                 error "$DIR/$tdir/$tfile timestamps changed" || true
4791
4792         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4793 }
4794
4795 test_36f() {
4796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4797
4798         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4799         subr_36fh "0x80000214"
4800 }
4801 run_test 36f "utime on file racing with OST BRW write =========="
4802
4803 test_36g() {
4804         remote_ost_nodsh && skip "remote OST with nodsh"
4805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4806         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4807                 skip "Need MDS version at least 2.12.51"
4808
4809         local fmd_max_age
4810         local fmd
4811         local facet="ost1"
4812         local tgt="obdfilter"
4813
4814         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4815
4816         test_mkdir $DIR/$tdir
4817         fmd_max_age=$(do_facet $facet \
4818                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4819                 head -n 1")
4820
4821         echo "FMD max age: ${fmd_max_age}s"
4822         touch $DIR/$tdir/$tfile
4823         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4824                 gawk '{cnt=cnt+$1}  END{print cnt}')
4825         echo "FMD before: $fmd"
4826         [[ $fmd == 0 ]] &&
4827                 error "FMD wasn't create by touch"
4828         sleep $((fmd_max_age + 12))
4829         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4830                 gawk '{cnt=cnt+$1}  END{print cnt}')
4831         echo "FMD after: $fmd"
4832         [[ $fmd == 0 ]] ||
4833                 error "FMD wasn't expired by ping"
4834 }
4835 run_test 36g "FMD cache expiry ====================="
4836
4837 test_36h() {
4838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4839
4840         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4841         subr_36fh "0x80000227"
4842 }
4843 run_test 36h "utime on file racing with OST BRW write =========="
4844
4845 test_36i() {
4846         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4847
4848         test_mkdir $DIR/$tdir
4849         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4850
4851         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4852         local new_mtime=$((mtime + 200))
4853
4854         #change Modify time of striped dir
4855         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4856                         error "change mtime failed"
4857
4858         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4859
4860         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4861 }
4862 run_test 36i "change mtime on striped directory"
4863
4864 # test_37 - duplicate with tests 32q 32r
4865
4866 test_38() {
4867         local file=$DIR/$tfile
4868         touch $file
4869         openfile -f O_DIRECTORY $file
4870         local RC=$?
4871         local ENOTDIR=20
4872         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4873         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4874 }
4875 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4876
4877 test_39a() { # was test_39
4878         touch $DIR/$tfile
4879         touch $DIR/${tfile}2
4880 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4881 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4882 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4883         sleep 2
4884         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4885         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4886                 echo "mtime"
4887                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4888                 echo "atime"
4889                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4890                 echo "ctime"
4891                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4892                 error "O_TRUNC didn't change timestamps"
4893         fi
4894 }
4895 run_test 39a "mtime changed on create"
4896
4897 test_39b() {
4898         test_mkdir -c1 $DIR/$tdir
4899         cp -p /etc/passwd $DIR/$tdir/fopen
4900         cp -p /etc/passwd $DIR/$tdir/flink
4901         cp -p /etc/passwd $DIR/$tdir/funlink
4902         cp -p /etc/passwd $DIR/$tdir/frename
4903         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4904
4905         sleep 1
4906         echo "aaaaaa" >> $DIR/$tdir/fopen
4907         echo "aaaaaa" >> $DIR/$tdir/flink
4908         echo "aaaaaa" >> $DIR/$tdir/funlink
4909         echo "aaaaaa" >> $DIR/$tdir/frename
4910
4911         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4912         local link_new=`stat -c %Y $DIR/$tdir/flink`
4913         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4914         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4915
4916         cat $DIR/$tdir/fopen > /dev/null
4917         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4918         rm -f $DIR/$tdir/funlink2
4919         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4920
4921         for (( i=0; i < 2; i++ )) ; do
4922                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4923                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4924                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4925                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4926
4927                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4928                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4929                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4930                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4931
4932                 cancel_lru_locks $OSC
4933                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4934         done
4935 }
4936 run_test 39b "mtime change on open, link, unlink, rename  ======"
4937
4938 # this should be set to past
4939 TEST_39_MTIME=`date -d "1 year ago" +%s`
4940
4941 # bug 11063
4942 test_39c() {
4943         touch $DIR1/$tfile
4944         sleep 2
4945         local mtime0=`stat -c %Y $DIR1/$tfile`
4946
4947         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4948         local mtime1=`stat -c %Y $DIR1/$tfile`
4949         [ "$mtime1" = $TEST_39_MTIME ] || \
4950                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4951
4952         local d1=`date +%s`
4953         echo hello >> $DIR1/$tfile
4954         local d2=`date +%s`
4955         local mtime2=`stat -c %Y $DIR1/$tfile`
4956         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4957                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4958
4959         mv $DIR1/$tfile $DIR1/$tfile-1
4960
4961         for (( i=0; i < 2; i++ )) ; do
4962                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4963                 [ "$mtime2" = "$mtime3" ] || \
4964                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4965
4966                 cancel_lru_locks $OSC
4967                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4968         done
4969 }
4970 run_test 39c "mtime change on rename ==========================="
4971
4972 # bug 21114
4973 test_39d() {
4974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4975
4976         touch $DIR1/$tfile
4977         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4978
4979         for (( i=0; i < 2; i++ )) ; do
4980                 local mtime=`stat -c %Y $DIR1/$tfile`
4981                 [ $mtime = $TEST_39_MTIME ] || \
4982                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4983
4984                 cancel_lru_locks $OSC
4985                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4986         done
4987 }
4988 run_test 39d "create, utime, stat =============================="
4989
4990 # bug 21114
4991 test_39e() {
4992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4993
4994         touch $DIR1/$tfile
4995         local mtime1=`stat -c %Y $DIR1/$tfile`
4996
4997         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4998
4999         for (( i=0; i < 2; i++ )) ; do
5000                 local mtime2=`stat -c %Y $DIR1/$tfile`
5001                 [ $mtime2 = $TEST_39_MTIME ] || \
5002                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5003
5004                 cancel_lru_locks $OSC
5005                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5006         done
5007 }
5008 run_test 39e "create, stat, utime, stat ========================"
5009
5010 # bug 21114
5011 test_39f() {
5012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5013
5014         touch $DIR1/$tfile
5015         mtime1=`stat -c %Y $DIR1/$tfile`
5016
5017         sleep 2
5018         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5019
5020         for (( i=0; i < 2; i++ )) ; do
5021                 local mtime2=`stat -c %Y $DIR1/$tfile`
5022                 [ $mtime2 = $TEST_39_MTIME ] || \
5023                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
5024
5025                 cancel_lru_locks $OSC
5026                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5027         done
5028 }
5029 run_test 39f "create, stat, sleep, utime, stat ================="
5030
5031 # bug 11063
5032 test_39g() {
5033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5034
5035         echo hello >> $DIR1/$tfile
5036         local mtime1=`stat -c %Y $DIR1/$tfile`
5037
5038         sleep 2
5039         chmod o+r $DIR1/$tfile
5040
5041         for (( i=0; i < 2; i++ )) ; do
5042                 local mtime2=`stat -c %Y $DIR1/$tfile`
5043                 [ "$mtime1" = "$mtime2" ] || \
5044                         error "lost mtime: $mtime2, should be $mtime1"
5045
5046                 cancel_lru_locks $OSC
5047                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5048         done
5049 }
5050 run_test 39g "write, chmod, stat ==============================="
5051
5052 # bug 11063
5053 test_39h() {
5054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5055
5056         touch $DIR1/$tfile
5057         sleep 1
5058
5059         local d1=`date`
5060         echo hello >> $DIR1/$tfile
5061         local mtime1=`stat -c %Y $DIR1/$tfile`
5062
5063         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5064         local d2=`date`
5065         if [ "$d1" != "$d2" ]; then
5066                 echo "write and touch not within one second"
5067         else
5068                 for (( i=0; i < 2; i++ )) ; do
5069                         local mtime2=`stat -c %Y $DIR1/$tfile`
5070                         [ "$mtime2" = $TEST_39_MTIME ] || \
5071                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
5072
5073                         cancel_lru_locks $OSC
5074                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5075                 done
5076         fi
5077 }
5078 run_test 39h "write, utime within one second, stat ============="
5079
5080 test_39i() {
5081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5082
5083         touch $DIR1/$tfile
5084         sleep 1
5085
5086         echo hello >> $DIR1/$tfile
5087         local mtime1=`stat -c %Y $DIR1/$tfile`
5088
5089         mv $DIR1/$tfile $DIR1/$tfile-1
5090
5091         for (( i=0; i < 2; i++ )) ; do
5092                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5093
5094                 [ "$mtime1" = "$mtime2" ] || \
5095                         error "lost mtime: $mtime2, should be $mtime1"
5096
5097                 cancel_lru_locks $OSC
5098                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5099         done
5100 }
5101 run_test 39i "write, rename, stat =============================="
5102
5103 test_39j() {
5104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5105
5106         start_full_debug_logging
5107         touch $DIR1/$tfile
5108         sleep 1
5109
5110         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5111         lctl set_param fail_loc=0x80000412
5112         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5113                 error "multiop failed"
5114         local multipid=$!
5115         local mtime1=`stat -c %Y $DIR1/$tfile`
5116
5117         mv $DIR1/$tfile $DIR1/$tfile-1
5118
5119         kill -USR1 $multipid
5120         wait $multipid || error "multiop close failed"
5121
5122         for (( i=0; i < 2; i++ )) ; do
5123                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5124                 [ "$mtime1" = "$mtime2" ] ||
5125                         error "mtime is lost on close: $mtime2, " \
5126                               "should be $mtime1"
5127
5128                 cancel_lru_locks
5129                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5130         done
5131         lctl set_param fail_loc=0
5132         stop_full_debug_logging
5133 }
5134 run_test 39j "write, rename, close, stat ======================="
5135
5136 test_39k() {
5137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5138
5139         touch $DIR1/$tfile
5140         sleep 1
5141
5142         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5143         local multipid=$!
5144         local mtime1=`stat -c %Y $DIR1/$tfile`
5145
5146         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5147
5148         kill -USR1 $multipid
5149         wait $multipid || error "multiop close failed"
5150
5151         for (( i=0; i < 2; i++ )) ; do
5152                 local mtime2=`stat -c %Y $DIR1/$tfile`
5153
5154                 [ "$mtime2" = $TEST_39_MTIME ] || \
5155                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5156
5157                 cancel_lru_locks
5158                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5159         done
5160 }
5161 run_test 39k "write, utime, close, stat ========================"
5162
5163 # this should be set to future
5164 TEST_39_ATIME=`date -d "1 year" +%s`
5165
5166 test_39l() {
5167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5168         remote_mds_nodsh && skip "remote MDS with nodsh"
5169
5170         local atime_diff=$(do_facet $SINGLEMDS \
5171                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5172         rm -rf $DIR/$tdir
5173         mkdir_on_mdt0 $DIR/$tdir
5174
5175         # test setting directory atime to future
5176         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5177         local atime=$(stat -c %X $DIR/$tdir)
5178         [ "$atime" = $TEST_39_ATIME ] ||
5179                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5180
5181         # test setting directory atime from future to now
5182         local now=$(date +%s)
5183         touch -a -d @$now $DIR/$tdir
5184
5185         atime=$(stat -c %X $DIR/$tdir)
5186         [ "$atime" -eq "$now"  ] ||
5187                 error "atime is not updated from future: $atime, $now"
5188
5189         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5190         sleep 3
5191
5192         # test setting directory atime when now > dir atime + atime_diff
5193         local d1=$(date +%s)
5194         ls $DIR/$tdir
5195         local d2=$(date +%s)
5196         cancel_lru_locks mdc
5197         atime=$(stat -c %X $DIR/$tdir)
5198         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5199                 error "atime is not updated  : $atime, should be $d2"
5200
5201         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5202         sleep 3
5203
5204         # test not setting directory atime when now < dir atime + atime_diff
5205         ls $DIR/$tdir
5206         cancel_lru_locks mdc
5207         atime=$(stat -c %X $DIR/$tdir)
5208         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5209                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5210
5211         do_facet $SINGLEMDS \
5212                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5213 }
5214 run_test 39l "directory atime update ==========================="
5215
5216 test_39m() {
5217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5218
5219         touch $DIR1/$tfile
5220         sleep 2
5221         local far_past_mtime=$(date -d "May 29 1953" +%s)
5222         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5223
5224         touch -m -d @$far_past_mtime $DIR1/$tfile
5225         touch -a -d @$far_past_atime $DIR1/$tfile
5226
5227         for (( i=0; i < 2; i++ )) ; do
5228                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5229                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5230                         error "atime or mtime set incorrectly"
5231
5232                 cancel_lru_locks $OSC
5233                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5234         done
5235 }
5236 run_test 39m "test atime and mtime before 1970"
5237
5238 test_39n() { # LU-3832
5239         remote_mds_nodsh && skip "remote MDS with nodsh"
5240
5241         local atime_diff=$(do_facet $SINGLEMDS \
5242                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5243         local atime0
5244         local atime1
5245         local atime2
5246
5247         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5248
5249         rm -rf $DIR/$tfile
5250         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5251         atime0=$(stat -c %X $DIR/$tfile)
5252
5253         sleep 5
5254         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5255         atime1=$(stat -c %X $DIR/$tfile)
5256
5257         sleep 5
5258         cancel_lru_locks mdc
5259         cancel_lru_locks osc
5260         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5261         atime2=$(stat -c %X $DIR/$tfile)
5262
5263         do_facet $SINGLEMDS \
5264                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5265
5266         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5267         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5268 }
5269 run_test 39n "check that O_NOATIME is honored"
5270
5271 test_39o() {
5272         TESTDIR=$DIR/$tdir/$tfile
5273         [ -e $TESTDIR ] && rm -rf $TESTDIR
5274         mkdir -p $TESTDIR
5275         cd $TESTDIR
5276         links1=2
5277         ls
5278         mkdir a b
5279         ls
5280         links2=$(stat -c %h .)
5281         [ $(($links1 + 2)) != $links2 ] &&
5282                 error "wrong links count $(($links1 + 2)) != $links2"
5283         rmdir b
5284         links3=$(stat -c %h .)
5285         [ $(($links1 + 1)) != $links3 ] &&
5286                 error "wrong links count $links1 != $links3"
5287         return 0
5288 }
5289 run_test 39o "directory cached attributes updated after create"
5290
5291 test_39p() {
5292         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5293
5294         local MDTIDX=1
5295         TESTDIR=$DIR/$tdir/$tdir
5296         [ -e $TESTDIR ] && rm -rf $TESTDIR
5297         test_mkdir -p $TESTDIR
5298         cd $TESTDIR
5299         links1=2
5300         ls
5301         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5302         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5303         ls
5304         links2=$(stat -c %h .)
5305         [ $(($links1 + 2)) != $links2 ] &&
5306                 error "wrong links count $(($links1 + 2)) != $links2"
5307         rmdir remote_dir2
5308         links3=$(stat -c %h .)
5309         [ $(($links1 + 1)) != $links3 ] &&
5310                 error "wrong links count $links1 != $links3"
5311         return 0
5312 }
5313 run_test 39p "remote directory cached attributes updated after create ========"
5314
5315 test_39r() {
5316         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5317                 skip "no atime update on old OST"
5318         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5319                 skip_env "ldiskfs only test"
5320         fi
5321
5322         local saved_adiff
5323         local ahost=$(facet_active_host ost1)
5324         saved_adiff=$(do_facet ost1 \
5325                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5326         stack_trap "do_facet ost1 \
5327                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5328
5329         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5330
5331         $LFS setstripe -i 0 $DIR/$tfile
5332         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5333                 error "can't write initial file"
5334         cancel_lru_locks osc
5335
5336         # exceed atime_diff and access file
5337         sleep 10
5338         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5339                 error "can't udpate atime"
5340
5341         # atime_cli value is in decimal
5342         local atime_cli=$(stat -c %X $DIR/$tfile)
5343         echo "client atime: $atime_cli"
5344
5345         local ostdev=$(ostdevname 1)
5346         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5347         local seq=${fid[3]#0x}
5348         local oid=${fid[1]}
5349         local oid_hex
5350
5351         if [ $seq == 0 ]; then
5352                 oid_hex=${fid[1]}
5353         else
5354                 oid_hex=${fid[2]#0x}
5355         fi
5356         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5357         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5358
5359         # allow atime update to be written to device
5360         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync=1"
5361         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5362
5363         # Give enough time for server to get updated. Until then
5364         # the value read is defaulted to "0x00000000:00000000"
5365         # Wait until atime read via debugfs is not equal to zero.
5366         # Max limit to wait is 30 seconds.
5367         wait_update_cond $ahost                                         \
5368                 "$cmd |& awk -F'[: ]' '/atime:/ { print \\\$4 }'"       \
5369                 "-gt" "0" 30 || error "atime on ost is still 0 after 30 seconds"
5370         # atime_ost value is in hex
5371         local atime_ost=$(do_facet ost1 "$cmd" |&
5372                           awk -F'[: ]' '/atime:/ { print $4 }')
5373         # debugfs returns atime in 0xNNNNNNNN:00000000 format
5374         # convert Hex to decimal before comparing
5375         local atime_ost_dec=$((atime_ost))
5376
5377         # The test pass criteria is that the client time and server should
5378         # be same (2s gap accepted). This gap could arise due to VFS updating
5379         # the atime after the read(dd), stat and the updated time from the
5380         # inode
5381         (( $((atime_cli - atime_ost_dec)) <= 2 )) ||
5382                 error "atime on client $atime_cli != ost $atime_ost_dec"
5383 }
5384 run_test 39r "lazy atime update on OST"
5385
5386 test_39q() { # LU-8041
5387         local testdir=$DIR/$tdir
5388         mkdir -p $testdir
5389         multiop_bg_pause $testdir D_c || error "multiop failed"
5390         local multipid=$!
5391         cancel_lru_locks mdc
5392         kill -USR1 $multipid
5393         local atime=$(stat -c %X $testdir)
5394         [ "$atime" -ne 0 ] || error "atime is zero"
5395 }
5396 run_test 39q "close won't zero out atime"
5397
5398 test_39s() {
5399         local atime0
5400         local atime1
5401         local atime2
5402         local atime3
5403         local atime4
5404
5405         umount_client $MOUNT
5406         mount_client $MOUNT relatime
5407
5408         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5409         atime0=$(stat -c %X $DIR/$tfile)
5410
5411         # First read updates atime
5412         sleep 1
5413         cat $DIR/$tfile >/dev/null
5414         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5415
5416         # Next reads do not update atime
5417         sleep 1
5418         cat $DIR/$tfile >/dev/null
5419         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5420
5421         # If mtime is greater than atime, atime is updated
5422         sleep 1
5423         touch -m $DIR/$tfile # (mtime = now)
5424         sleep 1
5425         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5426         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5427
5428         # Next reads do not update atime
5429         sleep 1
5430         cat $DIR/$tfile >/dev/null
5431         atime4=$(stat -c %X $DIR/$tfile)
5432
5433         # Remount the client to clear 'relatime' option
5434         remount_client $MOUNT
5435
5436         (( atime0 < atime1 )) ||
5437                 error "atime $atime0 should be smaller than $atime1"
5438         (( atime1 == atime2 )) ||
5439                 error "atime $atime1 was updated to $atime2"
5440         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5441         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5442 }
5443 run_test 39s "relatime is supported"
5444
5445 test_40() {
5446         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5447         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5448                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5449         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5450                 error "$tfile is not 4096 bytes in size"
5451 }
5452 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5453
5454 test_41() {
5455         # bug 1553
5456         small_write $DIR/f41 18
5457 }
5458 run_test 41 "test small file write + fstat ====================="
5459
5460 count_ost_writes() {
5461         lctl get_param -n ${OSC}.*.stats |
5462                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5463                         END { printf("%0.0f", writes) }'
5464 }
5465
5466 # decent default
5467 WRITEBACK_SAVE=500
5468 DIRTY_RATIO_SAVE=40
5469 MAX_DIRTY_RATIO=50
5470 BG_DIRTY_RATIO_SAVE=10
5471 MAX_BG_DIRTY_RATIO=25
5472
5473 start_writeback() {
5474         trap 0
5475         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5476         # dirty_ratio, dirty_background_ratio
5477         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5478                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5479                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5480                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5481         else
5482                 # if file not here, we are a 2.4 kernel
5483                 kill -CONT `pidof kupdated`
5484         fi
5485 }
5486
5487 stop_writeback() {
5488         # setup the trap first, so someone cannot exit the test at the
5489         # exact wrong time and mess up a machine
5490         trap start_writeback EXIT
5491         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5492         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5493                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5494                 sysctl -w vm.dirty_writeback_centisecs=0
5495                 sysctl -w vm.dirty_writeback_centisecs=0
5496                 # save and increase /proc/sys/vm/dirty_ratio
5497                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5498                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5499                 # save and increase /proc/sys/vm/dirty_background_ratio
5500                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5501                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5502         else
5503                 # if file not here, we are a 2.4 kernel
5504                 kill -STOP `pidof kupdated`
5505         fi
5506 }
5507
5508 # ensure that all stripes have some grant before we test client-side cache
5509 setup_test42() {
5510         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5511                 dd if=/dev/zero of=$i bs=4k count=1
5512                 rm $i
5513         done
5514 }
5515
5516 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5517 # file truncation, and file removal.
5518 test_42a() {
5519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5520
5521         setup_test42
5522         cancel_lru_locks $OSC
5523         stop_writeback
5524         sync; sleep 1; sync # just to be safe
5525         BEFOREWRITES=`count_ost_writes`
5526         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5527         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5528         AFTERWRITES=`count_ost_writes`
5529         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5530                 error "$BEFOREWRITES < $AFTERWRITES"
5531         start_writeback
5532 }
5533 run_test 42a "ensure that we don't flush on close"
5534
5535 test_42b() {
5536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5537
5538         setup_test42
5539         cancel_lru_locks $OSC
5540         stop_writeback
5541         sync
5542         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5543         BEFOREWRITES=$(count_ost_writes)
5544         unlink $DIR/f42b || error "unlink $DIR/f42b: $?"
5545         AFTERWRITES=$(count_ost_writes)
5546         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5547                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5548         fi
5549         BEFOREWRITES=$(count_ost_writes)
5550         sync || error "sync: $?"
5551         AFTERWRITES=$(count_ost_writes)
5552         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5553                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5554         fi
5555         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5556         start_writeback
5557         return 0
5558 }
5559 run_test 42b "test destroy of file with cached dirty data ======"
5560
5561 # if these tests just want to test the effect of truncation,
5562 # they have to be very careful.  consider:
5563 # - the first open gets a {0,EOF}PR lock
5564 # - the first write conflicts and gets a {0, count-1}PW
5565 # - the rest of the writes are under {count,EOF}PW
5566 # - the open for truncate tries to match a {0,EOF}PR
5567 #   for the filesize and cancels the PWs.
5568 # any number of fixes (don't get {0,EOF} on open, match
5569 # composite locks, do smarter file size management) fix
5570 # this, but for now we want these tests to verify that
5571 # the cancellation with truncate intent works, so we
5572 # start the file with a full-file pw lock to match against
5573 # until the truncate.
5574 trunc_test() {
5575         test=$1
5576         file=$DIR/$test
5577         offset=$2
5578         cancel_lru_locks $OSC
5579         stop_writeback
5580         # prime the file with 0,EOF PW to match
5581         touch $file
5582         $TRUNCATE $file 0
5583         sync; sync
5584         # now the real test..
5585         dd if=/dev/zero of=$file bs=1024 count=100
5586         BEFOREWRITES=`count_ost_writes`
5587         $TRUNCATE $file $offset
5588         cancel_lru_locks $OSC
5589         AFTERWRITES=`count_ost_writes`
5590         start_writeback
5591 }
5592
5593 test_42c() {
5594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5595
5596         trunc_test 42c 1024
5597         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5598                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5599         rm $file
5600 }
5601 run_test 42c "test partial truncate of file with cached dirty data"
5602
5603 test_42d() {
5604         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5605
5606         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5607         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5608         $LCTL set_param debug=+cache
5609
5610         trunc_test 42d 0
5611         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5612                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5613         rm $file
5614 }
5615 run_test 42d "test complete truncate of file with cached dirty data"
5616
5617 test_42e() { # bug22074
5618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5619
5620         local TDIR=$DIR/${tdir}e
5621         local pages=16 # hardcoded 16 pages, don't change it.
5622         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5623         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5624         local max_dirty_mb
5625         local warmup_files
5626
5627         test_mkdir $DIR/${tdir}e
5628         $LFS setstripe -c 1 $TDIR
5629         createmany -o $TDIR/f $files
5630
5631         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5632
5633         # we assume that with $OSTCOUNT files, at least one of them will
5634         # be allocated on OST0.
5635         warmup_files=$((OSTCOUNT * max_dirty_mb))
5636         createmany -o $TDIR/w $warmup_files
5637
5638         # write a large amount of data into one file and sync, to get good
5639         # avail_grant number from OST.
5640         for ((i=0; i<$warmup_files; i++)); do
5641                 idx=$($LFS getstripe -i $TDIR/w$i)
5642                 [ $idx -ne 0 ] && continue
5643                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5644                 break
5645         done
5646         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5647         sync
5648         $LCTL get_param $proc_osc0/cur_dirty_bytes
5649         $LCTL get_param $proc_osc0/cur_grant_bytes
5650
5651         # create as much dirty pages as we can while not to trigger the actual
5652         # RPCs directly. but depends on the env, VFS may trigger flush during this
5653         # period, hopefully we are good.
5654         for ((i=0; i<$warmup_files; i++)); do
5655                 idx=$($LFS getstripe -i $TDIR/w$i)
5656                 [ $idx -ne 0 ] && continue
5657                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5658         done
5659         $LCTL get_param $proc_osc0/cur_dirty_bytes
5660         $LCTL get_param $proc_osc0/cur_grant_bytes
5661
5662         # perform the real test
5663         $LCTL set_param $proc_osc0/rpc_stats 0
5664         for ((;i<$files; i++)); do
5665                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5666                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5667         done
5668         sync
5669         $LCTL get_param $proc_osc0/rpc_stats
5670
5671         local percent=0
5672         local have_ppr=false
5673         $LCTL get_param $proc_osc0/rpc_stats |
5674                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5675                         # skip lines until we are at the RPC histogram data
5676                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5677                         $have_ppr || continue
5678
5679                         # we only want the percent stat for < 16 pages
5680                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5681
5682                         percent=$((percent + WPCT))
5683                         if [[ $percent -gt 15 ]]; then
5684                                 error "less than 16-pages write RPCs" \
5685                                       "$percent% > 15%"
5686                                 break
5687                         fi
5688                 done
5689         rm -rf $TDIR
5690 }
5691 run_test 42e "verify sub-RPC writes are not done synchronously"
5692
5693 test_43A() { # was test_43
5694         test_mkdir $DIR/$tdir
5695         cp -p /bin/ls $DIR/$tdir/$tfile
5696         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5697         pid=$!
5698         # give multiop a chance to open
5699         sleep 1
5700
5701         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5702         kill -USR1 $pid
5703         # Wait for multiop to exit
5704         wait $pid
5705 }
5706 run_test 43A "execution of file opened for write should return -ETXTBSY"
5707
5708 test_43a() {
5709         test_mkdir $DIR/$tdir
5710         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5711         $DIR/$tdir/sleep 60 &
5712         SLEEP_PID=$!
5713         # Make sure exec of $tdir/sleep wins race with truncate
5714         sleep 1
5715         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5716         kill $SLEEP_PID
5717 }
5718 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5719
5720 test_43b() {
5721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5722
5723         test_mkdir $DIR/$tdir
5724         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5725         $DIR/$tdir/sleep 60 &
5726         SLEEP_PID=$!
5727         # Make sure exec of $tdir/sleep wins race with truncate
5728         sleep 1
5729         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5730         kill $SLEEP_PID
5731 }
5732 run_test 43b "truncate of file being executed should return -ETXTBSY"
5733
5734 test_43c() {
5735         local testdir="$DIR/$tdir"
5736         test_mkdir $testdir
5737         cp $SHELL $testdir/
5738         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5739                 ( cd $testdir && md5sum -c )
5740 }
5741 run_test 43c "md5sum of copy into lustre"
5742
5743 test_44A() { # was test_44
5744         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5745
5746         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5747         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5748 }
5749 run_test 44A "zero length read from a sparse stripe"
5750
5751 test_44a() {
5752         local nstripe=$($LFS getstripe -c -d $DIR)
5753         [ -z "$nstripe" ] && skip "can't get stripe info"
5754         [[ $nstripe -gt $OSTCOUNT ]] &&
5755                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5756
5757         local stride=$($LFS getstripe -S -d $DIR)
5758         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5759                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5760         fi
5761
5762         OFFSETS="0 $((stride/2)) $((stride-1))"
5763         for offset in $OFFSETS; do
5764                 for i in $(seq 0 $((nstripe-1))); do
5765                         local GLOBALOFFSETS=""
5766                         # size in Bytes
5767                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5768                         local myfn=$DIR/d44a-$size
5769                         echo "--------writing $myfn at $size"
5770                         ll_sparseness_write $myfn $size ||
5771                                 error "ll_sparseness_write"
5772                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5773                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5774                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5775
5776                         for j in $(seq 0 $((nstripe-1))); do
5777                                 # size in Bytes
5778                                 size=$((((j + $nstripe )*$stride + $offset)))
5779                                 ll_sparseness_write $myfn $size ||
5780                                         error "ll_sparseness_write"
5781                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5782                         done
5783                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5784                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5785                         rm -f $myfn
5786                 done
5787         done
5788 }
5789 run_test 44a "test sparse pwrite ==============================="
5790
5791 dirty_osc_total() {
5792         tot=0
5793         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5794                 tot=$(($tot + $d))
5795         done
5796         echo $tot
5797 }
5798 do_dirty_record() {
5799         before=`dirty_osc_total`
5800         echo executing "\"$*\""
5801         eval $*
5802         after=`dirty_osc_total`
5803         echo before $before, after $after
5804 }
5805 test_45() {
5806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5807
5808         f="$DIR/f45"
5809         # Obtain grants from OST if it supports it
5810         echo blah > ${f}_grant
5811         stop_writeback
5812         sync
5813         do_dirty_record "echo blah > $f"
5814         [[ $before -eq $after ]] && error "write wasn't cached"
5815         do_dirty_record "> $f"
5816         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5817         do_dirty_record "echo blah > $f"
5818         [[ $before -eq $after ]] && error "write wasn't cached"
5819         do_dirty_record "sync"
5820         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5821         do_dirty_record "echo blah > $f"
5822         [[ $before -eq $after ]] && error "write wasn't cached"
5823         do_dirty_record "cancel_lru_locks osc"
5824         [[ $before -gt $after ]] ||
5825                 error "lock cancellation didn't lower dirty count"
5826         start_writeback
5827 }
5828 run_test 45 "osc io page accounting ============================"
5829
5830 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5831 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5832 # objects offset and an assert hit when an rpc was built with 1023's mapped
5833 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5834 test_46() {
5835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5836
5837         f="$DIR/f46"
5838         stop_writeback
5839         sync
5840         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5841         sync
5842         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5843         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5844         sync
5845         start_writeback
5846 }
5847 run_test 46 "dirtying a previously written page ================"
5848
5849 # test_47 is removed "Device nodes check" is moved to test_28
5850
5851 test_48a() { # bug 2399
5852         [ "$mds1_FSTYPE" = "zfs" ] &&
5853         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5854                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5855
5856         test_mkdir $DIR/$tdir
5857         cd $DIR/$tdir
5858         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5859         test_mkdir $DIR/$tdir
5860         touch foo || error "'touch foo' failed after recreating cwd"
5861         test_mkdir bar
5862         touch .foo || error "'touch .foo' failed after recreating cwd"
5863         test_mkdir .bar
5864         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5865         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5866         cd . || error "'cd .' failed after recreating cwd"
5867         mkdir . && error "'mkdir .' worked after recreating cwd"
5868         rmdir . && error "'rmdir .' worked after recreating cwd"
5869         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5870         cd .. || error "'cd ..' failed after recreating cwd"
5871 }
5872 run_test 48a "Access renamed working dir (should return errors)="
5873
5874 test_48b() { # bug 2399
5875         rm -rf $DIR/$tdir
5876         test_mkdir $DIR/$tdir
5877         cd $DIR/$tdir
5878         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5879         touch foo && error "'touch foo' worked after removing cwd"
5880         mkdir foo && error "'mkdir foo' worked after removing cwd"
5881         touch .foo && error "'touch .foo' worked after removing cwd"
5882         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5883         ls . > /dev/null && error "'ls .' worked after removing cwd"
5884         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5885         mkdir . && error "'mkdir .' worked after removing cwd"
5886         rmdir . && error "'rmdir .' worked after removing cwd"
5887         ln -s . foo && error "'ln -s .' worked after removing cwd"
5888         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5889 }
5890 run_test 48b "Access removed working dir (should return errors)="
5891
5892 test_48c() { # bug 2350
5893         #lctl set_param debug=-1
5894         #set -vx
5895         rm -rf $DIR/$tdir
5896         test_mkdir -p $DIR/$tdir/dir
5897         cd $DIR/$tdir/dir
5898         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5899         $TRACE touch foo && error "touch foo worked after removing cwd"
5900         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5901         touch .foo && error "touch .foo worked after removing cwd"
5902         mkdir .foo && error "mkdir .foo worked after removing cwd"
5903         $TRACE ls . && error "'ls .' worked after removing cwd"
5904         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5905         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5906         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5907         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5908         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5909 }
5910 run_test 48c "Access removed working subdir (should return errors)"
5911
5912 test_48d() { # bug 2350
5913         #lctl set_param debug=-1
5914         #set -vx
5915         rm -rf $DIR/$tdir
5916         test_mkdir -p $DIR/$tdir/dir
5917         cd $DIR/$tdir/dir
5918         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5919         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5920         $TRACE touch foo && error "'touch foo' worked after removing parent"
5921         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5922         touch .foo && error "'touch .foo' worked after removing parent"
5923         mkdir .foo && error "mkdir .foo worked after removing parent"
5924         $TRACE ls . && error "'ls .' worked after removing parent"
5925         $TRACE ls .. && error "'ls ..' worked after removing parent"
5926         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5927         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5928         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5929         true
5930 }
5931 run_test 48d "Access removed parent subdir (should return errors)"
5932
5933 test_48e() { # bug 4134
5934         #lctl set_param debug=-1
5935         #set -vx
5936         rm -rf $DIR/$tdir
5937         test_mkdir -p $DIR/$tdir/dir
5938         cd $DIR/$tdir/dir
5939         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5940         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5941         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5942         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5943         # On a buggy kernel addition of "touch foo" after cd .. will
5944         # produce kernel oops in lookup_hash_it
5945         touch ../foo && error "'cd ..' worked after recreate parent"
5946         cd $DIR
5947         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5948 }
5949 run_test 48e "Access to recreated parent subdir (should return errors)"
5950
5951 test_48f() {
5952         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5953                 skip "need MDS >= 2.13.55"
5954         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5955         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5956                 skip "needs different host for mdt1 mdt2"
5957         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5958
5959         $LFS mkdir -i0 $DIR/$tdir
5960         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5961
5962         for d in sub1 sub2 sub3; do
5963                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5964                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5965                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5966         done
5967
5968         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5969 }
5970 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5971
5972 test_49() { # LU-1030
5973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5974         remote_ost_nodsh && skip "remote OST with nodsh"
5975
5976         # get ost1 size - $FSNAME-OST0000
5977         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5978                 awk '{ print $4 }')
5979         # write 800M at maximum
5980         [[ $ost1_size -lt 2 ]] && ost1_size=2
5981         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5982
5983         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5984         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5985         local dd_pid=$!
5986
5987         # change max_pages_per_rpc while writing the file
5988         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5989         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5990         # loop until dd process exits
5991         while ps ax -opid | grep -wq $dd_pid; do
5992                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5993                 sleep $((RANDOM % 5 + 1))
5994         done
5995         # restore original max_pages_per_rpc
5996         $LCTL set_param $osc1_mppc=$orig_mppc
5997         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5998 }
5999 run_test 49 "Change max_pages_per_rpc won't break osc extent"
6000
6001 test_50() {
6002         # bug 1485
6003         test_mkdir $DIR/$tdir
6004         cd $DIR/$tdir
6005         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
6006 }
6007 run_test 50 "special situations: /proc symlinks  ==============="
6008
6009 test_51a() {    # was test_51
6010         # bug 1516 - create an empty entry right after ".." then split dir
6011         test_mkdir -c1 $DIR/$tdir
6012         touch $DIR/$tdir/foo
6013         $MCREATE $DIR/$tdir/bar
6014         rm $DIR/$tdir/foo
6015         createmany -m $DIR/$tdir/longfile 201
6016         FNUM=202
6017         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
6018                 $MCREATE $DIR/$tdir/longfile$FNUM
6019                 FNUM=$(($FNUM + 1))
6020                 echo -n "+"
6021         done
6022         echo
6023         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
6024 }
6025 run_test 51a "special situations: split htree with empty entry =="
6026
6027 cleanup_print_lfs_df () {
6028         trap 0
6029         $LFS df
6030         $LFS df -i
6031 }
6032
6033 test_51b() {
6034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6035
6036         local dir=$DIR/$tdir
6037         local nrdirs=$((65536 + 100))
6038
6039         # cleanup the directory
6040         rm -fr $dir
6041
6042         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
6043
6044         $LFS df
6045         $LFS df -i
6046         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
6047         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
6048         [[ $numfree -lt $nrdirs ]] &&
6049                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
6050
6051         # need to check free space for the directories as well
6052         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
6053         numfree=$(( blkfree / $(fs_inode_ksize) ))
6054         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
6055
6056         trap cleanup_print_lfs_df EXIT
6057
6058         # create files
6059         createmany -d $dir/d $nrdirs || {
6060                 unlinkmany $dir/d $nrdirs
6061                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
6062         }
6063
6064         # really created :
6065         nrdirs=$(ls -U $dir | wc -l)
6066
6067         # unlink all but 100 subdirectories, then check it still works
6068         local left=100
6069         local delete=$((nrdirs - left))
6070
6071         $LFS df
6072         $LFS df -i
6073
6074         # for ldiskfs the nlink count should be 1, but this is OSD specific
6075         # and so this is listed for informational purposes only
6076         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
6077         unlinkmany -d $dir/d $delete ||
6078                 error "unlink of first $delete subdirs failed"
6079
6080         echo "nlink between: $(stat -c %h $dir)"
6081         local found=$(ls -U $dir | wc -l)
6082         [ $found -ne $left ] &&
6083                 error "can't find subdirs: found only $found, expected $left"
6084
6085         unlinkmany -d $dir/d $delete $left ||
6086                 error "unlink of second $left subdirs failed"
6087         # regardless of whether the backing filesystem tracks nlink accurately
6088         # or not, the nlink count shouldn't be more than "." and ".." here
6089         local after=$(stat -c %h $dir)
6090         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
6091                 echo "nlink after: $after"
6092
6093         cleanup_print_lfs_df
6094 }
6095 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
6096
6097 test_51d_sub() {
6098         local stripecount=$1
6099         local nfiles=$2
6100
6101         log "create files with stripecount=$stripecount"
6102         $LFS setstripe -C $stripecount $DIR/$tdir
6103         createmany -o $DIR/$tdir/t- $nfiles
6104         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6105         for ((n = 0; n < $OSTCOUNT; n++)); do
6106                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6107                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6108                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6109                             '($1 == '$n') { objs += 1 } \
6110                             END { printf("%0.0f", objs) }')
6111                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6112         done
6113         unlinkmany $DIR/$tdir/t- $nfiles
6114         rm  -f $TMP/$tfile
6115
6116         local nlast
6117         local min=4
6118         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6119
6120         # For some combinations of stripecount and OSTCOUNT current code
6121         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6122         # than others. Rather than skipping this test entirely, check that
6123         # and keep testing to ensure imbalance does not get worse. LU-15282
6124         (( (OSTCOUNT == 6 && stripecount == 4) ||
6125            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6126            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6127         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6128                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6129                         { $LFS df && $LFS df -i &&
6130                         error "stripecount=$stripecount: " \
6131                               "OST $n has fewer objects vs. OST $nlast " \
6132                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6133                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6134                         { $LFS df && $LFS df -i &&
6135                         error "stripecount=$stripecount: " \
6136                               "OST $n has more objects vs. OST $nlast " \
6137                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6138
6139                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6140                         { $LFS df && $LFS df -i &&
6141                         error "stripecount=$stripecount: " \
6142                               "OST $n has fewer #0 objects vs. OST $nlast " \
6143                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6144                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6145                         { $LFS df && $LFS df -i &&
6146                         error "stripecount=$stripecount: " \
6147                               "OST $n has more #0 objects vs. OST $nlast " \
6148                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6149         done
6150 }
6151
6152 test_51d() {
6153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6154         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6155
6156         local stripecount
6157         local per_ost=100
6158         local nfiles=$((per_ost * OSTCOUNT))
6159         local mdts=$(comma_list $(mdts_nodes))
6160         local param="osp.*.create_count"
6161         local qos_old=$(do_facet mds1 \
6162                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6163
6164         do_nodes $mdts \
6165                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6166         stack_trap "do_nodes $mdts \
6167                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6168
6169         test_mkdir $DIR/$tdir
6170         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6171         (( dirstripes > 0 )) || dirstripes=1
6172
6173         # Ensure enough OST objects precreated for tests to pass without
6174         # running out of objects.  This is an LOV r-r OST algorithm test,
6175         # not an OST object precreation test.
6176         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6177         (( old >= nfiles )) ||
6178         {
6179                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6180
6181                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6182                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6183
6184                 # trigger precreation from all MDTs for all OSTs
6185                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6186                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6187                 done
6188         }
6189
6190         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6191                 sleep 8  # allow object precreation to catch up
6192                 test_51d_sub $stripecount $nfiles
6193         done
6194 }
6195 run_test 51d "check LOV round-robin OST object distribution"
6196
6197 test_51e() {
6198         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6199                 skip_env "ldiskfs only test"
6200         fi
6201
6202         test_mkdir -c1 $DIR/$tdir
6203         test_mkdir -c1 $DIR/$tdir/d0
6204
6205         touch $DIR/$tdir/d0/foo
6206         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6207                 error "file exceed 65000 nlink limit!"
6208         unlinkmany $DIR/$tdir/d0/f- 65001
6209         return 0
6210 }
6211 run_test 51e "check file nlink limit"
6212
6213 test_51f() {
6214         test_mkdir $DIR/$tdir
6215
6216         local max=100000
6217         local ulimit_old=$(ulimit -n)
6218         local spare=20 # number of spare fd's for scripts/libraries, etc.
6219         local mdt=$($LFS getstripe -m $DIR/$tdir)
6220         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6221
6222         echo "MDT$mdt numfree=$numfree, max=$max"
6223         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6224         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6225                 while ! ulimit -n $((numfree + spare)); do
6226                         numfree=$((numfree * 3 / 4))
6227                 done
6228                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6229         else
6230                 echo "left ulimit at $ulimit_old"
6231         fi
6232
6233         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6234                 unlinkmany $DIR/$tdir/f $numfree
6235                 error "create+open $numfree files in $DIR/$tdir failed"
6236         }
6237         ulimit -n $ulimit_old
6238
6239         # if createmany exits at 120s there will be fewer than $numfree files
6240         unlinkmany $DIR/$tdir/f $numfree || true
6241 }
6242 run_test 51f "check many open files limit"
6243
6244 test_52a() {
6245         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6246         test_mkdir $DIR/$tdir
6247         touch $DIR/$tdir/foo
6248         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6249         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6250         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6251         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6252         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6253                                         error "link worked"
6254         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6255         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6256         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6257                                                      error "lsattr"
6258         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6259         cp -r $DIR/$tdir $TMP/
6260         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6261 }
6262 run_test 52a "append-only flag test (should return errors)"
6263
6264 test_52b() {
6265         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6266         test_mkdir $DIR/$tdir
6267         touch $DIR/$tdir/foo
6268         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6269         cat test > $DIR/$tdir/foo && error "cat test worked"
6270         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6271         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6272         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6273                                         error "link worked"
6274         echo foo >> $DIR/$tdir/foo && error "echo worked"
6275         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6276         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6277         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6278         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6279                                                         error "lsattr"
6280         chattr -i $DIR/$tdir/foo || error "chattr failed"
6281
6282         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6283 }
6284 run_test 52b "immutable flag test (should return errors) ======="
6285
6286 test_53() {
6287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6288         remote_mds_nodsh && skip "remote MDS with nodsh"
6289         remote_ost_nodsh && skip "remote OST with nodsh"
6290
6291         local param
6292         local param_seq
6293         local ostname
6294         local mds_last
6295         local mds_last_seq
6296         local ost_last
6297         local ost_last_seq
6298         local ost_last_id
6299         local ostnum
6300         local node
6301         local found=false
6302         local support_last_seq=true
6303
6304         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6305                 support_last_seq=false
6306
6307         # only test MDT0000
6308         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6309         local value
6310         for value in $(do_facet $SINGLEMDS \
6311                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6312                 param=$(echo ${value[0]} | cut -d "=" -f1)
6313                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6314
6315                 if $support_last_seq; then
6316                         param_seq=$(echo $param |
6317                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6318                         mds_last_seq=$(do_facet $SINGLEMDS \
6319                                        $LCTL get_param -n $param_seq)
6320                 fi
6321                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6322
6323                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6324                 node=$(facet_active_host ost$((ostnum+1)))
6325                 param="obdfilter.$ostname.last_id"
6326                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6327                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6328                         ost_last_id=$ost_last
6329
6330                         if $support_last_seq; then
6331                                 ost_last_id=$(echo $ost_last |
6332                                               awk -F':' '{print $2}' |
6333                                               sed -e "s/^0x//g")
6334                                 ost_last_seq=$(echo $ost_last |
6335                                                awk -F':' '{print $1}')
6336                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6337                         fi
6338
6339                         if [[ $ost_last_id != $mds_last ]]; then
6340                                 error "$ost_last_id != $mds_last"
6341                         else
6342                                 found=true
6343                                 break
6344                         fi
6345                 done
6346         done
6347         $found || error "can not match last_seq/last_id for $mdtosc"
6348         return 0
6349 }
6350 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6351
6352 test_54a() {
6353         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6354
6355         LANG=C $SOCKETSERVER $DIR/socket ||
6356                 error "$SOCKETSERVER $DIR/socket failed: $?"
6357         LANG=C $SOCKETCLIENT $DIR/socket ||
6358                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6359         unlink $DIR/socket || error "unlink $DIR/socket failed: $?"
6360 }
6361 run_test 54a "unix domain socket test =========================="
6362
6363 test_54b() {
6364         f="$DIR/f54b"
6365         mknod $f c 1 3
6366         chmod 0666 $f
6367         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6368 }
6369 run_test 54b "char device works in lustre ======================"
6370
6371 find_loop_dev() {
6372         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6373         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6374         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6375
6376         for i in $(seq 3 7); do
6377                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6378                 LOOPDEV=$LOOPBASE$i
6379                 LOOPNUM=$i
6380                 break
6381         done
6382 }
6383
6384 cleanup_54c() {
6385         local rc=0
6386         loopdev="$DIR/loop54c"
6387
6388         trap 0
6389         $UMOUNT $DIR/$tdir || rc=$?
6390         losetup -d $loopdev || true
6391         losetup -d $LOOPDEV || true
6392         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6393         return $rc
6394 }
6395
6396 test_54c() {
6397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6398
6399         loopdev="$DIR/loop54c"
6400
6401         find_loop_dev
6402         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6403         trap cleanup_54c EXIT
6404         mknod $loopdev b 7 $LOOPNUM
6405         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6406         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6407         losetup $loopdev $DIR/$tfile ||
6408                 error "can't set up $loopdev for $DIR/$tfile"
6409         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6410         test_mkdir $DIR/$tdir
6411         mount -t ext2 $loopdev $DIR/$tdir ||
6412                 error "error mounting $loopdev on $DIR/$tdir"
6413         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6414                 error "dd write"
6415         df $DIR/$tdir
6416         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6417                 error "dd read"
6418         cleanup_54c
6419 }
6420 run_test 54c "block device works in lustre ====================="
6421
6422 test_54d() {
6423         local pipe="$DIR/$tfile.pipe"
6424         local string="aaaaaa"
6425
6426         mknod $pipe p
6427         echo -n "$string" > $pipe &
6428         local result=$(cat $pipe)
6429         [[ "$result" == "$string" ]] || error "$result != $string"
6430 }
6431 run_test 54d "fifo device works in lustre ======================"
6432
6433 test_54e() {
6434         f="$DIR/f54e"
6435         string="aaaaaa"
6436         cp -aL /dev/console $f
6437         echo $string > $f || error "echo $string to $f failed"
6438 }
6439 run_test 54e "console/tty device works in lustre ======================"
6440
6441 test_55a() {
6442         local dev_path="/sys/kernel/debug/lustre/devices"
6443
6444         load_module kunit/obd_test verbose=2 || error "load_module failed"
6445
6446         # This must be run in iteractive mode, since attach and setup
6447         # are stateful
6448         eval "$LCTL <<-EOF || error 'OBD device creation failed'
6449                 attach obd_test obd_name obd_uuid
6450                 setup obd_test
6451         EOF"
6452
6453         echo "Devices:"
6454         cat "$dev_path" | tail -n 10
6455
6456         $LCTL --device "obd_name" cleanup
6457         $LCTL --device "obd_name" detach
6458
6459         dmesg | tail -n 25 | grep "Lustre: OBD:.*FAIL" &&
6460                 error "OBD unit test failed"
6461
6462         rmmod -v obd_test ||
6463                 error "rmmod failed (may trigger a failure in a later test)"
6464 }
6465 run_test 55a "OBD device life cycle unit tests"
6466
6467 test_55b() {
6468         local dev_path="/sys/kernel/debug/lustre/devices"
6469         local dev_count="$(wc -l $dev_path | awk '{print $1}')"
6470
6471         # Set up a large number of devices, using the number
6472         # that can be set up in about a minute (based on prior
6473         # testing). We don't want to run this test forever.
6474         local num_dev_to_create="$(( 24000 - $dev_count))"
6475
6476         load_module kunit/obd_test || error "load_module failed"
6477
6478         local start=$SECONDS
6479
6480         # This must be run in iteractive mode, since attach and setup
6481         # are stateful
6482         for ((i = 1; i <= num_dev_to_create; i++)); do
6483                 echo "attach obd_test obd_name_$i obd_uuid_$i"
6484                 echo "setup obd_test_$i"
6485         done | $LCTL || error "OBD device creation failed"
6486
6487         echo "Load time: $((SECONDS - start))"
6488         echo "Devices:"
6489         cat "$dev_path" | tail -n 10
6490
6491         for ((i = 1; i <= num_dev_to_create; i++)); do
6492                 echo "--device obd_name_$i cleanup"
6493                 echo "--device obd_name_$i detach"
6494         done | $LCTL || error "OBD device cleanup failed"
6495
6496         echo "Unload time: $((SECONDS - start))"
6497
6498         rmmod -v obd_test ||
6499                 error "rmmod failed (may trigger a failure in a later test)"
6500 }
6501 run_test 55b "Load and unload max OBD devices"
6502
6503 test_56a() {
6504         local numfiles=3
6505         local numdirs=2
6506         local dir=$DIR/$tdir
6507
6508         rm -rf $dir
6509         test_mkdir -p $dir/dir
6510         for i in $(seq $numfiles); do
6511                 touch $dir/file$i
6512                 touch $dir/dir/file$i
6513         done
6514
6515         local numcomp=$($LFS getstripe --component-count $dir)
6516
6517         [[ $numcomp == 0 ]] && numcomp=1
6518
6519         # test lfs getstripe with --recursive
6520         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6521
6522         [[ $filenum -eq $((numfiles * 2)) ]] ||
6523                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6524         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6525         [[ $filenum -eq $numfiles ]] ||
6526                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6527         echo "$LFS getstripe showed obdidx or l_ost_idx"
6528
6529         # test lfs getstripe with file instead of dir
6530         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6531         [[ $filenum -eq 1 ]] ||
6532                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6533         echo "$LFS getstripe file1 passed"
6534
6535         #test lfs getstripe with --verbose
6536         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6537         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6538                 error "$LFS getstripe --verbose $dir: "\
6539                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6540         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6541                 error "$LFS getstripe $dir: showed lmm_magic"
6542
6543         #test lfs getstripe with -v prints lmm_fid
6544         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6545         local countfids=$((numdirs + numfiles * numcomp))
6546         [[ $filenum -eq $countfids ]] ||
6547                 error "$LFS getstripe -v $dir: "\
6548                       "got $filenum want $countfids lmm_fid"
6549         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6550                 error "$LFS getstripe $dir: showed lmm_fid by default"
6551         echo "$LFS getstripe --verbose passed"
6552
6553         #check for FID information
6554         local fid1=$($LFS getstripe --fid $dir/file1)
6555         local fid2=$($LFS getstripe --verbose $dir/file1 |
6556                      awk '/lmm_fid: / { print $2; exit; }')
6557         local fid3=$($LFS path2fid $dir/file1)
6558
6559         [ "$fid1" != "$fid2" ] &&
6560                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6561         [ "$fid1" != "$fid3" ] &&
6562                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6563         echo "$LFS getstripe --fid passed"
6564
6565         #test lfs getstripe with --obd
6566         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6567                 error "$LFS getstripe --obd wrong_uuid: should return error"
6568
6569         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6570
6571         local ostidx=1
6572         local obduuid=$(ostuuid_from_index $ostidx)
6573         local found=$($LFS getstripe -r --obd $obduuid $dir |
6574                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6575
6576         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6577         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6578                 ((filenum--))
6579         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6580                 ((filenum--))
6581
6582         [[ $found -eq $filenum ]] ||
6583                 error "$LFS getstripe --obd: found $found expect $filenum"
6584         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6585                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6586                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6587                 error "$LFS getstripe --obd: should not show file on other obd"
6588         echo "$LFS getstripe --obd passed"
6589 }
6590 run_test 56a "check $LFS getstripe"
6591
6592 test_56b() {
6593         local dir=$DIR/$tdir
6594         local numdirs=3
6595
6596         test_mkdir $dir
6597         for i in $(seq $numdirs); do
6598                 test_mkdir $dir/dir$i
6599         done
6600
6601         # test lfs getdirstripe default mode is non-recursion, which is
6602         # different from lfs getstripe
6603         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6604
6605         [[ $dircnt -eq 1 ]] ||
6606                 error "$LFS getdirstripe: found $dircnt, not 1"
6607         dircnt=$($LFS getdirstripe --recursive $dir |
6608                 grep -c lmv_stripe_count)
6609         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6610                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6611 }
6612 run_test 56b "check $LFS getdirstripe"
6613
6614 test_56bb() {
6615         verify_yaml_available || skip_env "YAML verification not installed"
6616         local output_file=$DIR/$tfile.out
6617
6618         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6619
6620         cat $output_file
6621         cat $output_file | verify_yaml || error "layout is not valid YAML"
6622 }
6623 run_test 56bb "check $LFS getdirstripe layout is YAML"
6624
6625 test_56c() {
6626         remote_ost_nodsh && skip "remote OST with nodsh"
6627
6628         local ost_idx=0
6629         local ost_name=$(ostname_from_index $ost_idx)
6630         local old_status=$(ost_dev_status $ost_idx)
6631         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6632
6633         [[ -z "$old_status" ]] ||
6634                 skip_env "OST $ost_name is in $old_status status"
6635
6636         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6637         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6638                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6639         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6640                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6641                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6642         fi
6643
6644         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6645                 error "$LFS df -v showing inactive devices"
6646         sleep_maxage
6647
6648         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6649
6650         [[ "$new_status" =~ "D" ]] ||
6651                 error "$ost_name status is '$new_status', missing 'D'"
6652         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6653                 [[ "$new_status" =~ "N" ]] ||
6654                         error "$ost_name status is '$new_status', missing 'N'"
6655         fi
6656         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6657                 [[ "$new_status" =~ "f" ]] ||
6658                         error "$ost_name status is '$new_status', missing 'f'"
6659         fi
6660
6661         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6662         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6663                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6664         [[ -z "$p" ]] && restore_lustre_params < $p || true
6665         sleep_maxage
6666
6667         new_status=$(ost_dev_status $ost_idx)
6668         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6669                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6670         # can't check 'f' as devices may actually be on flash
6671 }
6672 run_test 56c "check 'lfs df' showing device status"
6673
6674 test_56d() {
6675         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6676         local osts=$($LFS df -v $MOUNT | grep -c OST)
6677
6678         $LFS df $MOUNT
6679
6680         (( mdts == MDSCOUNT )) ||
6681                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6682         (( osts == OSTCOUNT )) ||
6683                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6684 }
6685 run_test 56d "'lfs df -v' prints only configured devices"
6686
6687 test_56e() {
6688         err_enoent=2 # No such file or directory
6689         err_eopnotsupp=95 # Operation not supported
6690
6691         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6692         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6693
6694         # Check for handling of path not exists
6695         output=$($LFS df $enoent_mnt 2>&1)
6696         ret=$?
6697
6698         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6699         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6700                 error "expect failure $err_enoent, not $ret"
6701
6702         # Check for handling of non-Lustre FS
6703         output=$($LFS df $notsup_mnt)
6704         ret=$?
6705
6706         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6707         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6708                 error "expect success $err_eopnotsupp, not $ret"
6709
6710         # Check for multiple LustreFS argument
6711         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6712         ret=$?
6713
6714         [[ $output -eq 3 && $ret -eq 0 ]] ||
6715                 error "expect success 3, not $output, rc = $ret"
6716
6717         # Check for correct non-Lustre FS handling among multiple
6718         # LustreFS argument
6719         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6720                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6721         ret=$?
6722
6723         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6724                 error "expect success 2, not $output, rc = $ret"
6725 }
6726 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6727
6728 NUMFILES=3
6729 NUMDIRS=3
6730 setup_56() {
6731         local local_tdir="$1"
6732         local local_numfiles="$2"
6733         local local_numdirs="$3"
6734         local dir_params="$4"
6735         local dir_stripe_params="$5"
6736
6737         if [ ! -d "$local_tdir" ] ; then
6738                 test_mkdir -p $dir_stripe_params $local_tdir
6739                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6740                 for i in $(seq $local_numfiles) ; do
6741                         touch $local_tdir/file$i
6742                 done
6743                 for i in $(seq $local_numdirs) ; do
6744                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6745                         for j in $(seq $local_numfiles) ; do
6746                                 touch $local_tdir/dir$i/file$j
6747                         done
6748                 done
6749         fi
6750 }
6751
6752 setup_56_special() {
6753         local local_tdir=$1
6754         local local_numfiles=$2
6755         local local_numdirs=$3
6756
6757         setup_56 $local_tdir $local_numfiles $local_numdirs
6758
6759         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6760                 for i in $(seq $local_numfiles) ; do
6761                         mknod $local_tdir/loop${i}b b 7 $i
6762                         mknod $local_tdir/null${i}c c 1 3
6763                         ln -s $local_tdir/file1 $local_tdir/link${i}
6764                 done
6765                 for i in $(seq $local_numdirs) ; do
6766                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6767                         mknod $local_tdir/dir$i/null${i}c c 1 3
6768                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6769                 done
6770         fi
6771 }
6772
6773 test_56g() {
6774         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6775         local expected=$(($NUMDIRS + 2))
6776
6777         setup_56 $dir $NUMFILES $NUMDIRS
6778
6779         # test lfs find with -name
6780         for i in $(seq $NUMFILES) ; do
6781                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6782
6783                 [ $nums -eq $expected ] ||
6784                         error "lfs find -name '*$i' $dir wrong: "\
6785                               "found $nums, expected $expected"
6786         done
6787 }
6788 run_test 56g "check lfs find -name"
6789
6790 test_56h() {
6791         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6792         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6793
6794         setup_56 $dir $NUMFILES $NUMDIRS
6795
6796         # test lfs find with ! -name
6797         for i in $(seq $NUMFILES) ; do
6798                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6799
6800                 [ $nums -eq $expected ] ||
6801                         error "lfs find ! -name '*$i' $dir wrong: "\
6802                               "found $nums, expected $expected"
6803         done
6804 }
6805 run_test 56h "check lfs find ! -name"
6806
6807 test_56i() {
6808         local dir=$DIR/$tdir
6809
6810         test_mkdir $dir
6811
6812         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6813         local out=$($cmd)
6814
6815         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6816 }
6817 run_test 56i "check 'lfs find -ost UUID' skips directories"
6818
6819 test_56j() {
6820         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6821
6822         setup_56_special $dir $NUMFILES $NUMDIRS
6823
6824         local expected=$((NUMDIRS + 1))
6825         local cmd="$LFS find -type d $dir"
6826         local nums=$($cmd | wc -l)
6827
6828         [ $nums -eq $expected ] ||
6829                 error "'$cmd' wrong: found $nums, expected $expected"
6830 }
6831 run_test 56j "check lfs find -type d"
6832
6833 test_56k() {
6834         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6835
6836         setup_56_special $dir $NUMFILES $NUMDIRS
6837
6838         local expected=$(((NUMDIRS + 1) * NUMFILES))
6839         local cmd="$LFS find -type f $dir"
6840         local nums=$($cmd | wc -l)
6841
6842         [ $nums -eq $expected ] ||
6843                 error "'$cmd' wrong: found $nums, expected $expected"
6844 }
6845 run_test 56k "check lfs find -type f"
6846
6847 test_56l() {
6848         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6849
6850         setup_56_special $dir $NUMFILES $NUMDIRS
6851
6852         local expected=$((NUMDIRS + NUMFILES))
6853         local cmd="$LFS find -type b $dir"
6854         local nums=$($cmd | wc -l)
6855
6856         [ $nums -eq $expected ] ||
6857                 error "'$cmd' wrong: found $nums, expected $expected"
6858 }
6859 run_test 56l "check lfs find -type b"
6860
6861 test_56m() {
6862         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6863
6864         setup_56_special $dir $NUMFILES $NUMDIRS
6865
6866         local expected=$((NUMDIRS + NUMFILES))
6867         local cmd="$LFS find -type c $dir"
6868         local nums=$($cmd | wc -l)
6869         [ $nums -eq $expected ] ||
6870                 error "'$cmd' wrong: found $nums, expected $expected"
6871 }
6872 run_test 56m "check lfs find -type c"
6873
6874 test_56n() {
6875         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6876         setup_56_special $dir $NUMFILES $NUMDIRS
6877
6878         local expected=$((NUMDIRS + NUMFILES))
6879         local cmd="$LFS find -type l $dir"
6880         local nums=$($cmd | wc -l)
6881
6882         [ $nums -eq $expected ] ||
6883                 error "'$cmd' wrong: found $nums, expected $expected"
6884 }
6885 run_test 56n "check lfs find -type l"
6886
6887 test_56o() {
6888         local dir=$DIR/$tdir
6889
6890         setup_56 $dir $NUMFILES $NUMDIRS
6891         utime $dir/file1 > /dev/null || error "utime (1)"
6892         utime $dir/file2 > /dev/null || error "utime (2)"
6893         utime $dir/dir1 > /dev/null || error "utime (3)"
6894         utime $dir/dir2 > /dev/null || error "utime (4)"
6895         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6896         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6897
6898         local expected=4
6899         local nums=$($LFS find -mtime +0 $dir | wc -l)
6900
6901         [ $nums -eq $expected ] ||
6902                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6903
6904         expected=12
6905         cmd="$LFS find -mtime 0 $dir"
6906         nums=$($cmd | wc -l)
6907         [ $nums -eq $expected ] ||
6908                 error "'$cmd' wrong: found $nums, expected $expected"
6909 }
6910 run_test 56o "check lfs find -mtime for old files"
6911
6912 test_56ob() {
6913         local dir=$DIR/$tdir
6914         local expected=1
6915         local count=0
6916
6917         # just to make sure there is something that won't be found
6918         test_mkdir $dir
6919         touch $dir/$tfile.now
6920
6921         for age in year week day hour min; do
6922                 count=$((count + 1))
6923
6924                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6925                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6926                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6927
6928                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6929                 local nums=$($cmd | wc -l)
6930                 [ $nums -eq $expected ] ||
6931                         error "'$cmd' wrong: found $nums, expected $expected"
6932
6933                 cmd="$LFS find $dir -atime $count${age:0:1}"
6934                 nums=$($cmd | wc -l)
6935                 [ $nums -eq $expected ] ||
6936                         error "'$cmd' wrong: found $nums, expected $expected"
6937         done
6938
6939         sleep 2
6940         cmd="$LFS find $dir -ctime +1s -type f"
6941         nums=$($cmd | wc -l)
6942         (( $nums == $count * 2 + 1)) ||
6943                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6944 }
6945 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6946
6947 test_newerXY_base() {
6948         local x=$1
6949         local y=$2
6950         local dir=$DIR/$tdir
6951         local ref
6952         local negref
6953
6954         if [ $y == "t" ]; then
6955                 if [ $x == "b" ]; then
6956                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6957                 else
6958                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6959                 fi
6960         else
6961                 ref=$DIR/$tfile.newer.$x$y
6962                 touch $ref || error "touch $ref failed"
6963         fi
6964
6965         echo "before = $ref"
6966         sleep 2
6967         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6968         sleep 2
6969         if [ $y == "t" ]; then
6970                 if [ $x == "b" ]; then
6971                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6972                 else
6973                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6974                 fi
6975         else
6976                 negref=$DIR/$tfile.negnewer.$x$y
6977                 touch $negref || error "touch $negref failed"
6978         fi
6979
6980         echo "after = $negref"
6981         local cmd="$LFS find $dir -newer$x$y $ref"
6982         local nums=$(eval $cmd | wc -l)
6983         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6984
6985         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6986                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6987
6988         cmd="$LFS find $dir ! -newer$x$y $negref"
6989         nums=$(eval $cmd | wc -l)
6990         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6991                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6992
6993         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6994         nums=$(eval $cmd | wc -l)
6995         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6996                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6997
6998         rm -rf $DIR/*
6999 }
7000
7001 test_56oc() {
7002         test_newerXY_base "a" "a"
7003         test_newerXY_base "a" "m"
7004         test_newerXY_base "a" "c"
7005         test_newerXY_base "m" "a"
7006         test_newerXY_base "m" "m"
7007         test_newerXY_base "m" "c"
7008         test_newerXY_base "c" "a"
7009         test_newerXY_base "c" "m"
7010         test_newerXY_base "c" "c"
7011
7012         test_newerXY_base "a" "t"
7013         test_newerXY_base "m" "t"
7014         test_newerXY_base "c" "t"
7015
7016         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) &&
7017            $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7018                 { echo "btime needs v2_13_53-145-g186b97e68a"; return 0; }
7019
7020         test_newerXY_base "b" "b"
7021         test_newerXY_base "b" "t"
7022 }
7023 run_test 56oc "check lfs find -newerXY work"
7024
7025 test_56od() {
7026         (( $MDS1_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7027                 skip "btime unsupported on MDS < v2_13_53-145-g186b97e68a"
7028
7029         (( $CLIENT_VERSION >= $(version_code v2_13_53-145-g186b97e68a) )) ||
7030                 skip "btime unsupported on clients < v2_13_53-145-g186b97e68a"
7031
7032         local dir=$DIR/$tdir
7033         local ref=$DIR/$tfile.ref
7034         local negref=$DIR/$tfile.negref
7035
7036         mkdir $dir || error "mkdir $dir failed"
7037         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
7038         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
7039         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
7040         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
7041         touch $ref || error "touch $ref failed"
7042         # sleep 3 seconds at least
7043         sleep 3
7044
7045         local before=$(do_facet mds1 date +%s)
7046         local skew=$(($(date +%s) - before + 1))
7047
7048         if (( skew < 0 && skew > -5 )); then
7049                 sleep $((0 - skew + 1))
7050                 skew=0
7051         fi
7052
7053         # Set the dir stripe params to limit files all on MDT0,
7054         # otherwise we need to calc the max clock skew between
7055         # the client and MDTs.
7056         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
7057         sleep 2
7058         touch $negref || error "touch $negref failed"
7059
7060         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
7061         local nums=$($cmd | wc -l)
7062         local expected=$(((NUMFILES + 1) * NUMDIRS))
7063
7064         [ $nums -eq $expected ] ||
7065                 error "'$cmd' wrong: found $nums, expected $expected"
7066
7067         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
7068         nums=$($cmd | wc -l)
7069         expected=$((NUMFILES + 1))
7070         [ $nums -eq $expected ] ||
7071                 error "'$cmd' wrong: found $nums, expected $expected"
7072
7073         [ $skew -lt 0 ] && return
7074
7075         local after=$(do_facet mds1 date +%s)
7076         local age=$((after - before + 1 + skew))
7077
7078         cmd="$LFS find $dir -btime -${age}s -type f"
7079         nums=$($cmd | wc -l)
7080         expected=$(((NUMFILES + 1) * NUMDIRS))
7081
7082         echo "Clock skew between client and server: $skew, age:$age"
7083         [ $nums -eq $expected ] ||
7084                 error "'$cmd' wrong: found $nums, expected $expected"
7085
7086         expected=$(($NUMDIRS + 1))
7087         cmd="$LFS find $dir -btime -${age}s -type d"
7088         nums=$($cmd | wc -l)
7089         [ $nums -eq $expected ] ||
7090                 error "'$cmd' wrong: found $nums, expected $expected"
7091         rm -f $ref $negref || error "Failed to remove $ref $negref"
7092 }
7093 run_test 56od "check lfs find -btime with units"
7094
7095 test_56p() {
7096         [ $RUNAS_ID -eq $UID ] &&
7097                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7098
7099         local dir=$DIR/$tdir
7100
7101         setup_56 $dir $NUMFILES $NUMDIRS
7102         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
7103
7104         local expected=$NUMFILES
7105         local cmd="$LFS find -uid $RUNAS_ID $dir"
7106         local nums=$($cmd | wc -l)
7107
7108         [ $nums -eq $expected ] ||
7109                 error "'$cmd' wrong: found $nums, expected $expected"
7110
7111         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
7112         cmd="$LFS find ! -uid $RUNAS_ID $dir"
7113         nums=$($cmd | wc -l)
7114         [ $nums -eq $expected ] ||
7115                 error "'$cmd' wrong: found $nums, expected $expected"
7116 }
7117 run_test 56p "check lfs find -uid and ! -uid"
7118
7119 test_56q() {
7120         [ $RUNAS_ID -eq $UID ] &&
7121                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7122
7123         local dir=$DIR/$tdir
7124
7125         setup_56 $dir $NUMFILES $NUMDIRS
7126         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
7127
7128         local expected=$NUMFILES
7129         local cmd="$LFS find -gid $RUNAS_GID $dir"
7130         local nums=$($cmd | wc -l)
7131
7132         [ $nums -eq $expected ] ||
7133                 error "'$cmd' wrong: found $nums, expected $expected"
7134
7135         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
7136         cmd="$LFS find ! -gid $RUNAS_GID $dir"
7137         nums=$($cmd | wc -l)
7138         [ $nums -eq $expected ] ||
7139                 error "'$cmd' wrong: found $nums, expected $expected"
7140 }
7141 run_test 56q "check lfs find -gid and ! -gid"
7142
7143 test_56r() {
7144         local dir=$DIR/$tdir
7145
7146         setup_56 $dir $NUMFILES $NUMDIRS
7147
7148         local expected=12
7149         local cmd="$LFS find -size 0 -type f -lazy $dir"
7150         local nums=$($cmd | wc -l)
7151
7152         [ $nums -eq $expected ] ||
7153                 error "'$cmd' wrong: found $nums, expected $expected"
7154         cmd="$LFS find -size 0 -type f $dir"
7155         nums=$($cmd | wc -l)
7156         [ $nums -eq $expected ] ||
7157                 error "'$cmd' wrong: found $nums, expected $expected"
7158
7159         expected=0
7160         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7161         nums=$($cmd | wc -l)
7162         [ $nums -eq $expected ] ||
7163                 error "'$cmd' wrong: found $nums, expected $expected"
7164         cmd="$LFS find ! -size 0 -type f $dir"
7165         nums=$($cmd | wc -l)
7166         [ $nums -eq $expected ] ||
7167                 error "'$cmd' wrong: found $nums, expected $expected"
7168
7169         echo "test" > $dir/$tfile
7170         echo "test2" > $dir/$tfile.2 && sync
7171         expected=1
7172         cmd="$LFS find -size 5c -type f -lazy $dir"
7173         nums=$($cmd | wc -l)
7174         [ $nums -eq $expected ] ||
7175                 error "'$cmd' wrong: found $nums, expected $expected"
7176         cmd="$LFS find -size 5c -type f $dir"
7177         nums=$($cmd | wc -l)
7178         [ $nums -eq $expected ] ||
7179                 error "'$cmd' wrong: found $nums, expected $expected"
7180
7181         expected=1
7182         cmd="$LFS find -size +5c -type f -lazy $dir"
7183         nums=$($cmd | wc -l)
7184         [ $nums -eq $expected ] ||
7185                 error "'$cmd' wrong: found $nums, expected $expected"
7186         cmd="$LFS find -size +5c -type f $dir"
7187         nums=$($cmd | wc -l)
7188         [ $nums -eq $expected ] ||
7189                 error "'$cmd' wrong: found $nums, expected $expected"
7190
7191         expected=2
7192         cmd="$LFS find -size +0 -type f -lazy $dir"
7193         nums=$($cmd | wc -l)
7194         [ $nums -eq $expected ] ||
7195                 error "'$cmd' wrong: found $nums, expected $expected"
7196         cmd="$LFS find -size +0 -type f $dir"
7197         nums=$($cmd | wc -l)
7198         [ $nums -eq $expected ] ||
7199                 error "'$cmd' wrong: found $nums, expected $expected"
7200
7201         expected=2
7202         cmd="$LFS find ! -size -5c -type f -lazy $dir"
7203         nums=$($cmd | wc -l)
7204         [ $nums -eq $expected ] ||
7205                 error "'$cmd' wrong: found $nums, expected $expected"
7206         cmd="$LFS find ! -size -5c -type f $dir"
7207         nums=$($cmd | wc -l)
7208         [ $nums -eq $expected ] ||
7209                 error "'$cmd' wrong: found $nums, expected $expected"
7210
7211         expected=12
7212         cmd="$LFS find -size -5c -type f -lazy $dir"
7213         nums=$($cmd | wc -l)
7214         [ $nums -eq $expected ] ||
7215                 error "'$cmd' wrong: found $nums, expected $expected"
7216         cmd="$LFS find -size -5c -type f $dir"
7217         nums=$($cmd | wc -l)
7218         [ $nums -eq $expected ] ||
7219                 error "'$cmd' wrong: found $nums, expected $expected"
7220 }
7221 run_test 56r "check lfs find -size works"
7222
7223 test_56ra_sub() {
7224         local expected=$1
7225         local glimpses=$2
7226         local cmd="$3"
7227
7228         cancel_lru_locks $OSC
7229
7230         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7231         local nums=$($cmd | wc -l)
7232
7233         [ $nums -eq $expected ] ||
7234                 error "'$cmd' wrong: found $nums, expected $expected"
7235
7236         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7237
7238         if (( rpcs_before + glimpses != rpcs_after )); then
7239                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7240                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7241
7242                 if [[ $glimpses == 0 ]]; then
7243                         error "'$cmd' should not send glimpse RPCs to OST"
7244                 else
7245                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7246                 fi
7247         fi
7248 }
7249
7250 test_56ra() {
7251         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7252                 skip "MDS < 2.12.58 doesn't return LSOM data"
7253         local dir=$DIR/$tdir
7254         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7255
7256         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7257
7258         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7259         $LCTL set_param -n llite.*.statahead_agl=0
7260         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7261
7262         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7263         # open and close all files to ensure LSOM is updated
7264         cancel_lru_locks $OSC
7265         find $dir -type f | xargs cat > /dev/null
7266
7267         #   expect_found  glimpse_rpcs  command_to_run
7268         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7269         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7270         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7271         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7272
7273         echo "test" > $dir/$tfile
7274         echo "test2" > $dir/$tfile.2 && sync
7275         cancel_lru_locks $OSC
7276         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7277
7278         test_56ra_sub  1  0 "$LFS find -size 5c -type f -lazy $dir"
7279         test_56ra_sub  1 14 "$LFS find -size 5c -type f $dir"
7280         test_56ra_sub  1  0 "$LFS find -size +5c -type f -lazy $dir"
7281         test_56ra_sub  1 14 "$LFS find -size +5c -type f $dir"
7282
7283         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7284         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7285         test_56ra_sub  2  0 "$LFS find ! -size -5c -type f -lazy $dir"
7286         test_56ra_sub  2 14 "$LFS find ! -size -5c -type f $dir"
7287         test_56ra_sub 12  0 "$LFS find -size -5c -type f -lazy $dir"
7288         test_56ra_sub 12 14 "$LFS find -size -5c -type f $dir"
7289 }
7290 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7291
7292 test_56rb() {
7293         local dir=$DIR/$tdir
7294         local tmp=$TMP/$tfile.log
7295         local mdt_idx;
7296
7297         test_mkdir -p $dir || error "failed to mkdir $dir"
7298         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7299                 error "failed to setstripe $dir/$tfile"
7300         mdt_idx=$($LFS getdirstripe -i $dir)
7301         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7302
7303         stack_trap "rm -f $tmp" EXIT
7304         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7305         ! grep -q obd_uuid $tmp ||
7306                 error "failed to find --size +100K --ost 0 $dir"
7307         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7308         ! grep -q obd_uuid $tmp ||
7309                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7310 }
7311 run_test 56rb "check lfs find --size --ost/--mdt works"
7312
7313 test_56rc() {
7314         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7315         local dir=$DIR/$tdir
7316         local found
7317
7318         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7319         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7320         (( $MDSCOUNT > 2 )) &&
7321                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7322         mkdir $dir/$tdir-{1..10}
7323         touch $dir/$tfile-{1..10}
7324
7325         found=$($LFS find $dir --mdt-count 2 | wc -l)
7326         expect=11
7327         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7328
7329         found=$($LFS find $dir -T +1 | wc -l)
7330         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7331         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7332
7333         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7334         expect=11
7335         (( $found == $expect )) || error "found $found all_char, expect $expect"
7336
7337         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7338         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7339         (( $found == $expect )) || error "found $found all_char, expect $expect"
7340 }
7341 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7342
7343 test_56rd() {
7344         local dir=$DIR/$tdir
7345
7346         test_mkdir $dir
7347         rm -f $dir/*
7348
7349         mkfifo $dir/fifo || error "failed to create fifo file"
7350         $LFS find $dir -t p --printf "%p %y %LP\n" ||
7351                 error "should not fail even cannot get projid from pipe file"
7352         found=$($LFS find $dir -t p --printf "%y")
7353         [[ "p" == $found ]] || error "found $found, expect p"
7354
7355         mknod $dir/chardev c 1 5 ||
7356                 error "failed to create character device file"
7357         $LFS find $dir -t c --printf "%p %y %LP\n" ||
7358                 error "should not fail even cannot get projid from chardev file"
7359         found=$($LFS find $dir -t c --printf "%y")
7360         [[ "c" == $found ]] || error "found $found, expect c"
7361
7362         found=$($LFS find $dir ! -type d --printf "%p %y %LP\n" | wc -l)
7363         (( found == 2 )) || error "unable to list all files"
7364 }
7365 run_test 56rd "check lfs find --printf special files"
7366
7367 test_56s() { # LU-611 #LU-9369
7368         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7369
7370         local dir=$DIR/$tdir
7371         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7372
7373         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7374         for i in $(seq $NUMDIRS); do
7375                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7376         done
7377
7378         local expected=$NUMDIRS
7379         local cmd="$LFS find -c $OSTCOUNT $dir"
7380         local nums=$($cmd | wc -l)
7381
7382         [ $nums -eq $expected ] || {
7383                 $LFS getstripe -R $dir
7384                 error "'$cmd' wrong: found $nums, expected $expected"
7385         }
7386
7387         expected=$((NUMDIRS + onestripe))
7388         cmd="$LFS find -stripe-count +0 -type f $dir"
7389         nums=$($cmd | wc -l)
7390         [ $nums -eq $expected ] || {
7391                 $LFS getstripe -R $dir
7392                 error "'$cmd' wrong: found $nums, expected $expected"
7393         }
7394
7395         expected=$onestripe
7396         cmd="$LFS find -stripe-count 1 -type f $dir"
7397         nums=$($cmd | wc -l)
7398         [ $nums -eq $expected ] || {
7399                 $LFS getstripe -R $dir
7400                 error "'$cmd' wrong: found $nums, expected $expected"
7401         }
7402
7403         cmd="$LFS find -stripe-count -2 -type f $dir"
7404         nums=$($cmd | wc -l)
7405         [ $nums -eq $expected ] || {
7406                 $LFS getstripe -R $dir
7407                 error "'$cmd' wrong: found $nums, expected $expected"
7408         }
7409
7410         expected=0
7411         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7412         nums=$($cmd | wc -l)
7413         [ $nums -eq $expected ] || {
7414                 $LFS getstripe -R $dir
7415                 error "'$cmd' wrong: found $nums, expected $expected"
7416         }
7417 }
7418 run_test 56s "check lfs find -stripe-count works"
7419
7420 test_56t() { # LU-611 #LU-9369
7421         local dir=$DIR/$tdir
7422
7423         setup_56 $dir 0 $NUMDIRS
7424         for i in $(seq $NUMDIRS); do
7425                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7426         done
7427
7428         local expected=$NUMDIRS
7429         local cmd="$LFS find -S 8M $dir"
7430         local nums=$($cmd | wc -l)
7431
7432         [ $nums -eq $expected ] || {
7433                 $LFS getstripe -R $dir
7434                 error "'$cmd' wrong: found $nums, expected $expected"
7435         }
7436         rm -rf $dir
7437
7438         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7439
7440         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7441
7442         expected=$(((NUMDIRS + 1) * NUMFILES))
7443         cmd="$LFS find -stripe-size 512k -type f $dir"
7444         nums=$($cmd | wc -l)
7445         [ $nums -eq $expected ] ||
7446                 error "'$cmd' wrong: found $nums, expected $expected"
7447
7448         cmd="$LFS find -stripe-size +320k -type f $dir"
7449         nums=$($cmd | wc -l)
7450         [ $nums -eq $expected ] ||
7451                 error "'$cmd' wrong: found $nums, expected $expected"
7452
7453         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7454         cmd="$LFS find -stripe-size +200k -type f $dir"
7455         nums=$($cmd | wc -l)
7456         [ $nums -eq $expected ] ||
7457                 error "'$cmd' wrong: found $nums, expected $expected"
7458
7459         cmd="$LFS find -stripe-size -640k -type f $dir"
7460         nums=$($cmd | wc -l)
7461         [ $nums -eq $expected ] ||
7462                 error "'$cmd' wrong: found $nums, expected $expected"
7463
7464         expected=4
7465         cmd="$LFS find -stripe-size 256k -type f $dir"
7466         nums=$($cmd | wc -l)
7467         [ $nums -eq $expected ] ||
7468                 error "'$cmd' wrong: found $nums, expected $expected"
7469
7470         cmd="$LFS find -stripe-size -320k -type f $dir"
7471         nums=$($cmd | wc -l)
7472         [ $nums -eq $expected ] ||
7473                 error "'$cmd' wrong: found $nums, expected $expected"
7474
7475         expected=0
7476         cmd="$LFS find -stripe-size 1024k -type f $dir"
7477         nums=$($cmd | wc -l)
7478         [ $nums -eq $expected ] ||
7479                 error "'$cmd' wrong: found $nums, expected $expected"
7480 }
7481 run_test 56t "check lfs find -stripe-size works"
7482
7483 test_56u() { # LU-611
7484         local dir=$DIR/$tdir
7485
7486         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7487
7488         if [[ $OSTCOUNT -gt 1 ]]; then
7489                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7490                 onestripe=4
7491         else
7492                 onestripe=0
7493         fi
7494
7495         local expected=$(((NUMDIRS + 1) * NUMFILES))
7496         local cmd="$LFS find -stripe-index 0 -type f $dir"
7497         local nums=$($cmd | wc -l)
7498
7499         [ $nums -eq $expected ] ||
7500                 error "'$cmd' wrong: found $nums, expected $expected"
7501
7502         expected=$onestripe
7503         cmd="$LFS find -stripe-index 1 -type f $dir"
7504         nums=$($cmd | wc -l)
7505         [ $nums -eq $expected ] ||
7506                 error "'$cmd' wrong: found $nums, expected $expected"
7507
7508         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7509         nums=$($cmd | wc -l)
7510         [ $nums -eq $expected ] ||
7511                 error "'$cmd' wrong: found $nums, expected $expected"
7512
7513         expected=0
7514         # This should produce an error and not return any files
7515         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7516         nums=$($cmd 2>/dev/null | wc -l)
7517         [ $nums -eq $expected ] ||
7518                 error "'$cmd' wrong: found $nums, expected $expected"
7519
7520         if [[ $OSTCOUNT -gt 1 ]]; then
7521                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7522                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7523                 nums=$($cmd | wc -l)
7524                 [ $nums -eq $expected ] ||
7525                         error "'$cmd' wrong: found $nums, expected $expected"
7526         fi
7527 }
7528 run_test 56u "check lfs find -stripe-index works"
7529
7530 test_56v() {
7531         local mdt_idx=0
7532         local dir=$DIR/$tdir
7533
7534         setup_56 $dir $NUMFILES $NUMDIRS
7535
7536         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7537         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7538
7539         for file in $($LFS find -m $UUID $dir); do
7540                 file_midx=$($LFS getstripe -m $file)
7541                 [ $file_midx -eq $mdt_idx ] ||
7542                         error "lfs find -m $UUID != getstripe -m $file_midx"
7543         done
7544 }
7545 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7546
7547 test_56wa() {
7548         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7550
7551         local dir=$DIR/$tdir
7552
7553         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7554         stack_trap "rm -rf $dir"
7555
7556         local stripe_size=$($LFS getstripe -S -d $dir) ||
7557                 error "$LFS getstripe -S -d $dir failed"
7558         stripe_size=${stripe_size%% *}
7559
7560         local file_size=$((stripe_size * OSTCOUNT))
7561         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7562         local required_space=$((file_num * file_size))
7563         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7564                            head -n1)
7565         (( free_space >= required_space / 1024 )) ||
7566                 skip_env "need $required_space, have $free_space kbytes"
7567
7568         local dd_bs=65536
7569         local dd_count=$((file_size / dd_bs))
7570
7571         # write data into the files
7572         local i
7573         local j
7574         local file
7575
7576         for ((i = 1; i <= NUMFILES; i++ )); do
7577                 file=$dir/file$i
7578                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7579                         error "write data into $file failed"
7580         done
7581         for ((i = 1; i <= NUMDIRS; i++ )); do
7582                 for ((j = 1; j <= NUMFILES; j++ )); do
7583                         file=$dir/dir$i/file$j
7584                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7585                                 error "write data into $file failed"
7586                 done
7587         done
7588
7589         # $LFS_MIGRATE will fail if hard link migration is unsupported
7590         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7591                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7592                         error "creating links to $dir/dir1/file1 failed"
7593         fi
7594
7595         local expected=-1
7596
7597         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7598
7599         # lfs_migrate file
7600         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7601
7602         echo "$cmd"
7603         eval $cmd || error "$cmd failed"
7604
7605         check_stripe_count $dir/file1 $expected
7606
7607         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7608                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7609                 # OST 1 if it is on OST 0. This file is small enough to
7610                 # be on only one stripe.
7611                 file=$dir/migr_1_ost
7612                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7613                         error "write data into $file failed"
7614                 local obdidx=$($LFS getstripe -i $file)
7615                 local oldmd5=$(md5sum $file)
7616                 local newobdidx=0
7617
7618                 (( obdidx != 0 )) || newobdidx=1
7619                 cmd="$LFS migrate -i $newobdidx $file"
7620                 echo $cmd
7621                 eval $cmd || error "$cmd failed"
7622
7623                 local realobdix=$($LFS getstripe -i $file)
7624                 local newmd5=$(md5sum $file)
7625
7626                 (( $newobdidx == $realobdix )) ||
7627                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7628                 [[ "$oldmd5" == "$newmd5" ]] ||
7629                         error "md5sum differ: $oldmd5, $newmd5"
7630         fi
7631
7632         # lfs_migrate dir
7633         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7634         echo "$cmd"
7635         eval $cmd || error "$cmd failed"
7636
7637         for (( j = 1; j <= NUMFILES; j++ )); do
7638                 check_stripe_count $dir/dir1/file$j $expected
7639         done
7640
7641         # lfs_migrate works with lfs find
7642         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7643              $LFS_MIGRATE -y -c $expected"
7644         echo "$cmd"
7645         eval $cmd || error "$cmd failed"
7646
7647         for (( i = 2; i <= NUMFILES; i++ )); do
7648                 check_stripe_count $dir/file$i $expected
7649         done
7650         for (( i = 2; i <= NUMDIRS; i++ )); do
7651                 for (( j = 1; j <= NUMFILES; j++ )); do
7652                         check_stripe_count $dir/dir$i/file$j $expected
7653                 done
7654         done
7655 }
7656 run_test 56wa "check lfs_migrate -c stripe_count works"
7657
7658 test_56wb() {
7659         local file1=$DIR/$tdir/file1
7660         local create_pool=false
7661         local initial_pool=$($LFS getstripe -p $DIR)
7662         local pool_list=()
7663         local pool=""
7664
7665         echo -n "Creating test dir..."
7666         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7667         echo "done."
7668
7669         echo -n "Creating test file..."
7670         touch $file1 || error "cannot create file"
7671         echo "done."
7672
7673         echo -n "Detecting existing pools..."
7674         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7675
7676         if [ ${#pool_list[@]} -gt 0 ]; then
7677                 echo "${pool_list[@]}"
7678                 for thispool in "${pool_list[@]}"; do
7679                         if [[ -z "$initial_pool" ||
7680                               "$initial_pool" != "$thispool" ]]; then
7681                                 pool="$thispool"
7682                                 echo "Using existing pool '$pool'"
7683                                 break
7684                         fi
7685                 done
7686         else
7687                 echo "none detected."
7688         fi
7689         if [ -z "$pool" ]; then
7690                 pool=${POOL:-testpool}
7691                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7692                 echo -n "Creating pool '$pool'..."
7693                 create_pool=true
7694                 pool_add $pool &> /dev/null ||
7695                         error "pool_add failed"
7696                 echo "done."
7697
7698                 echo -n "Adding target to pool..."
7699                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7700                         error "pool_add_targets failed"
7701                 echo "done."
7702         fi
7703
7704         echo -n "Setting pool using -p option..."
7705         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7706                 error "migrate failed rc = $?"
7707         echo "done."
7708
7709         echo -n "Verifying test file is in pool after migrating..."
7710         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7711                 error "file was not migrated to pool $pool"
7712         echo "done."
7713
7714         echo -n "Removing test file from pool '$pool'..."
7715         # "lfs migrate $file" won't remove the file from the pool
7716         # until some striping information is changed.
7717         $LFS migrate -c 1 $file1 &> /dev/null ||
7718                 error "cannot remove from pool"
7719         [ "$($LFS getstripe -p $file1)" ] &&
7720                 error "pool still set"
7721         echo "done."
7722
7723         echo -n "Setting pool using --pool option..."
7724         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7725                 error "migrate failed rc = $?"
7726         echo "done."
7727
7728         # Clean up
7729         rm -f $file1
7730         if $create_pool; then
7731                 destroy_test_pools 2> /dev/null ||
7732                         error "destroy test pools failed"
7733         fi
7734 }
7735 run_test 56wb "check lfs_migrate pool support"
7736
7737 test_56wc() {
7738         local file1="$DIR/$tdir/$tfile"
7739         local md5
7740         local parent_ssize
7741         local parent_scount
7742         local cur_ssize
7743         local cur_scount
7744         local orig_ssize
7745         local new_scount
7746         local cur_comp
7747
7748         echo -n "Creating test dir..."
7749         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7750         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7751                 error "cannot set stripe by '-S 1M -c 1'"
7752         echo "done"
7753
7754         echo -n "Setting initial stripe for test file..."
7755         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7756                 error "cannot set stripe"
7757         cur_ssize=$($LFS getstripe -S "$file1")
7758         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7759         echo "done."
7760
7761         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7762         stack_trap "rm -f $file1"
7763         md5="$(md5sum $file1)"
7764
7765         # File currently set to -S 512K -c 1
7766
7767         # Ensure -c and -S options are rejected when -R is set
7768         echo -n "Verifying incompatible options are detected..."
7769         $LFS_MIGRATE -R -c 1 "$file1" &&
7770                 error "incompatible -R and -c options not detected"
7771         $LFS_MIGRATE -R -S 1M "$file1" &&
7772                 error "incompatible -R and -S options not detected"
7773         $LFS_MIGRATE -R -p pool "$file1" &&
7774                 error "incompatible -R and -p options not detected"
7775         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7776                 error "incompatible -R and -E options not detected"
7777         $LFS_MIGRATE -R -A "$file1" &&
7778                 error "incompatible -R and -A options not detected"
7779         $LFS_MIGRATE -A -c 1 "$file1" &&
7780                 error "incompatible -A and -c options not detected"
7781         $LFS_MIGRATE -A -S 1M "$file1" &&
7782                 error "incompatible -A and -S options not detected"
7783         $LFS_MIGRATE -A -p pool "$file1" &&
7784                 error "incompatible -A and -p options not detected"
7785         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7786                 error "incompatible -A and -E options not detected"
7787         echo "done."
7788
7789         # Ensure unrecognized options are passed through to 'lfs migrate'
7790         echo -n "Verifying -S option is passed through to lfs migrate..."
7791         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7792         cur_ssize=$($LFS getstripe -S "$file1")
7793         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7794         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7795         echo "done."
7796
7797         # File currently set to -S 1M -c 1
7798
7799         # Ensure long options are supported
7800         echo -n "Verifying long options supported..."
7801         $LFS_MIGRATE --non-block "$file1" ||
7802                 error "long option without argument not supported"
7803         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7804                 error "long option with argument not supported"
7805         cur_ssize=$($LFS getstripe -S "$file1")
7806         (( cur_ssize == 524288 )) ||
7807                 error "migrate --stripe-size $cur_ssize != 524288"
7808         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7809         echo "done."
7810
7811         # File currently set to -S 512K -c 1
7812
7813         if (( OSTCOUNT > 1 )); then
7814                 echo -n "Verifying explicit stripe count can be set..."
7815                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7816                 cur_scount=$($LFS getstripe -c "$file1")
7817                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7818                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7819                         error "file data has changed (3)"
7820                 echo "done."
7821         fi
7822
7823         # File currently set to -S 512K -c 1 or -S 512K -c 2
7824
7825         # Ensure parent striping is used if -R is set, and no stripe
7826         # count or size is specified
7827         echo -n "Setting stripe for parent directory..."
7828         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7829                 error "cannot set stripe '-S 2M -c 1'"
7830         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7831         echo "done."
7832
7833         echo -n "Verifying restripe option uses parent stripe settings..."
7834         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7835         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7836         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7837         cur_ssize=$($LFS getstripe -S "$file1")
7838         (( cur_ssize == parent_ssize )) ||
7839                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7840         cur_scount=$($LFS getstripe -c "$file1")
7841         (( cur_scount == parent_scount )) ||
7842                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7843         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7844         echo "done."
7845
7846         # File currently set to -S 1M -c 1
7847
7848         # Ensure striping is preserved if -R is not set, and no stripe
7849         # count or size is specified
7850         echo -n "Verifying striping size preserved when not specified..."
7851         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7852         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7853                 error "cannot set stripe on parent directory"
7854         $LFS_MIGRATE "$file1" || error "migrate failed"
7855         cur_ssize=$($LFS getstripe -S "$file1")
7856         (( cur_ssize == orig_ssize )) ||
7857                 error "migrate by default $cur_ssize != $orig_ssize"
7858         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7859         echo "done."
7860
7861         # Ensure file name properly detected when final option has no argument
7862         echo -n "Verifying file name properly detected..."
7863         $LFS_MIGRATE "$file1" ||
7864                 error "file name interpreted as option argument"
7865         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7866         echo "done."
7867
7868         # Ensure PFL arguments are passed through properly
7869         echo -n "Verifying PFL options passed through..."
7870         new_scount=$(((OSTCOUNT + 1) / 2))
7871         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7872                 error "migrate PFL arguments failed"
7873         cur_comp=$($LFS getstripe --comp-count $file1)
7874         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7875         cur_scount=$($LFS getstripe --stripe-count $file1)
7876         (( cur_scount == new_scount)) ||
7877                 error "PFL stripe count $cur_scount != $new_scount"
7878         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7879         echo "done."
7880 }
7881 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7882
7883 test_56wd() {
7884         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7885
7886         local file1=$DIR/$tdir/$tfile
7887
7888         echo -n "Creating test dir..."
7889         test_mkdir $DIR/$tdir || error "cannot create dir"
7890         echo "done."
7891
7892         echo -n "Creating test file..."
7893         echo "$tfile" > $file1
7894         echo "done."
7895
7896         # Ensure 'lfs migrate' will fail by using a non-existent option,
7897         # and make sure rsync is not called to recover
7898         echo -n "Make sure --no-rsync option works..."
7899         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7900                 grep -q 'refusing to fall back to rsync' ||
7901                 error "rsync was called with --no-rsync set"
7902         echo "done."
7903
7904         # Ensure rsync is called without trying 'lfs migrate' first
7905         echo -n "Make sure --rsync option works..."
7906         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7907                 grep -q 'falling back to rsync' &&
7908                 error "lfs migrate was called with --rsync set"
7909         echo "done."
7910 }
7911 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7912
7913 test_56we() {
7914         local td=$DIR/$tdir
7915         local tf=$td/$tfile
7916
7917         test_mkdir $td || error "cannot create $td"
7918         touch $tf || error "cannot touch $tf"
7919
7920         echo -n "Make sure --non-direct|-D works..."
7921         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7922                 grep -q "lfs migrate --non-direct" ||
7923                 error "--non-direct option cannot work correctly"
7924         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7925                 grep -q "lfs migrate -D" ||
7926                 error "-D option cannot work correctly"
7927         echo "done."
7928 }
7929 run_test 56we "check lfs_migrate --non-direct|-D support"
7930
7931 test_56x() {
7932         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7933         check_swap_layouts_support
7934
7935         local dir=$DIR/$tdir
7936         local ref1=/etc/passwd
7937         local file1=$dir/file1
7938
7939         test_mkdir $dir || error "creating dir $dir"
7940         $LFS setstripe -c 2 $file1
7941         cp $ref1 $file1
7942         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7943         stripe=$($LFS getstripe -c $file1)
7944         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7945         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7946
7947         # clean up
7948         rm -f $file1
7949 }
7950 run_test 56x "lfs migration support"
7951
7952 test_56xa() {
7953         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7954         check_swap_layouts_support
7955
7956         local dir=$DIR/$tdir/$testnum
7957
7958         test_mkdir -p $dir
7959
7960         local ref1=/etc/passwd
7961         local file1=$dir/file1
7962
7963         $LFS setstripe -c 2 $file1
7964         cp $ref1 $file1
7965         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7966
7967         local stripe=$($LFS getstripe -c $file1)
7968
7969         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7970         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7971
7972         # clean up
7973         rm -f $file1
7974 }
7975 run_test 56xa "lfs migration --block support"
7976
7977 check_migrate_links() {
7978         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7979         local dir="$1"
7980         local file1="$dir/file1"
7981         local begin="$2"
7982         local count="$3"
7983         local runas="$4"
7984         local total_count=$(($begin + $count - 1))
7985         local symlink_count=10
7986         local uniq_count=10
7987
7988         if [ ! -f "$file1" ]; then
7989                 echo -n "creating initial file..."
7990                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7991                         error "cannot setstripe initial file"
7992                 echo "done"
7993
7994                 echo -n "creating symlinks..."
7995                 for s in $(seq 1 $symlink_count); do
7996                         ln -s "$file1" "$dir/slink$s" ||
7997                                 error "cannot create symlinks"
7998                 done
7999                 echo "done"
8000
8001                 echo -n "creating nonlinked files..."
8002                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
8003                         error "cannot create nonlinked files"
8004                 echo "done"
8005         fi
8006
8007         # create hard links
8008         if [ ! -f "$dir/file$total_count" ]; then
8009                 echo -n "creating hard links $begin:$total_count..."
8010                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
8011                         /dev/null || error "cannot create hard links"
8012                 echo "done"
8013         fi
8014
8015         echo -n "checking number of hard links listed in xattrs..."
8016         local fid=$($LFS getstripe -F "$file1")
8017         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
8018
8019         echo "${#paths[*]}"
8020         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
8021                         skip "hard link list has unexpected size, skipping test"
8022         fi
8023         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
8024                         error "link names should exceed xattrs size"
8025         fi
8026
8027         echo -n "migrating files..."
8028         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
8029         local rc=$?
8030         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
8031         echo "done"
8032
8033         # make sure all links have been properly migrated
8034         echo -n "verifying files..."
8035         fid=$($LFS getstripe -F "$file1") ||
8036                 error "cannot get fid for file $file1"
8037         for i in $(seq 2 $total_count); do
8038                 local fid2=$($LFS getstripe -F $dir/file$i)
8039
8040                 [ "$fid2" == "$fid" ] ||
8041                         error "migrated hard link has mismatched FID"
8042         done
8043
8044         # make sure hard links were properly detected, and migration was
8045         # performed only once for the entire link set; nonlinked files should
8046         # also be migrated
8047         local actual=$(grep -c 'done' <<< "$migrate_out")
8048         local expected=$(($uniq_count + 1))
8049
8050         [ "$actual" -eq  "$expected" ] ||
8051                 error "hard links individually migrated ($actual != $expected)"
8052
8053         # make sure the correct number of hard links are present
8054         local hardlinks=$(stat -c '%h' "$file1")
8055
8056         [ $hardlinks -eq $total_count ] ||
8057                 error "num hard links $hardlinks != $total_count"
8058         echo "done"
8059
8060         return 0
8061 }
8062
8063 test_56xb() {
8064         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
8065                 skip "Need MDS version at least 2.10.55"
8066
8067         local dir="$DIR/$tdir"
8068
8069         test_mkdir "$dir" || error "cannot create dir $dir"
8070
8071         echo "testing lfs migrate mode when all links fit within xattrs"
8072         check_migrate_links "$dir" 2 99
8073
8074         echo "testing rsync mode when all links fit within xattrs"
8075         check_migrate_links --rsync "$dir" 2 99
8076
8077         echo "testing lfs migrate mode when all links do not fit within xattrs"
8078         check_migrate_links "$dir" 101 100
8079
8080         echo "testing rsync mode when all links do not fit within xattrs"
8081         check_migrate_links --rsync "$dir" 101 100
8082
8083         chown -R $RUNAS_ID $dir
8084         echo "testing non-root lfs migrate mode when not all links are in xattr"
8085         check_migrate_links "$dir" 101 100 "$RUNAS"
8086
8087         # clean up
8088         rm -rf $dir
8089 }
8090 run_test 56xb "lfs migration hard link support"
8091
8092 test_56xc() {
8093         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8094
8095         local dir="$DIR/$tdir"
8096
8097         test_mkdir "$dir" || error "cannot create dir $dir"
8098
8099         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
8100         echo -n "Setting initial stripe for 20MB test file..."
8101         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
8102                 error "cannot setstripe 20MB file"
8103         echo "done"
8104         echo -n "Sizing 20MB test file..."
8105         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
8106         echo "done"
8107         echo -n "Verifying small file autostripe count is 1..."
8108         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
8109                 error "cannot migrate 20MB file"
8110         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
8111                 error "cannot get stripe for $dir/20mb"
8112         [ $stripe_count -eq 1 ] ||
8113                 error "unexpected stripe count $stripe_count for 20MB file"
8114         rm -f "$dir/20mb"
8115         echo "done"
8116
8117         # Test 2: File is small enough to fit within the available space on
8118         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
8119         # have at least an additional 1KB for each desired stripe for test 3
8120         echo -n "Setting stripe for 1GB test file..."
8121         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
8122         echo "done"
8123         echo -n "Sizing 1GB test file..."
8124         # File size is 1GB + 3KB
8125         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
8126         echo "done"
8127
8128         # need at least 512MB per OST for 1GB file to fit in 2 stripes
8129         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
8130         if (( avail > 524288 * OSTCOUNT )); then
8131                 echo -n "Migrating 1GB file..."
8132                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
8133                         error "cannot migrate 1GB file"
8134                 echo "done"
8135                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
8136                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
8137                         error "cannot getstripe for 1GB file"
8138                 [ $stripe_count -eq 2 ] ||
8139                         error "unexpected stripe count $stripe_count != 2"
8140                 echo "done"
8141         fi
8142
8143         # Test 3: File is too large to fit within the available space on
8144         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
8145         if [ $OSTCOUNT -ge 3 ]; then
8146                 # The required available space is calculated as
8147                 # file size (1GB + 3KB) / OST count (3).
8148                 local kb_per_ost=349526
8149
8150                 echo -n "Migrating 1GB file with limit..."
8151                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
8152                         error "cannot migrate 1GB file with limit"
8153                 echo "done"
8154
8155                 stripe_count=$($LFS getstripe -c "$dir/1gb")
8156                 echo -n "Verifying 1GB autostripe count with limited space..."
8157                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
8158                         error "unexpected stripe count $stripe_count (min 3)"
8159                 echo "done"
8160         fi
8161
8162         # clean up
8163         rm -rf $dir
8164 }
8165 run_test 56xc "lfs migration autostripe"
8166
8167 test_56xd() {
8168         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8169
8170         local dir=$DIR/$tdir
8171         local f_mgrt=$dir/$tfile.mgrt
8172         local f_yaml=$dir/$tfile.yaml
8173         local f_copy=$dir/$tfile.copy
8174         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8175         local layout_copy="-c 2 -S 2M -i 1"
8176         local yamlfile=$dir/yamlfile
8177         local layout_before;
8178         local layout_after;
8179
8180         test_mkdir "$dir" || error "cannot create dir $dir"
8181         stack_trap "rm -rf $dir"
8182         $LFS setstripe $layout_yaml $f_yaml ||
8183                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8184         $LFS getstripe --yaml $f_yaml > $yamlfile
8185         $LFS setstripe $layout_copy $f_copy ||
8186                 error "cannot setstripe $f_copy with layout $layout_copy"
8187         touch $f_mgrt
8188         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8189
8190         # 1. test option --yaml
8191         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8192                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8193         layout_before=$(get_layout_param $f_yaml)
8194         layout_after=$(get_layout_param $f_mgrt)
8195         [ "$layout_after" == "$layout_before" ] ||
8196                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8197
8198         # 2. test option --copy
8199         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8200                 error "cannot migrate $f_mgrt with --copy $f_copy"
8201         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8202         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8203         [ "$layout_after" == "$layout_before" ] ||
8204                 error "lfs_migrate --copy: $layout_after != $layout_before"
8205 }
8206 run_test 56xd "check lfs_migrate --yaml and --copy support"
8207
8208 test_56xe() {
8209         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8210
8211         local dir=$DIR/$tdir
8212         local f_comp=$dir/$tfile
8213         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8214         local layout_before=""
8215         local layout_after=""
8216
8217         test_mkdir "$dir" || error "cannot create dir $dir"
8218         stack_trap "rm -rf $dir"
8219         $LFS setstripe $layout $f_comp ||
8220                 error "cannot setstripe $f_comp with layout $layout"
8221         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8222         dd if=/dev/zero of=$f_comp bs=1M count=4
8223
8224         # 1. migrate a comp layout file by lfs_migrate
8225         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8226         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8227         [ "$layout_before" == "$layout_after" ] ||
8228                 error "lfs_migrate: $layout_before != $layout_after"
8229
8230         # 2. migrate a comp layout file by lfs migrate
8231         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8232         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8233         [ "$layout_before" == "$layout_after" ] ||
8234                 error "lfs migrate: $layout_before != $layout_after"
8235 }
8236 run_test 56xe "migrate a composite layout file"
8237
8238 test_56xf() {
8239         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8240
8241         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8242                 skip "Need server version at least 2.13.53"
8243
8244         local dir=$DIR/$tdir
8245         local f_comp=$dir/$tfile
8246         local layout="-E 1M -c1 -E -1 -c2"
8247         local fid_before=""
8248         local fid_after=""
8249
8250         test_mkdir "$dir" || error "cannot create dir $dir"
8251         stack_trap "rm -rf $dir"
8252         $LFS setstripe $layout $f_comp ||
8253                 error "cannot setstripe $f_comp with layout $layout"
8254         fid_before=$($LFS getstripe --fid $f_comp)
8255         dd if=/dev/zero of=$f_comp bs=1M count=4
8256
8257         # 1. migrate a comp layout file to a comp layout
8258         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8259         fid_after=$($LFS getstripe --fid $f_comp)
8260         [ "$fid_before" == "$fid_after" ] ||
8261                 error "comp-to-comp migrate: $fid_before != $fid_after"
8262
8263         # 2. migrate a comp layout file to a plain layout
8264         $LFS migrate -c2 $f_comp ||
8265                 error "cannot migrate $f_comp by lfs migrate"
8266         fid_after=$($LFS getstripe --fid $f_comp)
8267         [ "$fid_before" == "$fid_after" ] ||
8268                 error "comp-to-plain migrate: $fid_before != $fid_after"
8269
8270         # 3. migrate a plain layout file to a comp layout
8271         $LFS migrate $layout $f_comp ||
8272                 error "cannot migrate $f_comp by lfs migrate"
8273         fid_after=$($LFS getstripe --fid $f_comp)
8274         [ "$fid_before" == "$fid_after" ] ||
8275                 error "plain-to-comp migrate: $fid_before != $fid_after"
8276 }
8277 run_test 56xf "FID is not lost during migration of a composite layout file"
8278
8279 check_file_ost_range() {
8280         local file="$1"
8281         shift
8282         local range="$*"
8283         local -a file_range
8284         local idx
8285
8286         file_range=($($LFS getstripe -y "$file" |
8287                 awk '/l_ost_idx:/ { print $NF }'))
8288
8289         if [[ "${#file_range[@]}" = 0 ]]; then
8290                 echo "No osts found for $file"
8291                 return 1
8292         fi
8293
8294         for idx in "${file_range[@]}"; do
8295                 [[ " $range " =~ " $idx " ]] ||
8296                         return 1
8297         done
8298
8299         return 0
8300 }
8301
8302 sub_test_56xg() {
8303         local stripe_opt="$1"
8304         local pool="$2"
8305         shift 2
8306         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8307
8308         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8309                 error "Fail to migrate $tfile on $pool"
8310         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8311                 error "$tfile is not in pool $pool"
8312         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8313                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8314 }
8315
8316 test_56xg() {
8317         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8318         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8319         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8320                 skip "Need MDS version newer than 2.14.52"
8321
8322         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8323         local -a pool_ranges=("0 0" "1 1" "0 1")
8324
8325         # init pools
8326         for i in "${!pool_names[@]}"; do
8327                 pool_add ${pool_names[$i]} ||
8328                         error "pool_add failed (pool: ${pool_names[$i]})"
8329                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8330                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8331         done
8332
8333         # init the file to migrate
8334         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8335                 error "Unable to create $tfile on OST1"
8336         stack_trap "rm -f $DIR/$tfile"
8337         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8338                 error "Unable to write on $tfile"
8339
8340         echo "1. migrate $tfile on pool ${pool_names[0]}"
8341         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8342
8343         echo "2. migrate $tfile on pool ${pool_names[2]}"
8344         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8345
8346         echo "3. migrate $tfile on pool ${pool_names[1]}"
8347         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8348
8349         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8350         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8351         echo
8352
8353         # Clean pools
8354         destroy_test_pools ||
8355                 error "pool_destroy failed"
8356 }
8357 run_test 56xg "lfs migrate pool support"
8358
8359 test_56xh() {
8360         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8361
8362         local size_mb=25
8363         local file1=$DIR/$tfile
8364         local tmp1=$TMP/$tfile.tmp
8365
8366         $LFS setstripe -c 2 $file1
8367
8368         stack_trap "rm -f $file1 $tmp1"
8369         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8370                         error "error creating $tmp1"
8371         ls -lsh $tmp1
8372         cp $tmp1 $file1
8373
8374         local start=$SECONDS
8375
8376         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8377                 error "migrate failed rc = $?"
8378
8379         local elapsed=$((SECONDS - start))
8380
8381         # with 1MB/s, elapsed should equal size_mb
8382         (( elapsed >= size_mb * 95 / 100 )) ||
8383                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8384
8385         (( elapsed <= size_mb * 120 / 100 )) ||
8386                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8387
8388         (( elapsed <= size_mb * 350 / 100 )) ||
8389                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8390
8391         stripe=$($LFS getstripe -c $file1)
8392         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8393         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8394
8395         # Clean up file (since it is multiple MB)
8396         rm -f $file1 $tmp1
8397 }
8398 run_test 56xh "lfs migrate bandwidth limitation support"
8399
8400 test_56xi() {
8401         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8402         verify_yaml_available || skip_env "YAML verification not installed"
8403
8404         local size_mb=5
8405         local file1=$DIR/$tfile.1
8406         local file2=$DIR/$tfile.2
8407         local file3=$DIR/$tfile.3
8408         local output_file=$DIR/$tfile.out
8409         local tmp1=$TMP/$tfile.tmp
8410
8411         $LFS setstripe -c 2 $file1
8412         $LFS setstripe -c 2 $file2
8413         $LFS setstripe -c 2 $file3
8414
8415         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8416         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8417                         error "error creating $tmp1"
8418         ls -lsh $tmp1
8419         cp $tmp1 $file1
8420         cp $tmp1 $file2
8421         cp $tmp1 $file3
8422
8423         $LFS migrate --stats --stats-interval=1 \
8424                 -c 1 $file1 $file2 $file3 1> $output_file ||
8425                 error "migrate failed rc = $?"
8426
8427         cat $output_file
8428         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8429
8430         # Clean up file (since it is multiple MB)
8431         rm -f $file1 $file2 $file3 $tmp1 $output_file
8432 }
8433 run_test 56xi "lfs migrate stats support"
8434
8435 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8436         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8437
8438         local file=$DIR/$tfile
8439         local linkdir=$DIR/$tdir
8440
8441         test_mkdir $linkdir || error "fail to create $linkdir"
8442         $LFS setstripe -i 0 -c 1 -S1M $file
8443         stack_trap "rm -rf $file $linkdir"
8444         dd if=/dev/urandom of=$file bs=1M count=10 ||
8445                 error "fail to create $file"
8446
8447         # Create file links
8448         local cpts
8449         local threads_max
8450         local nlinks
8451
8452         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8453         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8454         (( nlinks = thread_max * 3 / 2 / cpts))
8455
8456         echo "create $nlinks hard links of $file"
8457         createmany -l $file $linkdir/link $nlinks
8458
8459         # Parallel migrates (should not block)
8460         local i
8461         for ((i = 0; i < nlinks; i++)); do
8462                 echo $linkdir/link$i
8463         done | xargs -n1 -P $nlinks $LFS migrate -c2
8464
8465         local stripe_count
8466         stripe_count=$($LFS getstripe -c $file) ||
8467                 error "fail to get stripe count on $file"
8468
8469         ((stripe_count == 2)) ||
8470                 error "fail to migrate $file (stripe_count = $stripe_count)"
8471 }
8472 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8473
8474 test_56xk() {
8475         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8476
8477         local size_mb=5
8478         local file1=$DIR/$tfile
8479
8480         stack_trap "rm -f $file1"
8481         $LFS setstripe -c 1 $file1
8482         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8483                 error "error creating $file1"
8484         $LFS mirror extend -N $file1 || error "can't mirror"
8485         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8486                 error "can't dd"
8487         $LFS getstripe $file1 | grep stale ||
8488                 error "one component must be stale"
8489
8490         local start=$SECONDS
8491         $LFS mirror resync --stats --stats-interval=1 -W 1M $file1 ||
8492                 error "migrate failed rc = $?"
8493         local elapsed=$((SECONDS - start))
8494         $LFS getstripe $file1 | grep stale &&
8495                 error "all components must be sync"
8496
8497         # with 1MB/s, elapsed should equal size_mb
8498         (( elapsed >= size_mb * 95 / 100 )) ||
8499                 error "'lfs mirror resync -W' too fast ($elapsed < 0.95 * $size_mb)?"
8500
8501         (( elapsed <= size_mb * 120 / 100 )) ||
8502                 error_not_in_vm "'lfs mirror resync -W' slow ($elapsed > 1.2 * $size_mb)"
8503
8504         (( elapsed <= size_mb * 350 / 100 )) ||
8505                 error "'lfs mirror resync -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8506 }
8507 run_test 56xk "lfs mirror resync bandwidth limitation support"
8508
8509 test_56xl() {
8510         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8511         verify_yaml_available || skip_env "YAML verification not installed"
8512
8513         local size_mb=5
8514         local file1=$DIR/$tfile.1
8515         local output_file=$DIR/$tfile.out
8516
8517         stack_trap "rm -f $file1"
8518         $LFS setstripe -c 1 $file1
8519         dd if=/dev/zero of=$file1 bs=1M count=$size_mb ||
8520                 error "error creating $file1"
8521         $LFS mirror extend -N $file1 || error "can't mirror"
8522         dd if=/dev/zero of=$file1 bs=4k count=1 conv=notrunc ||
8523                 error "can't dd"
8524         $LFS getstripe $file1 | grep stale ||
8525                 error "one component must be stale"
8526         $LFS getstripe $file1
8527
8528         $LFS mirror resync --stats --stats-interval=1 $file1 >$output_file ||
8529                 error "resync failed rc = $?"
8530         $LFS getstripe $file1 | grep stale &&
8531                 error "all components must be sync"
8532
8533         cat $output_file
8534         cat $output_file | verify_yaml || error "stats is not valid YAML"
8535 }
8536 run_test 56xl "lfs mirror resync stats support"
8537
8538 test_56y() {
8539         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8540                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8541
8542         local res=""
8543         local dir=$DIR/$tdir
8544         local f1=$dir/file1
8545         local f2=$dir/file2
8546
8547         test_mkdir -p $dir || error "creating dir $dir"
8548         touch $f1 || error "creating std file $f1"
8549         $MULTIOP $f2 H2c || error "creating released file $f2"
8550
8551         # a directory can be raid0, so ask only for files
8552         res=$($LFS find $dir -L raid0 -type f | wc -l)
8553         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8554
8555         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8556         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8557
8558         # only files can be released, so no need to force file search
8559         res=$($LFS find $dir -L released)
8560         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8561
8562         res=$($LFS find $dir -type f \! -L released)
8563         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8564 }
8565 run_test 56y "lfs find -L raid0|released"
8566
8567 test_56z() { # LU-4824
8568         # This checks to make sure 'lfs find' continues after errors
8569         # There are two classes of errors that should be caught:
8570         # - If multiple paths are provided, all should be searched even if one
8571         #   errors out
8572         # - If errors are encountered during the search, it should not terminate
8573         #   early
8574         local dir=$DIR/$tdir
8575         local i
8576
8577         test_mkdir $dir
8578         for i in d{0..9}; do
8579                 test_mkdir $dir/$i
8580                 touch $dir/$i/$tfile
8581         done
8582         $LFS find $DIR/non_existent_dir $dir &&
8583                 error "$LFS find did not return an error"
8584         # Make a directory unsearchable. This should NOT be the last entry in
8585         # directory order.  Arbitrarily pick the 6th entry
8586         chmod 700 $($LFS find $dir -type d | sed '6!d')
8587
8588         $RUNAS $LFS find $DIR/non_existent $dir
8589         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8590
8591         # The user should be able to see 10 directories and 9 files
8592         (( count == 19 )) ||
8593                 error "$LFS find found $count != 19 entries after error"
8594 }
8595 run_test 56z "lfs find should continue after an error"
8596
8597 test_56aa() { # LU-5937
8598         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8599
8600         local dir=$DIR/$tdir
8601
8602         mkdir $dir
8603         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8604
8605         createmany -o $dir/striped_dir/${tfile}- 1024
8606         local dirs=$($LFS find --size +8k $dir/)
8607
8608         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8609 }
8610 run_test 56aa "lfs find --size under striped dir"
8611
8612 test_56ab() { # LU-10705
8613         test_mkdir $DIR/$tdir
8614         dd if=/dev/urandom of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8615         dd if=/dev/urandom of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8616         dd if=/dev/urandom of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8617         # Flush writes to ensure valid blocks.  Need to be more thorough for
8618         # ZFS, since blocks are not allocated/returned to client immediately.
8619         sync_all_data
8620         wait_zfs_commit ost1 2
8621         cancel_lru_locks osc
8622         ls -ls $DIR/$tdir
8623
8624         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8625
8626         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8627
8628         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8629         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8630
8631         rm -f $DIR/$tdir/$tfile.[123]
8632 }
8633 run_test 56ab "lfs find --blocks"
8634
8635 # LU-11188
8636 test_56aca() {
8637         local dir="$DIR/$tdir"
8638         local perms=(001 002 003 004 005 006 007
8639                      010 020 030 040 050 060 070
8640                      100 200 300 400 500 600 700
8641                      111 222 333 444 555 666 777)
8642         local perm_minus=(8 8 4 8 4 4 2
8643                           8 8 4 8 4 4 2
8644                           8 8 4 8 4 4 2
8645                           4 4 2 4 2 2 1)
8646         local perm_slash=(8  8 12  8 12 12 14
8647                           8  8 12  8 12 12 14
8648                           8  8 12  8 12 12 14
8649                          16 16 24 16 24 24 28)
8650
8651         test_mkdir "$dir"
8652         for perm in ${perms[*]}; do
8653                 touch "$dir/$tfile.$perm"
8654                 chmod $perm "$dir/$tfile.$perm"
8655         done
8656
8657         for ((i = 0; i < ${#perms[*]}; i++)); do
8658                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8659                 (( $num == 1 )) ||
8660                         error "lfs find -perm ${perms[i]}:"\
8661                               "$num != 1"
8662
8663                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8664                 (( $num == ${perm_minus[i]} )) ||
8665                         error "lfs find -perm -${perms[i]}:"\
8666                               "$num != ${perm_minus[i]}"
8667
8668                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8669                 (( $num == ${perm_slash[i]} )) ||
8670                         error "lfs find -perm /${perms[i]}:"\
8671                               "$num != ${perm_slash[i]}"
8672         done
8673 }
8674 run_test 56aca "check lfs find -perm with octal representation"
8675
8676 test_56acb() {
8677         local dir=$DIR/$tdir
8678         # p is the permission of write and execute for user, group and other
8679         # without the umask. It is used to test +wx.
8680         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8681         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8682         local symbolic=(+t  a+t u+t g+t o+t
8683                         g+s u+s o+s +s o+sr
8684                         o=r,ug+o,u+w
8685                         u+ g+ o+ a+ ugo+
8686                         u- g- o- a- ugo-
8687                         u= g= o= a= ugo=
8688                         o=r,ug+o,u+w u=r,a+u,u+w
8689                         g=r,ugo=g,u+w u+x,+X +X
8690                         u+x,u+X u+X u+x,g+X o+r,+X
8691                         u+x,go+X +wx +rwx)
8692
8693         test_mkdir $dir
8694         for perm in ${perms[*]}; do
8695                 touch "$dir/$tfile.$perm"
8696                 chmod $perm "$dir/$tfile.$perm"
8697         done
8698
8699         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8700                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8701
8702                 (( $num == 1 )) ||
8703                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8704         done
8705 }
8706 run_test 56acb "check lfs find -perm with symbolic representation"
8707
8708 test_56acc() {
8709         local dir=$DIR/$tdir
8710         local tests="17777 787 789 abcd
8711                 ug=uu ug=a ug=gu uo=ou urw
8712                 u+xg+x a=r,u+x,"
8713
8714         test_mkdir $dir
8715         for err in $tests; do
8716                 if $LFS find $dir -perm $err 2>/dev/null; then
8717                         error "lfs find -perm $err: parsing should have failed"
8718                 fi
8719         done
8720 }
8721 run_test 56acc "check parsing error for lfs find -perm"
8722
8723 test_56ba() {
8724         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8725                 skip "Need MDS version at least 2.10.50"
8726
8727         # Create composite files with one component
8728         local dir=$DIR/$tdir
8729
8730         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8731         # Create composite files with three components
8732         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8733         # LU-16904 Create plain layout files
8734         lfs setstripe -c 1 $dir/$tfile-{1..10}
8735
8736         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8737
8738         [[ $nfiles == 10 ]] ||
8739                 error "lfs find -E 1M found $nfiles != 10 files"
8740
8741         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8742         [[ $nfiles == 25 ]] ||
8743                 error "lfs find ! -E 1M found $nfiles != 25 files"
8744
8745         # All files have a component that starts at 0
8746         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8747         [[ $nfiles == 35 ]] ||
8748                 error "lfs find --component-start 0 - $nfiles != 35 files"
8749
8750         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8751         [[ $nfiles == 15 ]] ||
8752                 error "lfs find --component-start 2M - $nfiles != 15 files"
8753
8754         # All files created here have a componenet that does not starts at 2M
8755         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8756         [[ $nfiles == 35 ]] ||
8757                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8758
8759         # Find files with a specified number of components
8760         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8761         [[ $nfiles == 15 ]] ||
8762                 error "lfs find --component-count 3 - $nfiles != 15 files"
8763
8764         # Remember non-composite files have a component count of zero
8765         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8766         [[ $nfiles == 10 ]] ||
8767                 error "lfs find --component-count 0 - $nfiles != 10 files"
8768
8769         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8770         [[ $nfiles == 20 ]] ||
8771                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8772
8773         # All files have a flag called "init"
8774         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8775         [[ $nfiles == 35 ]] ||
8776                 error "lfs find --component-flags init - $nfiles != 35 files"
8777
8778         # Multi-component files will have a component not initialized
8779         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8780         [[ $nfiles == 15 ]] ||
8781                 error "lfs find !--component-flags init - $nfiles != 15 files"
8782
8783         rm -rf $dir
8784
8785 }
8786 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8787
8788 test_56ca() {
8789         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8790                 skip "Need MDS version at least 2.10.57"
8791
8792         local td=$DIR/$tdir
8793         local tf=$td/$tfile
8794         local dir
8795         local nfiles
8796         local cmd
8797         local i
8798         local j
8799
8800         # create mirrored directories and mirrored files
8801         mkdir $td || error "mkdir $td failed"
8802         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8803         createmany -o $tf- 10 || error "create $tf- failed"
8804
8805         for i in $(seq 2); do
8806                 dir=$td/dir$i
8807                 mkdir $dir || error "mkdir $dir failed"
8808                 $LFS mirror create -N$((3 + i)) $dir ||
8809                         error "create mirrored dir $dir failed"
8810                 createmany -o $dir/$tfile- 10 ||
8811                         error "create $dir/$tfile- failed"
8812         done
8813
8814         # change the states of some mirrored files
8815         echo foo > $tf-6
8816         for i in $(seq 2); do
8817                 dir=$td/dir$i
8818                 for j in $(seq 4 9); do
8819                         echo foo > $dir/$tfile-$j
8820                 done
8821         done
8822
8823         # find mirrored files with specific mirror count
8824         cmd="$LFS find --mirror-count 3 --type f $td"
8825         nfiles=$($cmd | wc -l)
8826         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8827
8828         cmd="$LFS find ! --mirror-count 3 --type f $td"
8829         nfiles=$($cmd | wc -l)
8830         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8831
8832         cmd="$LFS find --mirror-count +2 --type f $td"
8833         nfiles=$($cmd | wc -l)
8834         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8835
8836         cmd="$LFS find --mirror-count -6 --type f $td"
8837         nfiles=$($cmd | wc -l)
8838         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8839
8840         # find mirrored files with specific file state
8841         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8842         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8843
8844         cmd="$LFS find --mirror-state=ro --type f $td"
8845         nfiles=$($cmd | wc -l)
8846         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8847
8848         cmd="$LFS find ! --mirror-state=ro --type f $td"
8849         nfiles=$($cmd | wc -l)
8850         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8851
8852         cmd="$LFS find --mirror-state=wp --type f $td"
8853         nfiles=$($cmd | wc -l)
8854         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8855
8856         cmd="$LFS find ! --mirror-state=sp --type f $td"
8857         nfiles=$($cmd | wc -l)
8858         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8859 }
8860 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8861
8862 test_56da() { # LU-14179
8863         local path=$DIR/$tdir
8864
8865         test_mkdir $path
8866         cd $path
8867
8868         local longdir=$(str_repeat 'a' 255)
8869
8870         for i in {1..15}; do
8871                 path=$path/$longdir
8872                 test_mkdir $longdir
8873                 cd $longdir
8874         done
8875
8876         local len=${#path}
8877         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8878
8879         test_mkdir $lastdir
8880         cd $lastdir
8881         # PATH_MAX-1
8882         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8883
8884         # NAME_MAX
8885         touch $(str_repeat 'f' 255)
8886
8887         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8888                 error "lfs find reported an error"
8889
8890         rm -rf $DIR/$tdir
8891 }
8892 run_test 56da "test lfs find with long paths"
8893
8894 test_56ea() { #LU-10378
8895         local path=$DIR/$tdir
8896         local pool=$TESTNAME
8897
8898         # Create ost pool
8899         pool_add $pool || error "pool_add $pool failed"
8900         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8901                 error "adding targets to $pool failed"
8902
8903         # Set default pool on directory before creating file
8904         mkdir $path || error "mkdir $path failed"
8905         $LFS setstripe -p $pool $path ||
8906                 error "set OST pool on $pool failed"
8907         touch $path/$tfile || error "touch $path/$tfile failed"
8908
8909         # Compare basic file attributes from -printf and stat
8910         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G %n")
8911         local attr_stat=$(stat -c "%X %Y %Z %u %g %h" $path/$tfile)
8912
8913         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8914                 error "Attrs from lfs find and stat don't match"
8915
8916         # Compare Lustre attributes from lfs find and lfs getstripe
8917         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8918         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8919         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8920         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8921         local fpool=$($LFS getstripe --pool $path/$tfile)
8922         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8923
8924         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8925                 error "Attrs from lfs find and lfs getstripe don't match"
8926
8927         # Verify behavior for unknown escape/format sequences
8928         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8929
8930         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8931                 error "Escape/format codes don't match"
8932 }
8933 run_test 56ea "test lfs find -printf option"
8934
8935 test_56eb() {
8936         local dir=$DIR/$tdir
8937         local subdir_1=$dir/subdir_1
8938
8939         test_mkdir -p $subdir_1
8940         ln -s subdir_1 $dir/link_1
8941
8942         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8943                 error "symlink is not followed"
8944
8945         $LFS getstripe --no-follow $dir |
8946                 grep "^$dir/link_1 has no stripe info$" ||
8947                 error "symlink should not have stripe info"
8948
8949         touch $dir/testfile
8950         ln -s testfile $dir/file_link_2
8951
8952         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8953                 error "symlink is not followed"
8954
8955         $LFS getstripe --no-follow $dir |
8956                 grep "^$dir/file_link_2 has no stripe info$" ||
8957                 error "symlink should not have stripe info"
8958 }
8959 run_test 56eb "check lfs getstripe on symlink"
8960
8961 test_56ec() {
8962         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8963         local dir=$DIR/$tdir
8964         local srcfile=$dir/srcfile
8965         local srcyaml=$dir/srcyaml
8966         local destfile=$dir/destfile
8967
8968         test_mkdir -p $dir
8969
8970         $LFS setstripe -i 1 $srcfile
8971         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8972         # if the setstripe yaml parsing fails for any reason, the command can
8973         # randomly assign the correct OST index, leading to an erroneous
8974         # success. but the chance of false success is low enough that a
8975         # regression should still be quickly caught.
8976         $LFS setstripe --yaml=$srcyaml $destfile
8977
8978         local srcindex=$($LFS getstripe -i $srcfile)
8979         local destindex=$($LFS getstripe -i $destfile)
8980
8981         if [[ ! $srcindex -eq $destindex ]]; then
8982                 error "setstripe did not set OST index correctly"
8983         fi
8984 }
8985 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8986
8987 test_56eda() {
8988         local dir=$DIR/$tdir
8989         local subdir=$dir/subdir
8990         local file1=$dir/$tfile
8991         local file2=$dir/$tfile\2
8992         local link=$dir/$tfile-link
8993         local nfiles
8994
8995         test_mkdir -p $dir
8996         $LFS setdirstripe -c1 $subdir
8997         touch $file1
8998         touch $file2
8999         ln $file2 $link
9000
9001         nfiles=$($LFS find --links 1 $dir | wc -l)
9002         (( $nfiles == 1 )) ||
9003                 error "lfs find --links expected 1 file, got $nfiles"
9004
9005         nfiles=$($LFS find --type f --links 2 $dir | wc -l)
9006         (( $nfiles == 2 )) ||
9007                 error "lfs find --links expected 2 files, got $nfiles"
9008
9009         nfiles=$($LFS find --type d --links 2 $dir | wc -l)
9010         (( $nfiles == 1 )) ||
9011                 error "lfs find --links expected 1 directory, got $nfiles"
9012 }
9013 run_test 56eda "check lfs find --links"
9014
9015 test_56edb() {
9016         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
9017
9018         local dir=$DIR/$tdir
9019         local stripedir=$dir/stripedir
9020         local nfiles
9021
9022         test_mkdir -p $dir
9023
9024         $LFS setdirstripe -c2 $stripedir
9025
9026         $LFS getdirstripe $stripedir
9027
9028         nfiles=$($LFS find --type d --links 2 $stripedir | wc -l)
9029         (( $nfiles == 1 )) ||
9030                 error "lfs find --links expected 1 directory, got $nfiles"
9031 }
9032 run_test 56edb "check lfs find --links for directory striped on multiple MDTs"
9033
9034 test_56ef() {
9035         local dir=$DIR/$tdir
9036         local dir1=$dir/d1
9037         local dir2=$dir/d2
9038         local nfiles
9039         local err_msg
9040
9041         test_mkdir -p $dir
9042
9043         mkdir $dir1
9044         mkdir $dir2
9045
9046         touch $dir1/f
9047         touch $dir2/f
9048
9049         nfiles=$($LFS find $dir1 $dir2 ! -type d | wc -l)
9050         (( $nfiles == 2 )) ||
9051                 error "(1) lfs find expected 2 files, got $nfiles"
9052
9053         nfiles=$($LFS find $dir1 $dir2 -type f | wc -l)
9054         (( $nfiles == 2 )) ||
9055                 error "(2) lfs find expected 2 files, got $nfiles"
9056
9057         nfiles=$($LFS find -type f $dir1 $dir2 | wc -l)
9058         (( $nfiles == 2 )) ||
9059                 error "(3) lfs find expected 2 files, got $nfiles"
9060
9061         err_msg=$($LFS find $dir1/typo $dir1/f 2>&1 > /dev/null)
9062         [[ $err_msg =~ "No such file or directory" ]] ||
9063                 error "expected standard error message, got: '$err_msg'"
9064 }
9065 run_test 56ef "lfs find with multiple paths"
9066
9067 test_56eg() {
9068         local dir=$DIR/$tdir
9069         local found
9070
9071         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9072
9073         test_mkdir -p $dir
9074
9075         touch $dir/$tfile
9076         ln -s $dir/$tfile $dir/$tfile.symlink
9077         setfattr -n "trusted.test" -v "test_target" $dir/$tfile
9078         setfattr --no-dereference -n "trusted.test" -v "test_link" \
9079                 $dir/$tfile.symlink
9080         setfattr --no-dereference -n "trusted.common" \
9081                 $dir/{$tfile,$tfile.symlink}
9082
9083         found=$($LFS find -xattr "trusted.*=test_target" \
9084                 -xattr "trusted.common" $dir)
9085         [[ "$found" == "$dir/$tfile" ]] || {
9086                 getfattr -d -m trusted.* $dir/$tfile
9087                 error "should have found '$tfile' with xattr 'trusted.test=test_target', got '$found'"
9088         }
9089
9090         found=$($LFS find -xattr "trusted.*=test_link" \
9091                 -xattr "trusted.common" $dir)
9092         [[ "$found" == "$dir/$tfile.symlink" ]] || {
9093                 getfattr --no-dereference -d -m trusted.* $dir/$tfile.symlink
9094                 error "should have found '$tfile.symlink' with xattr 'trusted.test=test_link', got '$found'"
9095         }
9096
9097         rm -f $dir/*
9098
9099         touch $dir/$tfile.1
9100         touch $dir/$tfile.2
9101         setfattr -n "user.test" -v "1" $dir/$tfile.1
9102         setfattr -n "user.test" -v "2" $dir/$tfile.2
9103         setfattr -n "user.test2" -v "common" $dir/$tfile.{1,2}
9104
9105         found=$($LFS find -xattr "user.*=common" -xattr "user.test=1" $dir)
9106         [[ "$found" == "$dir/$tfile.1" ]] || {
9107                 getfattr -d $dir/$tfile.1
9108                 error "should have found '$tfile.1' with xattr user.test=1', got '$found'"
9109         }
9110
9111         found=$($LFS find -xattr "user.*=common" ! -xattr "user.test=1" $dir)
9112         [[ "$found" == "$dir/$tfile.2" ]] || {
9113                 getfattr -d $dir/$tfile.2
9114                 error "should have found '$tfile.2' without xattr 'user.test=1', got '$found'"
9115         }
9116
9117         setfattr -n "user.empty" $dir/$tfile.1
9118         found=$($LFS find -xattr "user.empty" $dir)
9119         [[ "$found" == "$dir/$tfile.1" ]] || {
9120                 getfattr -d $dir/$tfile.1
9121                 error "should have found '$tfile.1' with xattr 'user.empty=', got '$found'"
9122         }
9123
9124         # setfattr command normally does not store terminating null byte
9125         # when writing a string as an xattr value.
9126         #
9127         # In order to test matching a value string that includes a terminating
9128         # null, explicitly encode the string "test\0" with the null terminator.
9129         setfattr -n "user.test" -v "0x7465737400" $dir/$tfile.1
9130         found=$($LFS find -xattr "user.test=test" $dir)
9131         [[ "$found" == "$dir/$tfile.1" ]] || {
9132                 getfattr -d --encoding=hex $dir/$tfile.1
9133                 error "should have found '$tfile.1' with xattr 'user.test=0x7465737400', got '$found'"
9134         }
9135 }
9136 run_test 56eg "lfs find -xattr"
9137
9138 test_57a() {
9139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9140         # note test will not do anything if MDS is not local
9141         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9142                 skip_env "ldiskfs only test"
9143         fi
9144         remote_mds_nodsh && skip "remote MDS with nodsh"
9145
9146         local MNTDEV="osd*.*MDT*.mntdev"
9147         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9148         [ -z "$DEV" ] && error "can't access $MNTDEV"
9149         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9150                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9151                         error "can't access $DEV"
9152                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9153                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9154                 rm $TMP/t57a.dump
9155         done
9156 }
9157 run_test 57a "verify MDS filesystem created with large inodes =="
9158
9159 test_57b() {
9160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9161         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9162                 skip_env "ldiskfs only test"
9163         fi
9164         remote_mds_nodsh && skip "remote MDS with nodsh"
9165
9166         local dir=$DIR/$tdir
9167         local filecount=100
9168         local file1=$dir/f1
9169         local fileN=$dir/f$filecount
9170
9171         rm -rf $dir || error "removing $dir"
9172         test_mkdir -c1 $dir
9173         local mdtidx=$($LFS getstripe -m $dir)
9174         local mdtname=MDT$(printf %04x $mdtidx)
9175         local facet=mds$((mdtidx + 1))
9176
9177         echo "mcreating $filecount files"
9178         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9179
9180         # verify that files do not have EAs yet
9181         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9182                 error "$file1 has an EA"
9183         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9184                 error "$fileN has an EA"
9185
9186         sync
9187         sleep 1
9188         df $dir  #make sure we get new statfs data
9189         local mdsfree=$(do_facet $facet \
9190                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9191         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9192         local file
9193
9194         echo "opening files to create objects/EAs"
9195         for file in $(seq -f $dir/f%g 1 $filecount); do
9196                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9197                         error "opening $file"
9198         done
9199
9200         # verify that files have EAs now
9201         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9202                 error "$file1 missing EA"
9203         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9204                 error "$fileN missing EA"
9205
9206         sleep 1  #make sure we get new statfs data
9207         df $dir
9208         local mdsfree2=$(do_facet $facet \
9209                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9210         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9211
9212         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9213                 if [ "$mdsfree" != "$mdsfree2" ]; then
9214                         error "MDC before $mdcfree != after $mdcfree2"
9215                 else
9216                         echo "MDC before $mdcfree != after $mdcfree2"
9217                         echo "unable to confirm if MDS has large inodes"
9218                 fi
9219         fi
9220         rm -rf $dir
9221 }
9222 run_test 57b "default LOV EAs are stored inside large inodes ==="
9223
9224 test_58() {
9225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9226         [ -z "$(which wiretest 2>/dev/null)" ] &&
9227                         skip_env "could not find wiretest"
9228
9229         wiretest
9230 }
9231 run_test 58 "verify cross-platform wire constants =============="
9232
9233 test_59() {
9234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9235
9236         echo "touch 130 files"
9237         createmany -o $DIR/f59- 130
9238         echo "rm 130 files"
9239         unlinkmany $DIR/f59- 130
9240         sync
9241         # wait for commitment of removal
9242         wait_delete_completed
9243 }
9244 run_test 59 "verify cancellation of llog records async ========="
9245
9246 TEST60_HEAD="test_60 run $RANDOM"
9247 test_60a() {
9248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9249         remote_mgs_nodsh && skip "remote MGS with nodsh"
9250         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9251                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9252                         skip_env "missing subtest run-llog.sh"
9253
9254         log "$TEST60_HEAD - from kernel mode"
9255         do_facet mgs "$LCTL dk > /dev/null"
9256         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9257         do_facet mgs $LCTL dk > $TMP/$tfile
9258
9259         # LU-6388: test llog_reader
9260         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9261         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9262         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9263                         skip_env "missing llog_reader"
9264         local fstype=$(facet_fstype mgs)
9265         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9266                 skip_env "Only for ldiskfs or zfs type mgs"
9267
9268         local mntpt=$(facet_mntpt mgs)
9269         local mgsdev=$(mgsdevname 1)
9270         local fid_list
9271         local fid
9272         local rec_list
9273         local rec
9274         local rec_type
9275         local obj_file
9276         local path
9277         local seq
9278         local oid
9279         local pass=true
9280
9281         #get fid and record list
9282         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9283                 tail -n 4))
9284         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9285                 tail -n 4))
9286         #remount mgs as ldiskfs or zfs type
9287         stop mgs || error "stop mgs failed"
9288         mount_fstype mgs || error "remount mgs failed"
9289         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9290                 fid=${fid_list[i]}
9291                 rec=${rec_list[i]}
9292                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9293                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9294                 oid=$((16#$oid))
9295
9296                 case $fstype in
9297                         ldiskfs )
9298                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9299                         zfs )
9300                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9301                 esac
9302                 echo "obj_file is $obj_file"
9303                 do_facet mgs $llog_reader $obj_file
9304
9305                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9306                         awk '{ print $3 }' | sed -e "s/^type=//g")
9307                 if [ $rec_type != $rec ]; then
9308                         echo "FAILED test_60a wrong record type $rec_type," \
9309                               "should be $rec"
9310                         pass=false
9311                         break
9312                 fi
9313
9314                 #check obj path if record type is LLOG_LOGID_MAGIC
9315                 if [ "$rec" == "1064553b" ]; then
9316                         path=$(do_facet mgs $llog_reader $obj_file |
9317                                 grep "path=" | awk '{ print $NF }' |
9318                                 sed -e "s/^path=//g")
9319                         if [ $obj_file != $mntpt/$path ]; then
9320                                 echo "FAILED test_60a wrong obj path" \
9321                                       "$montpt/$path, should be $obj_file"
9322                                 pass=false
9323                                 break
9324                         fi
9325                 fi
9326         done
9327         rm -f $TMP/$tfile
9328         #restart mgs before "error", otherwise it will block the next test
9329         stop mgs || error "stop mgs failed"
9330         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9331         $pass || error "test failed, see FAILED test_60a messages for specifics"
9332 }
9333 run_test 60a "llog_test run from kernel module and test llog_reader"
9334
9335 test_60b() { # bug 6411
9336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9337
9338         dmesg > $DIR/$tfile
9339         LLOG_COUNT=$(do_facet mgs dmesg |
9340                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9341                           /llog_[a-z]*.c:[0-9]/ {
9342                                 if (marker)
9343                                         from_marker++
9344                                 from_begin++
9345                           }
9346                           END {
9347                                 if (marker)
9348                                         print from_marker
9349                                 else
9350                                         print from_begin
9351                           }")
9352
9353         [[ $LLOG_COUNT -gt 120 ]] &&
9354                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9355 }
9356 run_test 60b "limit repeated messages from CERROR/CWARN"
9357
9358 test_60c() {
9359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9360
9361         echo "create 5000 files"
9362         createmany -o $DIR/f60c- 5000
9363 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9364         lctl set_param fail_loc=0x80000137
9365         unlinkmany $DIR/f60c- 5000
9366         lctl set_param fail_loc=0
9367 }
9368 run_test 60c "unlink file when mds full"
9369
9370 test_60d() {
9371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9372
9373         SAVEPRINTK=$(lctl get_param -n printk)
9374         # verify "lctl mark" is even working"
9375         MESSAGE="test message ID $RANDOM $$"
9376         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9377         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9378
9379         lctl set_param printk=0 || error "set lnet.printk failed"
9380         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9381         MESSAGE="new test message ID $RANDOM $$"
9382         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9383         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9384         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9385
9386         lctl set_param -n printk="$SAVEPRINTK"
9387 }
9388 run_test 60d "test printk console message masking"
9389
9390 test_60e() {
9391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9392         remote_mds_nodsh && skip "remote MDS with nodsh"
9393
9394         touch $DIR/$tfile
9395 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9396         do_facet mds1 lctl set_param fail_loc=0x15b
9397         rm $DIR/$tfile
9398 }
9399 run_test 60e "no space while new llog is being created"
9400
9401 test_60f() {
9402         local old_path=$($LCTL get_param -n debug_path)
9403
9404         stack_trap "$LCTL set_param debug_path=$old_path"
9405         stack_trap "rm -f $TMP/$tfile*"
9406         rm -f $TMP/$tfile* 2> /dev/null
9407         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9408         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9409         test_mkdir $DIR/$tdir
9410         # retry in case the open is cached and not released
9411         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9412                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9413                 sleep 0.1
9414         done
9415         ls $TMP/$tfile*
9416         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9417 }
9418 run_test 60f "change debug_path works"
9419
9420 test_60g() {
9421         local pid
9422         local i
9423
9424         test_mkdir -c $MDSCOUNT $DIR/$tdir
9425
9426         (
9427                 local index=0
9428                 while true; do
9429                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9430                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9431                                 2>/dev/null
9432                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9433                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9434                         index=$((index + 1))
9435                 done
9436         ) &
9437
9438         pid=$!
9439
9440         for i in {0..100}; do
9441                 # define OBD_FAIL_OSD_TXN_START    0x19a
9442                 local index=$((i % MDSCOUNT + 1))
9443
9444                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9445                         > /dev/null
9446                 sleep 0.01
9447         done
9448
9449         kill -9 $pid
9450
9451         for i in $(seq $MDSCOUNT); do
9452                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9453         done
9454
9455         mkdir $DIR/$tdir/new || error "mkdir failed"
9456         rmdir $DIR/$tdir/new || error "rmdir failed"
9457
9458         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9459                 -t namespace
9460         for i in $(seq $MDSCOUNT); do
9461                 wait_update_facet mds$i "$LCTL get_param -n \
9462                         mdd.$(facet_svc mds$i).lfsck_namespace |
9463                         awk '/^status/ { print \\\$2 }'" "completed"
9464         done
9465
9466         ls -R $DIR/$tdir
9467         rm -rf $DIR/$tdir || error "rmdir failed"
9468 }
9469 run_test 60g "transaction abort won't cause MDT hung"
9470
9471 test_60h() {
9472         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9473                 skip "Need MDS version at least 2.12.52"
9474         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9475
9476         local f
9477
9478         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9479         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9480         for fail_loc in 0x80000188 0x80000189; do
9481                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9482                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9483                         error "mkdir $dir-$fail_loc failed"
9484                 for i in {0..10}; do
9485                         # create may fail on missing stripe
9486                         echo $i > $DIR/$tdir-$fail_loc/$i
9487                 done
9488                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9489                         error "getdirstripe $tdir-$fail_loc failed"
9490                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9491                         error "migrate $tdir-$fail_loc failed"
9492                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9493                         error "getdirstripe $tdir-$fail_loc failed"
9494                 pushd $DIR/$tdir-$fail_loc
9495                 for f in *; do
9496                         echo $f | cmp $f - || error "$f data mismatch"
9497                 done
9498                 popd
9499                 rm -rf $DIR/$tdir-$fail_loc
9500         done
9501 }
9502 run_test 60h "striped directory with missing stripes can be accessed"
9503
9504 function t60i_load() {
9505         mkdir $DIR/$tdir
9506         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9507         $LCTL set_param fail_loc=0x131c fail_val=1
9508         for ((i=0; i<5000; i++)); do
9509                 touch $DIR/$tdir/f$i
9510         done
9511 }
9512
9513 test_60i() {
9514         changelog_register || error "changelog_register failed"
9515         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9516         changelog_users $SINGLEMDS | grep -q $cl_user ||
9517                 error "User $cl_user not found in changelog_users"
9518         changelog_chmask "ALL"
9519         t60i_load &
9520         local PID=$!
9521         for((i=0; i<100; i++)); do
9522                 changelog_dump >/dev/null ||
9523                         error "can't read changelog"
9524         done
9525         kill $PID
9526         wait $PID
9527         changelog_deregister || error "changelog_deregister failed"
9528         $LCTL set_param fail_loc=0
9529 }
9530 run_test 60i "llog: new record vs reader race"
9531
9532 test_60j() {
9533         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9534                 skip "need MDS version at least 2.15.50"
9535         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9536         remote_mds_nodsh && skip "remote MDS with nodsh"
9537         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9538
9539         changelog_users $SINGLEMDS | grep "^cl" &&
9540                 skip "active changelog user"
9541
9542         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9543
9544         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9545                 skip_env "missing llog_reader"
9546
9547         mkdir_on_mdt0 $DIR/$tdir
9548
9549         local f=$DIR/$tdir/$tfile
9550         local mdt_dev
9551         local tmpfile
9552         local plain
9553
9554         changelog_register || error "cannot register changelog user"
9555
9556         # set changelog_mask to ALL
9557         changelog_chmask "ALL"
9558         changelog_clear
9559
9560         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9561         unlinkmany ${f}- 100 || error "unlinkmany failed"
9562
9563         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9564         mdt_dev=$(facet_device $SINGLEMDS)
9565
9566         do_facet $SINGLEMDS sync
9567         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9568                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9569                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9570
9571         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9572
9573         # if $tmpfile is not on EXT3 filesystem for some reason
9574         [[ ${plain:0:1} == 'O' ]] ||
9575                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9576
9577         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9578                 $mdt_dev; stat -c %s $tmpfile")
9579         echo "Truncate llog from $size to $((size - size % 8192))"
9580         size=$((size - size % 8192))
9581         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9582         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9583                 grep -c 'in bitmap only')
9584         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9585
9586         size=$((size - 9000))
9587         echo "Corrupt llog in the middle at $size"
9588         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9589                 count=333 conv=notrunc
9590         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9591                 grep -c 'next chunk')
9592         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9593 }
9594 run_test 60j "llog_reader reports corruptions"
9595
9596 test_61a() {
9597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9598
9599         f="$DIR/f61"
9600         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9601         cancel_lru_locks osc
9602         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9603         sync
9604 }
9605 run_test 61a "mmap() writes don't make sync hang ================"
9606
9607 test_61b() {
9608         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9609 }
9610 run_test 61b "mmap() of unstriped file is successful"
9611
9612 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9613 # Though this test is irrelevant anymore, it helped to reveal some
9614 # other grant bugs (LU-4482), let's keep it.
9615 test_63a() {   # was test_63
9616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9617
9618         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9619
9620         for i in `seq 10` ; do
9621                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9622                 sleep 5
9623                 kill $!
9624                 sleep 1
9625         done
9626
9627         rm -f $DIR/f63 || true
9628 }
9629 run_test 63a "Verify oig_wait interruption does not crash ======="
9630
9631 # bug 2248 - async write errors didn't return to application on sync
9632 # bug 3677 - async write errors left page locked
9633 test_63b() {
9634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9635
9636         debugsave
9637         lctl set_param debug=-1
9638
9639         # ensure we have a grant to do async writes
9640         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9641         rm $DIR/$tfile
9642
9643         sync    # sync lest earlier test intercept the fail_loc
9644
9645         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9646         lctl set_param fail_loc=0x80000406
9647         $MULTIOP $DIR/$tfile Owy && \
9648                 error "sync didn't return ENOMEM"
9649         sync; sleep 2; sync     # do a real sync this time to flush page
9650         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9651                 error "locked page left in cache after async error" || true
9652         debugrestore
9653 }
9654 run_test 63b "async write errors should be returned to fsync ==="
9655
9656 test_64a () {
9657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9658
9659         lfs df $DIR
9660         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9661 }
9662 run_test 64a "verify filter grant calculations (in kernel) ====="
9663
9664 test_64b () {
9665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9666
9667         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9668 }
9669 run_test 64b "check out-of-space detection on client"
9670
9671 test_64c() {
9672         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9673 }
9674 run_test 64c "verify grant shrink"
9675
9676 import_param() {
9677         local tgt=$1
9678         local param=$2
9679
9680         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9681 }
9682
9683 # this does exactly what osc_request.c:osc_announce_cached() does in
9684 # order to calculate max amount of grants to ask from server
9685 want_grant() {
9686         local tgt=$1
9687
9688         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9689         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9690
9691         ((rpc_in_flight++));
9692         nrpages=$((nrpages * rpc_in_flight))
9693
9694         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9695
9696         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9697
9698         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9699         local undirty=$((nrpages * PAGE_SIZE))
9700
9701         local max_extent_pages
9702         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9703         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9704         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9705         local grant_extent_tax
9706         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9707
9708         undirty=$((undirty + nrextents * grant_extent_tax))
9709
9710         echo $undirty
9711 }
9712
9713 # this is size of unit for grant allocation. It should be equal to
9714 # what tgt_grant.c:tgt_grant_chunk() calculates
9715 grant_chunk() {
9716         local tgt=$1
9717         local max_brw_size
9718         local grant_extent_tax
9719
9720         max_brw_size=$(import_param $tgt max_brw_size)
9721
9722         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9723
9724         echo $(((max_brw_size + grant_extent_tax) * 2))
9725 }
9726
9727 test_64d() {
9728         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9729                 skip "OST < 2.10.55 doesn't limit grants enough"
9730
9731         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9732
9733         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9734                 skip "no grant_param connect flag"
9735
9736         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9737
9738         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9739         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9740
9741
9742         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9743         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9744
9745         $LFS setstripe $DIR/$tfile -i 0 -c 1
9746         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9747         ddpid=$!
9748
9749         while kill -0 $ddpid; do
9750                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9751
9752                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9753                         kill $ddpid
9754                         error "cur_grant $cur_grant > $max_cur_granted"
9755                 fi
9756
9757                 sleep 1
9758         done
9759 }
9760 run_test 64d "check grant limit exceed"
9761
9762 check_grants() {
9763         local tgt=$1
9764         local expected=$2
9765         local msg=$3
9766         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9767
9768         ((cur_grants == expected)) ||
9769                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9770 }
9771
9772 round_up_p2() {
9773         echo $((($1 + $2 - 1) & ~($2 - 1)))
9774 }
9775
9776 test_64e() {
9777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9778         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9779                 skip "Need OSS version at least 2.11.56"
9780
9781         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9782         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9783         $LCTL set_param debug=+cache
9784
9785         # Remount client to reset grant
9786         remount_client $MOUNT || error "failed to remount client"
9787         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9788
9789         local init_grants=$(import_param $osc_tgt initial_grant)
9790
9791         check_grants $osc_tgt $init_grants "init grants"
9792
9793         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9794         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9795         local gbs=$(import_param $osc_tgt grant_block_size)
9796
9797         # write random number of bytes from max_brw_size / 4 to max_brw_size
9798         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9799         # align for direct io
9800         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9801         # round to grant consumption unit
9802         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9803
9804         local grants=$((wb_round_up + extent_tax))
9805
9806         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9807         stack_trap "rm -f $DIR/$tfile"
9808
9809         # define OBD_FAIL_TGT_NO_GRANT 0x725
9810         # make the server not grant more back
9811         do_facet ost1 $LCTL set_param fail_loc=0x725
9812         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9813
9814         do_facet ost1 $LCTL set_param fail_loc=0
9815
9816         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9817
9818         rm -f $DIR/$tfile || error "rm failed"
9819
9820         # Remount client to reset grant
9821         remount_client $MOUNT || error "failed to remount client"
9822         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9823
9824         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9825
9826         # define OBD_FAIL_TGT_NO_GRANT 0x725
9827         # make the server not grant more back
9828         do_facet ost1 $LCTL set_param fail_loc=0x725
9829         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9830         do_facet ost1 $LCTL set_param fail_loc=0
9831
9832         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9833 }
9834 run_test 64e "check grant consumption (no grant allocation)"
9835
9836 test_64f() {
9837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9838
9839         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9840         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9841         $LCTL set_param debug=+cache
9842
9843         # Remount client to reset grant
9844         remount_client $MOUNT || error "failed to remount client"
9845         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9846
9847         local init_grants=$(import_param $osc_tgt initial_grant)
9848         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9849         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9850         local gbs=$(import_param $osc_tgt grant_block_size)
9851         local chunk=$(grant_chunk $osc_tgt)
9852
9853         # write random number of bytes from max_brw_size / 4 to max_brw_size
9854         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9855         # align for direct io
9856         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9857         # round to grant consumption unit
9858         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9859
9860         local grants=$((wb_round_up + extent_tax))
9861
9862         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9863         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9864                 error "error writing to $DIR/$tfile"
9865
9866         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9867                 "direct io with grant allocation"
9868
9869         rm -f $DIR/$tfile || error "rm failed"
9870
9871         # Remount client to reset grant
9872         remount_client $MOUNT || error "failed to remount client"
9873         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9874
9875         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9876
9877         # Testing that buffered IO consumes grant on the client
9878
9879         # Delay the RPC on the server so it's guaranteed to not complete even
9880         # if the RPC is sent from the client
9881         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9882         $LCTL set_param fail_loc=0x50a fail_val=3
9883         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9884                 error "error writing to $DIR/$tfile with buffered IO"
9885
9886         check_grants $osc_tgt $((init_grants - grants)) \
9887                 "buffered io, not write rpc"
9888
9889         # Clear the fail loc and do a sync on the client
9890         $LCTL set_param fail_loc=0 fail_val=0
9891         sync
9892
9893         # RPC is now known to have sent
9894         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9895                 "buffered io, one RPC"
9896 }
9897 run_test 64f "check grant consumption (with grant allocation)"
9898
9899 test_64g() {
9900         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9901                 skip "Need MDS version at least 2.14.56"
9902
9903         local mdts=$(comma_list $(mdts_nodes))
9904
9905         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9906                         tr '\n' ' ')
9907         stack_trap "$LCTL set_param $old"
9908
9909         # generate dirty pages and increase dirty granted on MDT
9910         stack_trap "rm -f $DIR/$tfile-*"
9911         for (( i = 0; i < 10; i++)); do
9912                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9913                         error "can't set stripe"
9914                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9915                         error "can't dd"
9916                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9917                         $LFS getstripe $DIR/$tfile-$i
9918                         error "not DoM file"
9919                 }
9920         done
9921
9922         # flush dirty pages
9923         sync
9924
9925         # wait until grant shrink reset grant dirty on MDTs
9926         for ((i = 0; i < 120; i++)); do
9927                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9928                         awk '{sum=sum+$1} END {print sum}')
9929                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9930                 echo "$grant_dirty grants, $vm_dirty pages"
9931                 (( grant_dirty + vm_dirty == 0 )) && break
9932                 (( i == 3 )) && sync &&
9933                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9934                 sleep 1
9935         done
9936
9937         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9938                 awk '{sum=sum+$1} END {print sum}')
9939         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9940 }
9941 run_test 64g "grant shrink on MDT"
9942
9943 test_64h() {
9944         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9945                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9946
9947         local instance=$($LFS getname -i $DIR)
9948         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9949         local num_exps=$(do_facet ost1 \
9950             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9951         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9952         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9953         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9954
9955         # 10MiB is for file to be written, max_brw_size * 16 *
9956         # num_exps is space reserve so that tgt_grant_shrink() decided
9957         # to not shrink
9958         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9959         (( avail * 1024 < expect )) &&
9960                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9961
9962         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9963         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9964         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9965         $LCTL set_param osc.*OST0000*.grant_shrink=1
9966         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9967
9968         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9969         stack_trap "rm -f $DIR/$tfile"
9970         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9971
9972         # drop cache so that coming read would do rpc
9973         cancel_lru_locks osc
9974
9975         # shrink interval is set to 10, pause for 7 seconds so that
9976         # grant thread did not wake up yet but coming read entered
9977         # shrink mode for rpc (osc_should_shrink_grant())
9978         sleep 7
9979
9980         declare -a cur_grant_bytes
9981         declare -a tot_granted
9982         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9983         tot_granted[0]=$(do_facet ost1 \
9984             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9985
9986         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9987
9988         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9989         tot_granted[1]=$(do_facet ost1 \
9990             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9991
9992         # grant change should be equal on both sides
9993         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9994                 tot_granted[0] - tot_granted[1])) ||
9995                 error "grant change mismatch, "                                \
9996                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9997                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9998 }
9999 run_test 64h "grant shrink on read"
10000
10001 test_64i() {
10002         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
10003                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
10004
10005         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10006         remote_ost_nodsh && skip "remote OSTs with nodsh"
10007
10008         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10009         stack_trap "rm -f $DIR/$tfile"
10010
10011         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
10012
10013         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
10014         local instance=$($LFS getname -i $DIR)
10015
10016         local osc_tgt="$FSNAME-OST0000-osc-$instance"
10017         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
10018
10019         # shrink grants and simulate rpc loss
10020         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
10021         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
10022         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
10023
10024         fail ost1
10025
10026         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
10027
10028         local testid=$(echo $TESTNAME | tr '_' ' ')
10029
10030         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
10031                 grep "GRANT, real grant" &&
10032                 error "client has more grants then it owns" || true
10033 }
10034 run_test 64i "shrink on reconnect"
10035
10036 # bug 1414 - set/get directories' stripe info
10037 test_65a() {
10038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
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_65p () { # LU-16194
10512         local src_dir=$DIR/$tdir/src_dir
10513
10514         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10515                 skip "Need at least version 2.15.51"
10516
10517         test_mkdir -p $src_dir
10518         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10519         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10520                 error "should fail if extent start/end >=8E"
10521
10522         # EOF should work as before
10523         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10524                 error "failed to setstripe normally"
10525 }
10526 run_test 65p "setstripe with >=8E offset should fail"
10527
10528 # bug 2543 - update blocks count on client
10529 test_66() {
10530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10531
10532         local COUNT=${COUNT:-8}
10533         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10534         sync; sync_all_data; sync; sync_all_data
10535         cancel_lru_locks osc
10536         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10537         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10538 }
10539 run_test 66 "update inode blocks count on client ==============="
10540
10541 meminfo() {
10542         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10543 }
10544
10545 swap_used() {
10546         swapon -s | awk '($1 == "'$1'") { print $4 }'
10547 }
10548
10549 # bug5265, obdfilter oa2dentry return -ENOENT
10550 # #define OBD_FAIL_SRV_ENOENT 0x217
10551 test_69() {
10552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10553         remote_ost_nodsh && skip "remote OST with nodsh"
10554
10555         f="$DIR/$tfile"
10556         $LFS setstripe -c 1 -i 0 $f
10557         stack_trap "rm -f $f ${f}.2"
10558
10559         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10560
10561         do_facet ost1 lctl set_param fail_loc=0x217
10562         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10563         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10564
10565         do_facet ost1 lctl set_param fail_loc=0
10566         $DIRECTIO write $f 0 2 || error "write error"
10567
10568         cancel_lru_locks osc
10569         $DIRECTIO read $f 0 1 || error "read error"
10570
10571         do_facet ost1 lctl set_param fail_loc=0x217
10572         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10573
10574         do_facet ost1 lctl set_param fail_loc=0
10575 }
10576 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10577
10578 test_70a() {
10579         # Perform a really simple test of health write and health check
10580         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10581                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10582
10583         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10584
10585         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10586
10587         # Test with health write off
10588         do_facet ost1 $LCTL set_param enable_health_write off ||
10589                 error "can't set enable_health_write off"
10590         do_facet ost1 $LCTL get_param enable_health_write ||
10591                 error "can't get enable_health_write"
10592
10593         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10594                 error "not healthy (1)"
10595
10596         # Test with health write on
10597         do_facet ost1 $LCTL set_param enable_health_write on ||
10598                 error "can't set enable_health_write on"
10599         do_facet ost1 $LCTL get_param enable_health_write ||
10600                 error "can't get enable_health_write"
10601
10602         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10603                 error "not healthy (2)"
10604 }
10605 run_test 70a "verify health_check, health_write don't explode (on OST)"
10606
10607 test_71() {
10608         test_mkdir $DIR/$tdir
10609         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10610         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10611 }
10612 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10613
10614 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10616         [ "$RUNAS_ID" = "$UID" ] &&
10617                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10618         # Check that testing environment is properly set up. Skip if not
10619         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10620                 skip_env "User $RUNAS_ID does not exist - skipping"
10621
10622         touch $DIR/$tfile
10623         chmod 777 $DIR/$tfile
10624         chmod ug+s $DIR/$tfile
10625         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10626                 error "$RUNAS dd $DIR/$tfile failed"
10627         # See if we are still setuid/sgid
10628         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10629                 error "S/gid is not dropped on write"
10630         # Now test that MDS is updated too
10631         cancel_lru_locks mdc
10632         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10633                 error "S/gid is not dropped on MDS"
10634         rm -f $DIR/$tfile
10635 }
10636 run_test 72a "Test that remove suid works properly (bug5695) ===="
10637
10638 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10639         local perm
10640
10641         [ "$RUNAS_ID" = "$UID" ] &&
10642                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10643         [ "$RUNAS_ID" -eq 0 ] &&
10644                 skip_env "RUNAS_ID = 0 -- skipping"
10645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10646         # Check that testing environment is properly set up. Skip if not
10647         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10648                 skip_env "User $RUNAS_ID does not exist - skipping"
10649
10650         touch $DIR/${tfile}-f{g,u}
10651         test_mkdir $DIR/${tfile}-dg
10652         test_mkdir $DIR/${tfile}-du
10653         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10654         chmod g+s $DIR/${tfile}-{f,d}g
10655         chmod u+s $DIR/${tfile}-{f,d}u
10656         for perm in 777 2777 4777; do
10657                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10658                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10659                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10660                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10661         done
10662         true
10663 }
10664 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10665
10666 # bug 3462 - multiple simultaneous MDC requests
10667 test_73() {
10668         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10669
10670         test_mkdir $DIR/d73-1
10671         test_mkdir $DIR/d73-2
10672         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10673         pid1=$!
10674
10675         lctl set_param fail_loc=0x80000129
10676         $MULTIOP $DIR/d73-1/f73-2 Oc &
10677         sleep 1
10678         lctl set_param fail_loc=0
10679
10680         $MULTIOP $DIR/d73-2/f73-3 Oc &
10681         pid3=$!
10682
10683         kill -USR1 $pid1
10684         wait $pid1 || return 1
10685
10686         sleep 25
10687
10688         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10689         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10690         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10691
10692         rm -rf $DIR/d73-*
10693 }
10694 run_test 73 "multiple MDC requests (should not deadlock)"
10695
10696 test_74a() { # bug 6149, 6184
10697         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10698
10699         touch $DIR/f74a
10700         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10701         #
10702         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10703         # will spin in a tight reconnection loop
10704         $LCTL set_param fail_loc=0x8000030e
10705         # get any lock that won't be difficult - lookup works.
10706         ls $DIR/f74a
10707         $LCTL set_param fail_loc=0
10708         rm -f $DIR/f74a
10709         true
10710 }
10711 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10712
10713 test_74b() { # bug 13310
10714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10715
10716         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10717         #
10718         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10719         # will spin in a tight reconnection loop
10720         $LCTL set_param fail_loc=0x8000030e
10721         # get a "difficult" lock
10722         touch $DIR/f74b
10723         $LCTL set_param fail_loc=0
10724         rm -f $DIR/f74b
10725         true
10726 }
10727 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10728
10729 test_74c() {
10730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10731
10732         #define OBD_FAIL_LDLM_NEW_LOCK
10733         $LCTL set_param fail_loc=0x319
10734         touch $DIR/$tfile && error "touch successful"
10735         $LCTL set_param fail_loc=0
10736         true
10737 }
10738 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10739
10740 slab_lic=/sys/kernel/slab/lustre_inode_cache
10741 num_objects() {
10742         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10743         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10744                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10745 }
10746
10747 test_76a() { # Now for b=20433, added originally in b=1443
10748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10749
10750         cancel_lru_locks osc
10751         # there may be some slab objects cached per core
10752         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10753         local before=$(num_objects)
10754         local count=$((512 * cpus))
10755         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10756         local margin=$((count / 10))
10757         if [[ -f $slab_lic/aliases ]]; then
10758                 local aliases=$(cat $slab_lic/aliases)
10759                 (( aliases > 0 )) && margin=$((margin * aliases))
10760         fi
10761
10762         echo "before slab objects: $before"
10763         for i in $(seq $count); do
10764                 touch $DIR/$tfile
10765                 rm -f $DIR/$tfile
10766         done
10767         cancel_lru_locks osc
10768         local after=$(num_objects)
10769         echo "created: $count, after slab objects: $after"
10770         # shared slab counts are not very accurate, allow significant margin
10771         # the main goal is that the cache growth is not permanently > $count
10772         while (( after > before + margin )); do
10773                 sleep 1
10774                 after=$(num_objects)
10775                 wait=$((wait + 1))
10776                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10777                 if (( wait > 60 )); then
10778                         error "inode slab grew from $before+$margin to $after"
10779                 fi
10780         done
10781 }
10782 run_test 76a "confirm clients recycle inodes properly ===="
10783
10784 test_76b() {
10785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10786         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10787
10788         local count=512
10789         local before=$(num_objects)
10790
10791         for i in $(seq $count); do
10792                 mkdir $DIR/$tdir
10793                 rmdir $DIR/$tdir
10794         done
10795
10796         local after=$(num_objects)
10797         local wait=0
10798
10799         while (( after > before )); do
10800                 sleep 1
10801                 after=$(num_objects)
10802                 wait=$((wait + 1))
10803                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10804                 if (( wait > 60 )); then
10805                         error "inode slab grew from $before to $after"
10806                 fi
10807         done
10808
10809         echo "slab objects before: $before, after: $after"
10810 }
10811 run_test 76b "confirm clients recycle directory inodes properly ===="
10812
10813 export ORIG_CSUM=""
10814 set_checksums()
10815 {
10816         # Note: in sptlrpc modes which enable its own bulk checksum, the
10817         # original crc32_le bulk checksum will be automatically disabled,
10818         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10819         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10820         # In this case set_checksums() will not be no-op, because sptlrpc
10821         # bulk checksum will be enabled all through the test.
10822
10823         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10824         lctl set_param -n osc.*.checksums $1
10825         return 0
10826 }
10827
10828 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10829                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10830 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10831                              tr -d [] | head -n1)}
10832 set_checksum_type()
10833 {
10834         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10835         rc=$?
10836         log "set checksum type to $1, rc = $rc"
10837         return $rc
10838 }
10839
10840 get_osc_checksum_type()
10841 {
10842         # arugment 1: OST name, like OST0000
10843         ost=$1
10844         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10845                         sed 's/.*\[\(.*\)\].*/\1/g')
10846         rc=$?
10847         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10848         echo $checksum_type
10849 }
10850
10851 F77_TMP=$TMP/f77-temp
10852 F77SZ=8
10853 setup_f77() {
10854         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10855                 error "error writing to $F77_TMP"
10856 }
10857
10858 test_77a() { # bug 10889
10859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10860         $GSS && skip_env "could not run with gss"
10861
10862         [ ! -f $F77_TMP ] && setup_f77
10863         set_checksums 1
10864         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10865         set_checksums 0
10866         rm -f $DIR/$tfile
10867 }
10868 run_test 77a "normal checksum read/write operation"
10869
10870 test_77b() { # bug 10889
10871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10872         $GSS && skip_env "could not run with gss"
10873
10874         [ ! -f $F77_TMP ] && setup_f77
10875         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10876         $LCTL set_param fail_loc=0x80000409
10877         set_checksums 1
10878
10879         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10880                 error "dd error: $?"
10881         $LCTL set_param fail_loc=0
10882
10883         for algo in $CKSUM_TYPES; do
10884                 cancel_lru_locks osc
10885                 set_checksum_type $algo
10886                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10887                 $LCTL set_param fail_loc=0x80000408
10888                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10889                 $LCTL set_param fail_loc=0
10890         done
10891         set_checksums 0
10892         set_checksum_type $ORIG_CSUM_TYPE
10893         rm -f $DIR/$tfile
10894 }
10895 run_test 77b "checksum error on client write, read"
10896
10897 cleanup_77c() {
10898         trap 0
10899         set_checksums 0
10900         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10901         $check_ost &&
10902                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10903         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10904         $check_ost && [ -n "$ost_file_prefix" ] &&
10905                 do_facet ost1 rm -f ${ost_file_prefix}\*
10906 }
10907
10908 test_77c() {
10909         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10910         $GSS && skip_env "could not run with gss"
10911         remote_ost_nodsh && skip "remote OST with nodsh"
10912
10913         local bad1
10914         local osc_file_prefix
10915         local osc_file
10916         local check_ost=false
10917         local ost_file_prefix
10918         local ost_file
10919         local orig_cksum
10920         local dump_cksum
10921         local fid
10922
10923         # ensure corruption will occur on first OSS/OST
10924         $LFS setstripe -i 0 $DIR/$tfile
10925
10926         [ ! -f $F77_TMP ] && setup_f77
10927         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10928                 error "dd write error: $?"
10929         fid=$($LFS path2fid $DIR/$tfile)
10930
10931         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10932         then
10933                 check_ost=true
10934                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10935                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10936         else
10937                 echo "OSS do not support bulk pages dump upon error"
10938         fi
10939
10940         osc_file_prefix=$($LCTL get_param -n debug_path)
10941         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10942
10943         trap cleanup_77c EXIT
10944
10945         set_checksums 1
10946         # enable bulk pages dump upon error on Client
10947         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10948         # enable bulk pages dump upon error on OSS
10949         $check_ost &&
10950                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10951
10952         # flush Client cache to allow next read to reach OSS
10953         cancel_lru_locks osc
10954
10955         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10956         $LCTL set_param fail_loc=0x80000408
10957         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10958         $LCTL set_param fail_loc=0
10959
10960         rm -f $DIR/$tfile
10961
10962         # check cksum dump on Client
10963         osc_file=$(ls ${osc_file_prefix}*)
10964         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10965         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10966         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10967         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10968         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10969                      cksum)
10970         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10971         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10972                 error "dump content does not match on Client"
10973
10974         $check_ost || skip "No need to check cksum dump on OSS"
10975
10976         # check cksum dump on OSS
10977         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10978         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10979         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10980         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10981         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10982                 error "dump content does not match on OSS"
10983
10984         cleanup_77c
10985 }
10986 run_test 77c "checksum error on client read with debug"
10987
10988 test_77d() { # bug 10889
10989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10990         $GSS && skip_env "could not run with gss"
10991
10992         stack_trap "rm -f $DIR/$tfile"
10993         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10994         $LCTL set_param fail_loc=0x80000409
10995         set_checksums 1
10996         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10997                 error "direct write: rc=$?"
10998         $LCTL set_param fail_loc=0
10999         set_checksums 0
11000
11001         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
11002         $LCTL set_param fail_loc=0x80000408
11003         set_checksums 1
11004         cancel_lru_locks osc
11005         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
11006                 error "direct read: rc=$?"
11007         $LCTL set_param fail_loc=0
11008         set_checksums 0
11009 }
11010 run_test 77d "checksum error on OST direct write, read"
11011
11012 test_77f() { # bug 10889
11013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11014         $GSS && skip_env "could not run with gss"
11015
11016         set_checksums 1
11017         stack_trap "rm -f $DIR/$tfile"
11018         for algo in $CKSUM_TYPES; do
11019                 cancel_lru_locks osc
11020                 set_checksum_type $algo
11021                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
11022                 $LCTL set_param fail_loc=0x409
11023                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
11024                         error "direct write succeeded"
11025                 $LCTL set_param fail_loc=0
11026         done
11027         set_checksum_type $ORIG_CSUM_TYPE
11028         set_checksums 0
11029 }
11030 run_test 77f "repeat checksum error on write (expect error)"
11031
11032 test_77g() { # bug 10889
11033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11034         $GSS && skip_env "could not run with gss"
11035         remote_ost_nodsh && skip "remote OST with nodsh"
11036
11037         [ ! -f $F77_TMP ] && setup_f77
11038
11039         local file=$DIR/$tfile
11040         stack_trap "rm -f $file" EXIT
11041
11042         $LFS setstripe -c 1 -i 0 $file
11043         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
11044         do_facet ost1 lctl set_param fail_loc=0x8000021a
11045         set_checksums 1
11046         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
11047                 error "write error: rc=$?"
11048         do_facet ost1 lctl set_param fail_loc=0
11049         set_checksums 0
11050
11051         cancel_lru_locks osc
11052         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
11053         do_facet ost1 lctl set_param fail_loc=0x8000021b
11054         set_checksums 1
11055         cmp $F77_TMP $file || error "file compare failed"
11056         do_facet ost1 lctl set_param fail_loc=0
11057         set_checksums 0
11058 }
11059 run_test 77g "checksum error on OST write, read"
11060
11061 test_77k() { # LU-10906
11062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11063         $GSS && skip_env "could not run with gss"
11064
11065         local cksum_param="osc.$FSNAME*.checksums"
11066         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
11067         local checksum
11068         local i
11069
11070         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11071         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11072         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11073
11074         for i in 0 1; do
11075                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11076                         error "failed to set checksum=$i on MGS"
11077                 wait_update $HOSTNAME "$get_checksum" $i
11078                 #remount
11079                 echo "remount client, checksum should be $i"
11080                 remount_client $MOUNT || error "failed to remount client"
11081                 checksum=$(eval $get_checksum)
11082                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11083         done
11084         # remove persistent param to avoid races with checksum mountopt below
11085         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11086                 error "failed to delete checksum on MGS"
11087
11088         for opt in "checksum" "nochecksum"; do
11089                 #remount with mount option
11090                 echo "remount client with option $opt, checksum should be $i"
11091                 umount_client $MOUNT || error "failed to umount client"
11092                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11093                         error "failed to mount client with option '$opt'"
11094                 checksum=$(eval $get_checksum)
11095                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11096                 i=$((i - 1))
11097         done
11098
11099         remount_client $MOUNT || error "failed to remount client"
11100 }
11101 run_test 77k "enable/disable checksum correctly"
11102
11103 test_77l() {
11104         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11105         $GSS && skip_env "could not run with gss"
11106
11107         set_checksums 1
11108         stack_trap "set_checksums $ORIG_CSUM" EXIT
11109         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11110
11111         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11112
11113         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11114         for algo in $CKSUM_TYPES; do
11115                 set_checksum_type $algo || error "fail to set checksum type $algo"
11116                 osc_algo=$(get_osc_checksum_type OST0000)
11117                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11118
11119                 # no locks, no reqs to let the connection idle
11120                 cancel_lru_locks osc
11121                 lru_resize_disable osc
11122                 wait_osc_import_state client ost1 IDLE
11123
11124                 # ensure ost1 is connected
11125                 stat $DIR/$tfile >/dev/null || error "can't stat"
11126                 wait_osc_import_state client ost1 FULL
11127
11128                 osc_algo=$(get_osc_checksum_type OST0000)
11129                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11130         done
11131         return 0
11132 }
11133 run_test 77l "preferred checksum type is remembered after reconnected"
11134
11135 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11136 rm -f $F77_TMP
11137 unset F77_TMP
11138
11139 test_77m() {
11140         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11141                 skip "Need at least version 2.14.52"
11142         local param=checksum_speed
11143
11144         $LCTL get_param $param || error "reading $param failed"
11145
11146         csum_speeds=$($LCTL get_param -n $param)
11147
11148         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11149                 error "known checksum types are missing"
11150 }
11151 run_test 77m "Verify checksum_speed is correctly read"
11152
11153 check_filefrag_77n() {
11154         local nr_ext=0
11155         local starts=()
11156         local ends=()
11157
11158         while read extidx a b start end rest; do
11159                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11160                         nr_ext=$(( $nr_ext + 1 ))
11161                         starts+=( ${start%..} )
11162                         ends+=( ${end%:} )
11163                 fi
11164         done < <( filefrag -sv $1 )
11165
11166         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11167         return 1
11168 }
11169
11170 test_77n() {
11171         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11172
11173         touch $DIR/$tfile
11174         $TRUNCATE $DIR/$tfile 0
11175         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11176         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11177         check_filefrag_77n $DIR/$tfile ||
11178                 skip "$tfile blocks not contiguous around hole"
11179
11180         set_checksums 1
11181         stack_trap "set_checksums $ORIG_CSUM" EXIT
11182         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11183         stack_trap "rm -f $DIR/$tfile"
11184
11185         for algo in $CKSUM_TYPES; do
11186                 if [[ "$algo" =~ ^t10 ]]; then
11187                         set_checksum_type $algo ||
11188                                 error "fail to set checksum type $algo"
11189                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11190                                 error "fail to read $tfile with $algo"
11191                 fi
11192         done
11193         rm -f $DIR/$tfile
11194         return 0
11195 }
11196 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11197
11198 test_77o() {
11199         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11200                 skip "Need MDS version at least 2.14.55"
11201         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11202                 skip "Need OST version at least 2.14.55"
11203         local ofd=obdfilter
11204         local mdt=mdt
11205
11206         # print OST checksum_type
11207         echo "$ofd.$FSNAME-*.checksum_type:"
11208         do_nodes $(comma_list $(osts_nodes)) \
11209                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11210
11211         # print MDT checksum_type
11212         echo "$mdt.$FSNAME-*.checksum_type:"
11213         do_nodes $(comma_list $(mdts_nodes)) \
11214                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11215
11216         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11217                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11218
11219         (( $o_count == $OSTCOUNT )) ||
11220                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11221
11222         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11223                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11224
11225         (( $m_count == $MDSCOUNT )) ||
11226                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11227 }
11228 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11229
11230 cleanup_test_78() {
11231         trap 0
11232         rm -f $DIR/$tfile
11233 }
11234
11235 test_78() { # bug 10901
11236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11237         remote_ost || skip_env "local OST"
11238
11239         NSEQ=5
11240         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11241         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11242         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11243         echo "MemTotal: $MEMTOTAL"
11244
11245         # reserve 256MB of memory for the kernel and other running processes,
11246         # and then take 1/2 of the remaining memory for the read/write buffers.
11247         if [ $MEMTOTAL -gt 512 ] ;then
11248                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11249         else
11250                 # for those poor memory-starved high-end clusters...
11251                 MEMTOTAL=$((MEMTOTAL / 2))
11252         fi
11253         echo "Mem to use for directio: $MEMTOTAL"
11254
11255         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11256         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11257         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11258         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11259                 head -n1)
11260         echo "Smallest OST: $SMALLESTOST"
11261         [[ $SMALLESTOST -lt 10240 ]] &&
11262                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11263
11264         trap cleanup_test_78 EXIT
11265
11266         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11267                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11268
11269         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11270         echo "File size: $F78SIZE"
11271         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11272         for i in $(seq 1 $NSEQ); do
11273                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11274                 echo directIO rdwr round $i of $NSEQ
11275                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11276         done
11277
11278         cleanup_test_78
11279 }
11280 run_test 78 "handle large O_DIRECT writes correctly ============"
11281
11282 test_79() { # bug 12743
11283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11284
11285         wait_delete_completed
11286
11287         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11288         BKFREE=$(calc_osc_kbytes kbytesfree)
11289         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11290
11291         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11292         DFTOTAL=`echo $STRING | cut -d, -f1`
11293         DFUSED=`echo $STRING  | cut -d, -f2`
11294         DFAVAIL=`echo $STRING | cut -d, -f3`
11295         DFFREE=$(($DFTOTAL - $DFUSED))
11296
11297         ALLOWANCE=$((64 * $OSTCOUNT))
11298
11299         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11300            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11301                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11302         fi
11303         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11304            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11305                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11306         fi
11307         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11308            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11309                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11310         fi
11311 }
11312 run_test 79 "df report consistency check ======================="
11313
11314 test_80() { # bug 10718
11315         remote_ost_nodsh && skip "remote OST with nodsh"
11316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11317
11318         # relax strong synchronous semantics for slow backends like ZFS
11319         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11320                 local soc="obdfilter.*.sync_lock_cancel"
11321                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11322
11323                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11324                 if [ -z "$save" ]; then
11325                         soc="obdfilter.*.sync_on_lock_cancel"
11326                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11327                 fi
11328
11329                 if [ "$save" != "never" ]; then
11330                         local hosts=$(comma_list $(osts_nodes))
11331
11332                         do_nodes $hosts $LCTL set_param $soc=never
11333                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11334                 fi
11335         fi
11336
11337         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11338         sync; sleep 1; sync
11339         local before=$(date +%s)
11340         cancel_lru_locks osc
11341         local after=$(date +%s)
11342         local diff=$((after - before))
11343         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11344
11345         rm -f $DIR/$tfile
11346 }
11347 run_test 80 "Page eviction is equally fast at high offsets too"
11348
11349 test_81a() { # LU-456
11350         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11351         remote_ost_nodsh && skip "remote OST with nodsh"
11352
11353         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11354         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11355         do_facet ost1 lctl set_param fail_loc=0x80000228
11356
11357         # write should trigger a retry and success
11358         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11359         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11360         RC=$?
11361         if [ $RC -ne 0 ] ; then
11362                 error "write should success, but failed for $RC"
11363         fi
11364 }
11365 run_test 81a "OST should retry write when get -ENOSPC ==============="
11366
11367 test_81b() { # LU-456
11368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11369         remote_ost_nodsh && skip "remote OST with nodsh"
11370
11371         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11372         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11373         do_facet ost1 lctl set_param fail_loc=0x228
11374
11375         # write should retry several times and return -ENOSPC finally
11376         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11377         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11378         RC=$?
11379         ENOSPC=28
11380         if [ $RC -ne $ENOSPC ] ; then
11381                 error "dd should fail for -ENOSPC, but succeed."
11382         fi
11383 }
11384 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11385
11386 test_99() {
11387         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11388
11389         test_mkdir $DIR/$tdir.cvsroot
11390         chown $RUNAS_ID $DIR/$tdir.cvsroot
11391
11392         cd $TMP
11393         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11394
11395         cd /etc/init.d
11396         # some versions of cvs import exit(1) when asked to import links or
11397         # files they can't read.  ignore those files.
11398         local toignore=$(find . -type l -printf '-I %f\n' -o \
11399                          ! -perm /4 -printf '-I %f\n')
11400         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11401                 $tdir.reposname vtag rtag
11402
11403         cd $DIR
11404         test_mkdir $DIR/$tdir.reposname
11405         chown $RUNAS_ID $DIR/$tdir.reposname
11406         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11407
11408         cd $DIR/$tdir.reposname
11409         $RUNAS touch foo99
11410         $RUNAS cvs add -m 'addmsg' foo99
11411         $RUNAS cvs update
11412         $RUNAS cvs commit -m 'nomsg' foo99
11413         rm -fr $DIR/$tdir.cvsroot
11414 }
11415 run_test 99 "cvs strange file/directory operations"
11416
11417 test_100() {
11418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11419         [[ "$NETTYPE" =~ tcp ]] ||
11420                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11421         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11422         remote_ost_nodsh && skip "remote OST with nodsh"
11423         remote_mds_nodsh && skip "remote MDS with nodsh"
11424         remote_servers || skip "useless for local single node setup"
11425
11426         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11427                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11428
11429                 rc=0
11430                 if (( ${LOCAL/*:/} >= 1024 )); then
11431                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11432                         ss -tna
11433                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11434                 fi
11435         done
11436         (( $rc == 0 )) || error "privileged port not found" )
11437 }
11438 run_test 100 "check local port using privileged port"
11439
11440 function get_named_value()
11441 {
11442     local tag=$1
11443
11444     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11445 }
11446
11447 test_101a() {
11448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11449
11450         local s
11451         local discard
11452         local nreads=10000
11453         local cache_limit=32
11454
11455         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11456         $LCTL set_param -n llite.*.read_ahead_stats=0
11457         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11458                               awk '/^max_cached_mb/ { print $2 }')
11459         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11460         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11461
11462         #
11463         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11464         #
11465         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11466         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11467
11468         discard=0
11469         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11470                    get_named_value 'read.but.discarded'); do
11471                         discard=$(($discard + $s))
11472         done
11473
11474         $LCTL get_param osc.*-osc*.rpc_stats
11475         $LCTL get_param llite.*.read_ahead_stats
11476
11477         # Discard is generally zero, but sometimes a few random reads line up
11478         # and trigger larger readahead, which is wasted & leads to discards.
11479         if [[ $(($discard)) -gt $nreads ]]; then
11480                 error "too many ($discard) discarded pages"
11481         fi
11482         rm -f $DIR/$tfile || true
11483 }
11484 run_test 101a "check read-ahead for random reads"
11485
11486 setup_test101bc() {
11487         test_mkdir $DIR/$tdir
11488         local ssize=$1
11489         local FILE_LENGTH=$2
11490         STRIPE_OFFSET=0
11491
11492         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11493
11494         local list=$(comma_list $(osts_nodes))
11495         set_osd_param $list '' read_cache_enable 0
11496         set_osd_param $list '' writethrough_cache_enable 0
11497
11498         trap cleanup_test101bc EXIT
11499         # prepare the read-ahead file
11500         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11501
11502         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11503                                 count=$FILE_SIZE_MB 2> /dev/null
11504
11505 }
11506
11507 cleanup_test101bc() {
11508         trap 0
11509         rm -rf $DIR/$tdir
11510         rm -f $DIR/$tfile
11511
11512         local list=$(comma_list $(osts_nodes))
11513         set_osd_param $list '' read_cache_enable 1
11514         set_osd_param $list '' writethrough_cache_enable 1
11515 }
11516
11517 ra_check_101() {
11518         local read_size=$1
11519         local stripe_size=$2
11520         local stride_length=$((stripe_size / read_size))
11521         local stride_width=$((stride_length * OSTCOUNT))
11522         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11523                                 (stride_width - stride_length) ))
11524         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11525                   get_named_value 'read.but.discarded' | calc_sum)
11526
11527         if [[ $discard -gt $discard_limit ]]; then
11528                 $LCTL get_param llite.*.read_ahead_stats
11529                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11530         else
11531                 echo "Read-ahead success for size ${read_size}"
11532         fi
11533 }
11534
11535 test_101b() {
11536         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11537         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11538
11539         local STRIPE_SIZE=1048576
11540         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11541
11542         if [ $SLOW == "yes" ]; then
11543                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11544         else
11545                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11546         fi
11547
11548         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11549
11550         # prepare the read-ahead file
11551         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11552         cancel_lru_locks osc
11553         for BIDX in 2 4 8 16 32 64 128 256
11554         do
11555                 local BSIZE=$((BIDX*4096))
11556                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11557                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11558                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11559                 $LCTL set_param -n llite.*.read_ahead_stats=0
11560                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11561                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11562                 cancel_lru_locks osc
11563                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11564         done
11565         cleanup_test101bc
11566         true
11567 }
11568 run_test 101b "check stride-io mode read-ahead ================="
11569
11570 test_101c() {
11571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11572
11573         local STRIPE_SIZE=1048576
11574         local FILE_LENGTH=$((STRIPE_SIZE*100))
11575         local nreads=10000
11576         local rsize=65536
11577         local osc_rpc_stats
11578
11579         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11580
11581         cancel_lru_locks osc
11582         $LCTL set_param osc.*.rpc_stats=0
11583         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11584         $LCTL get_param osc.*.rpc_stats
11585         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11586                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11587                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11588                 local size
11589
11590                 if [ $lines -le 20 ]; then
11591                         echo "continue debug"
11592                         continue
11593                 fi
11594                 for size in 1 2 4 8; do
11595                         local rpc=$(echo "$stats" |
11596                                     awk '($1 == "'$size':") {print $2; exit; }')
11597                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11598                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11599                 done
11600                 echo "$osc_rpc_stats check passed!"
11601         done
11602         cleanup_test101bc
11603         true
11604 }
11605 run_test 101c "check stripe_size aligned read-ahead"
11606
11607 test_101d() {
11608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11609
11610         local file=$DIR/$tfile
11611         local sz_MB=${FILESIZE_101d:-80}
11612         local ra_MB=${READAHEAD_MB:-40}
11613
11614         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11615         [ $free_MB -lt $sz_MB ] &&
11616                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11617
11618         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11619         $LFS setstripe -c -1 $file || error "setstripe failed"
11620
11621         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11622         echo Cancel LRU locks on lustre client to flush the client cache
11623         cancel_lru_locks osc
11624
11625         echo Disable read-ahead
11626         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11627         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11628         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11629         $LCTL get_param -n llite.*.max_read_ahead_mb
11630
11631         echo "Reading the test file $file with read-ahead disabled"
11632         local sz_KB=$((sz_MB * 1024 / 4))
11633         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11634         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11635         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11636         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11637                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11638
11639         echo "Cancel LRU locks on lustre client to flush the client cache"
11640         cancel_lru_locks osc
11641         echo Enable read-ahead with ${ra_MB}MB
11642         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11643
11644         echo "Reading the test file $file with read-ahead enabled"
11645         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11646                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11647
11648         echo "read-ahead disabled time read '$raOFF'"
11649         echo "read-ahead enabled time read '$raON'"
11650
11651         rm -f $file
11652         wait_delete_completed
11653
11654         # use awk for this check instead of bash because it handles decimals
11655         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11656                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11657 }
11658 run_test 101d "file read with and without read-ahead enabled"
11659
11660 test_101e() {
11661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11662
11663         local file=$DIR/$tfile
11664         local size_KB=500  #KB
11665         local count=100
11666         local bsize=1024
11667
11668         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11669         local need_KB=$((count * size_KB))
11670         [[ $free_KB -le $need_KB ]] &&
11671                 skip_env "Need free space $need_KB, have $free_KB"
11672
11673         echo "Creating $count ${size_KB}K test files"
11674         for ((i = 0; i < $count; i++)); do
11675                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11676         done
11677
11678         echo "Cancel LRU locks on lustre client to flush the client cache"
11679         cancel_lru_locks $OSC
11680
11681         echo "Reset readahead stats"
11682         $LCTL set_param -n llite.*.read_ahead_stats=0
11683
11684         for ((i = 0; i < $count; i++)); do
11685                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11686         done
11687
11688         $LCTL get_param llite.*.max_cached_mb
11689         $LCTL get_param llite.*.read_ahead_stats
11690         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11691                      get_named_value 'misses' | calc_sum)
11692
11693         for ((i = 0; i < $count; i++)); do
11694                 rm -rf $file.$i 2>/dev/null
11695         done
11696
11697         #10000 means 20% reads are missing in readahead
11698         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11699 }
11700 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11701
11702 test_101f() {
11703         which iozone || skip_env "no iozone installed"
11704
11705         local old_debug=$($LCTL get_param debug)
11706         old_debug=${old_debug#*=}
11707         $LCTL set_param debug="reada mmap"
11708
11709         # create a test file
11710         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11711
11712         echo Cancel LRU locks on lustre client to flush the client cache
11713         cancel_lru_locks osc
11714
11715         echo Reset readahead stats
11716         $LCTL set_param -n llite.*.read_ahead_stats=0
11717
11718         echo mmap read the file with small block size
11719         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11720                 > /dev/null 2>&1
11721
11722         echo checking missing pages
11723         $LCTL get_param llite.*.read_ahead_stats
11724         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11725                         get_named_value 'misses' | calc_sum)
11726
11727         $LCTL set_param debug="$old_debug"
11728         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11729         rm -f $DIR/$tfile
11730 }
11731 run_test 101f "check mmap read performance"
11732
11733 test_101g_brw_size_test() {
11734         local mb=$1
11735         local pages=$((mb * 1048576 / PAGE_SIZE))
11736         local file=$DIR/$tfile
11737
11738         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11739                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11740         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11741                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11742                         return 2
11743         done
11744
11745         stack_trap "rm -f $file" EXIT
11746         $LCTL set_param -n osc.*.rpc_stats=0
11747
11748         # 10 RPCs should be enough for the test
11749         local count=10
11750         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11751                 { error "dd write ${mb} MB blocks failed"; return 3; }
11752         cancel_lru_locks osc
11753         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11754                 { error "dd write ${mb} MB blocks failed"; return 4; }
11755
11756         # calculate number of full-sized read and write RPCs
11757         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11758                 sed -n '/pages per rpc/,/^$/p' |
11759                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11760                 END { print reads,writes }'))
11761         # allow one extra full-sized read RPC for async readahead
11762         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11763                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11764         [[ ${rpcs[1]} == $count ]] ||
11765                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11766 }
11767
11768 test_101g() {
11769         remote_ost_nodsh && skip "remote OST with nodsh"
11770
11771         local rpcs
11772         local osts=$(get_facets OST)
11773         local list=$(comma_list $(osts_nodes))
11774         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11775         local brw_size="obdfilter.*.brw_size"
11776
11777         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11778
11779         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11780
11781         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11782                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11783                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11784            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11785                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11786                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11787
11788                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11789                         suffix="M"
11790
11791                 if [[ $orig_mb -lt 16 ]]; then
11792                         save_lustre_params $osts "$brw_size" > $p
11793                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11794                                 error "set 16MB RPC size failed"
11795
11796                         echo "remount client to enable new RPC size"
11797                         remount_client $MOUNT || error "remount_client failed"
11798                 fi
11799
11800                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11801                 # should be able to set brw_size=12, but no rpc_stats for that
11802                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11803         fi
11804
11805         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11806
11807         if [[ $orig_mb -lt 16 ]]; then
11808                 restore_lustre_params < $p
11809                 remount_client $MOUNT || error "remount_client restore failed"
11810         fi
11811
11812         rm -f $p $DIR/$tfile
11813 }
11814 run_test 101g "Big bulk(4/16 MiB) readahead"
11815
11816 test_101h() {
11817         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11818
11819         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11820                 error "dd 70M file failed"
11821         echo Cancel LRU locks on lustre client to flush the client cache
11822         cancel_lru_locks osc
11823
11824         echo "Reset readahead stats"
11825         $LCTL set_param -n llite.*.read_ahead_stats 0
11826
11827         echo "Read 10M of data but cross 64M bundary"
11828         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11829         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11830                      get_named_value 'misses' | calc_sum)
11831         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11832         rm -f $p $DIR/$tfile
11833 }
11834 run_test 101h "Readahead should cover current read window"
11835
11836 test_101i() {
11837         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11838                 error "dd 10M file failed"
11839
11840         local max_per_file_mb=$($LCTL get_param -n \
11841                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11842         cancel_lru_locks osc
11843         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11844         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11845                 error "set max_read_ahead_per_file_mb to 1 failed"
11846
11847         echo "Reset readahead stats"
11848         $LCTL set_param llite.*.read_ahead_stats=0
11849
11850         dd if=$DIR/$tfile of=/dev/null bs=2M
11851
11852         $LCTL get_param llite.*.read_ahead_stats
11853         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11854                      awk '/misses/ { print $2 }')
11855         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11856         rm -f $DIR/$tfile
11857 }
11858 run_test 101i "allow current readahead to exceed reservation"
11859
11860 test_101j() {
11861         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11862                 error "setstripe $DIR/$tfile failed"
11863         local file_size=$((1048576 * 16))
11864         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11865         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11866
11867         echo Disable read-ahead
11868         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11869
11870         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11871         for blk in $PAGE_SIZE 1048576 $file_size; do
11872                 cancel_lru_locks osc
11873                 echo "Reset readahead stats"
11874                 $LCTL set_param -n llite.*.read_ahead_stats=0
11875                 local count=$(($file_size / $blk))
11876                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11877                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11878                              get_named_value 'failed.to.fast.read' | calc_sum)
11879                 $LCTL get_param -n llite.*.read_ahead_stats
11880                 [ $miss -eq $count ] || error "expected $count got $miss"
11881         done
11882
11883         rm -f $p $DIR/$tfile
11884 }
11885 run_test 101j "A complete read block should be submitted when no RA"
11886
11887 test_readahead_base() {
11888         local file=$DIR/$tfile
11889         local size=$1
11890         local iosz
11891         local ramax
11892         local ranum
11893
11894         $LCTL set_param -n llite.*.read_ahead_stats=0
11895         # The first page is not accounted into readahead
11896         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11897         iosz=$(((size + 1048575) / 1048576 * 1048576))
11898         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11899
11900         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11901         fallocate -l $size $file || error "failed to fallocate $file"
11902         cancel_lru_locks osc
11903         $MULTIOP $file or${iosz}c || error "failed to read $file"
11904         $LCTL get_param -n llite.*.read_ahead_stats
11905         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11906                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11907         (( $ranum <= $ramax )) ||
11908                 error "read-ahead pages is $ranum more than $ramax"
11909         rm -rf $file || error "failed to remove $file"
11910 }
11911
11912 test_101m()
11913 {
11914         local file=$DIR/$tfile
11915         local ramax
11916         local ranum
11917         local size
11918         local iosz
11919
11920         check_set_fallocate_or_skip
11921         stack_trap "rm -f $file" EXIT
11922
11923         test_readahead_base 4096
11924
11925         # file size: 16K = 16384
11926         test_readahead_base 16384
11927         test_readahead_base 16385
11928         test_readahead_base 16383
11929
11930         # file size: 1M + 1 = 1048576 + 1
11931         test_readahead_base 1048577
11932         # file size: 1M + 16K
11933         test_readahead_base $((1048576 + 16384))
11934
11935         # file size: stripe_size * (stripe_count - 1) + 16K
11936         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11937         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11938         # file size: stripe_size * stripe_count + 16K
11939         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11940         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11941         # file size: 2 * stripe_size * stripe_count + 16K
11942         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11943         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11944 }
11945 run_test 101m "read ahead for small file and last stripe of the file"
11946
11947 setup_test102() {
11948         test_mkdir $DIR/$tdir
11949         chown $RUNAS_ID $DIR/$tdir
11950         STRIPE_SIZE=65536
11951         STRIPE_OFFSET=1
11952         STRIPE_COUNT=$OSTCOUNT
11953         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11954
11955         trap cleanup_test102 EXIT
11956         cd $DIR
11957         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11958         cd $DIR/$tdir
11959         for num in 1 2 3 4; do
11960                 for count in $(seq 1 $STRIPE_COUNT); do
11961                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11962                                 local size=`expr $STRIPE_SIZE \* $num`
11963                                 local file=file"$num-$idx-$count"
11964                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11965                         done
11966                 done
11967         done
11968
11969         cd $DIR
11970         $1 tar cf $TMP/f102.tar $tdir --xattrs
11971 }
11972
11973 cleanup_test102() {
11974         trap 0
11975         rm -f $TMP/f102.tar
11976         rm -rf $DIR/d0.sanity/d102
11977 }
11978
11979 test_102a() {
11980         [ "$UID" != 0 ] && skip "must run as root"
11981         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11982                 skip_env "must have user_xattr"
11983
11984         [ -z "$(which setfattr 2>/dev/null)" ] &&
11985                 skip_env "could not find setfattr"
11986
11987         local testfile=$DIR/$tfile
11988
11989         touch $testfile
11990         echo "set/get xattr..."
11991         setfattr -n trusted.name1 -v value1 $testfile ||
11992                 error "setfattr -n trusted.name1=value1 $testfile failed"
11993         getfattr -n trusted.name1 $testfile 2> /dev/null |
11994           grep "trusted.name1=.value1" ||
11995                 error "$testfile missing trusted.name1=value1"
11996
11997         setfattr -n user.author1 -v author1 $testfile ||
11998                 error "setfattr -n user.author1=author1 $testfile failed"
11999         getfattr -n user.author1 $testfile 2> /dev/null |
12000           grep "user.author1=.author1" ||
12001                 error "$testfile missing trusted.author1=author1"
12002
12003         echo "listxattr..."
12004         setfattr -n trusted.name2 -v value2 $testfile ||
12005                 error "$testfile unable to set trusted.name2"
12006         setfattr -n trusted.name3 -v value3 $testfile ||
12007                 error "$testfile unable to set trusted.name3"
12008         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
12009             grep "trusted.name" | wc -l) -eq 3 ] ||
12010                 error "$testfile missing 3 trusted.name xattrs"
12011
12012         setfattr -n user.author2 -v author2 $testfile ||
12013                 error "$testfile unable to set user.author2"
12014         setfattr -n user.author3 -v author3 $testfile ||
12015                 error "$testfile unable to set user.author3"
12016         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
12017             grep "user.author" | wc -l) -eq 3 ] ||
12018                 error "$testfile missing 3 user.author xattrs"
12019
12020         echo "remove xattr..."
12021         setfattr -x trusted.name1 $testfile ||
12022                 error "$testfile error deleting trusted.name1"
12023         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
12024                 error "$testfile did not delete trusted.name1 xattr"
12025
12026         setfattr -x user.author1 $testfile ||
12027                 error "$testfile error deleting user.author1"
12028         echo "set lustre special xattr ..."
12029         $LFS setstripe -c1 $testfile
12030         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
12031                 awk -F "=" '/trusted.lov/ { print $2 }' )
12032         setfattr -n "trusted.lov" -v $lovea $testfile ||
12033                 error "$testfile doesn't ignore setting trusted.lov again"
12034         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
12035                 error "$testfile allow setting invalid trusted.lov"
12036         rm -f $testfile
12037 }
12038 run_test 102a "user xattr test =================================="
12039
12040 check_102b_layout() {
12041         local layout="$*"
12042         local testfile=$DIR/$tfile
12043
12044         echo "test layout '$layout'"
12045         $LFS setstripe $layout $testfile || error "setstripe failed"
12046         $LFS getstripe -y $testfile
12047
12048         echo "get/set/list trusted.lov xattr ..." # b=10930
12049         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
12050         [[ "$value" =~ "trusted.lov" ]] ||
12051                 error "can't get trusted.lov from $testfile"
12052         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
12053                 error "getstripe failed"
12054
12055         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
12056
12057         value=$(cut -d= -f2 <<<$value)
12058         # LU-13168: truncated xattr should fail if short lov_user_md header
12059         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
12060                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
12061         for len in $lens; do
12062                 echo "setfattr $len $testfile.2"
12063                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
12064                         [ $len -lt 66 ] && error "short xattr len=$len worked"
12065         done
12066         local stripe_size=$($LFS getstripe -S $testfile.2)
12067         local stripe_count=$($LFS getstripe -c $testfile.2)
12068         [[ $stripe_size -eq 65536 ]] ||
12069                 error "stripe size $stripe_size != 65536"
12070         [[ $stripe_count -eq $stripe_count_orig ]] ||
12071                 error "stripe count $stripe_count != $stripe_count_orig"
12072         rm $testfile $testfile.2
12073 }
12074
12075 test_102b() {
12076         [ -z "$(which setfattr 2>/dev/null)" ] &&
12077                 skip_env "could not find setfattr"
12078         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12079
12080         # check plain layout
12081         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12082
12083         # and also check composite layout
12084         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12085
12086 }
12087 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12088
12089 test_102c() {
12090         [ -z "$(which setfattr 2>/dev/null)" ] &&
12091                 skip_env "could not find setfattr"
12092         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12093
12094         # b10930: get/set/list lustre.lov xattr
12095         echo "get/set/list lustre.lov xattr ..."
12096         test_mkdir $DIR/$tdir
12097         chown $RUNAS_ID $DIR/$tdir
12098         local testfile=$DIR/$tdir/$tfile
12099         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12100                 error "setstripe failed"
12101         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12102                 error "getstripe failed"
12103         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12104         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12105
12106         local testfile2=${testfile}2
12107         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12108                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12109
12110         $RUNAS $MCREATE $testfile2
12111         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12112         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12113         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12114         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12115         [ $stripe_count -eq $STRIPECOUNT ] ||
12116                 error "stripe count $stripe_count != $STRIPECOUNT"
12117 }
12118 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12119
12120 compare_stripe_info1() {
12121         local stripe_index_all_zero=true
12122
12123         for num in 1 2 3 4; do
12124                 for count in $(seq 1 $STRIPE_COUNT); do
12125                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12126                                 local size=$((STRIPE_SIZE * num))
12127                                 local file=file"$num-$offset-$count"
12128                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12129                                 [[ $stripe_size -ne $size ]] &&
12130                                     error "$file: size $stripe_size != $size"
12131                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12132                                 # allow fewer stripes to be created, ORI-601
12133                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12134                                     error "$file: count $stripe_count != $count"
12135                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12136                                 [[ $stripe_index -ne 0 ]] &&
12137                                         stripe_index_all_zero=false
12138                         done
12139                 done
12140         done
12141         $stripe_index_all_zero &&
12142                 error "all files are being extracted starting from OST index 0"
12143         return 0
12144 }
12145
12146 have_xattrs_include() {
12147         tar --help | grep -q xattrs-include &&
12148                 echo --xattrs-include="lustre.*"
12149 }
12150
12151 test_102d() {
12152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12153         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12154
12155         XINC=$(have_xattrs_include)
12156         setup_test102
12157         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12158         cd $DIR/$tdir/$tdir
12159         compare_stripe_info1
12160 }
12161 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12162
12163 test_102f() {
12164         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12165         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12166
12167         XINC=$(have_xattrs_include)
12168         setup_test102
12169         test_mkdir $DIR/$tdir.restore
12170         cd $DIR
12171         tar cf - --xattrs $tdir | tar xf - \
12172                 -C $DIR/$tdir.restore --xattrs $XINC
12173         cd $DIR/$tdir.restore/$tdir
12174         compare_stripe_info1
12175 }
12176 run_test 102f "tar copy files, not keep osts"
12177
12178 grow_xattr() {
12179         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12180                 skip "must have user_xattr"
12181         [ -z "$(which setfattr 2>/dev/null)" ] &&
12182                 skip_env "could not find setfattr"
12183         [ -z "$(which getfattr 2>/dev/null)" ] &&
12184                 skip_env "could not find getfattr"
12185
12186         local xsize=${1:-1024}  # in bytes
12187         local file=$DIR/$tfile
12188         local value="$(generate_string $xsize)"
12189         local xbig=trusted.big
12190         local toobig=$2
12191
12192         touch $file
12193         log "save $xbig on $file"
12194         if [ -z "$toobig" ]
12195         then
12196                 setfattr -n $xbig -v $value $file ||
12197                         error "saving $xbig on $file failed"
12198         else
12199                 setfattr -n $xbig -v $value $file &&
12200                         error "saving $xbig on $file succeeded"
12201                 return 0
12202         fi
12203
12204         local orig=$(get_xattr_value $xbig $file)
12205         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12206
12207         local xsml=trusted.sml
12208         log "save $xsml on $file"
12209         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12210
12211         local new=$(get_xattr_value $xbig $file)
12212         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12213
12214         log "grow $xsml on $file"
12215         setfattr -n $xsml -v "$value" $file ||
12216                 error "growing $xsml on $file failed"
12217
12218         new=$(get_xattr_value $xbig $file)
12219         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12220         log "$xbig still valid after growing $xsml"
12221
12222         rm -f $file
12223 }
12224
12225 test_102h() { # bug 15777
12226         grow_xattr 1024
12227 }
12228 run_test 102h "grow xattr from inside inode to external block"
12229
12230 test_102ha() {
12231         large_xattr_enabled || skip_env "ea_inode feature disabled"
12232
12233         echo "setting xattr of max xattr size: $(max_xattr_size)"
12234         grow_xattr $(max_xattr_size)
12235
12236         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12237         echo "This should fail:"
12238         grow_xattr $(($(max_xattr_size) + 10)) 1
12239 }
12240 run_test 102ha "grow xattr from inside inode to external inode"
12241
12242 test_102i() { # bug 17038
12243         [ -z "$(which getfattr 2>/dev/null)" ] &&
12244                 skip "could not find getfattr"
12245
12246         touch $DIR/$tfile
12247         ln -s $DIR/$tfile $DIR/${tfile}link
12248         getfattr -n trusted.lov $DIR/$tfile ||
12249                 error "lgetxattr on $DIR/$tfile failed"
12250         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12251                 grep -i "no such attr" ||
12252                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12253         rm -f $DIR/$tfile $DIR/${tfile}link
12254 }
12255 run_test 102i "lgetxattr test on symbolic link ============"
12256
12257 test_102j() {
12258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12259         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12260
12261         XINC=$(have_xattrs_include)
12262         setup_test102 "$RUNAS"
12263         chown $RUNAS_ID $DIR/$tdir
12264         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12265         cd $DIR/$tdir/$tdir
12266         compare_stripe_info1 "$RUNAS"
12267 }
12268 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12269
12270 test_102k() {
12271         [ -z "$(which setfattr 2>/dev/null)" ] &&
12272                 skip "could not find setfattr"
12273
12274         touch $DIR/$tfile
12275         # b22187 just check that does not crash for regular file.
12276         setfattr -n trusted.lov $DIR/$tfile
12277         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12278         local test_kdir=$DIR/$tdir
12279         test_mkdir $test_kdir
12280         local default_size=$($LFS getstripe -S $test_kdir)
12281         local default_count=$($LFS getstripe -c $test_kdir)
12282         local default_offset=$($LFS getstripe -i $test_kdir)
12283         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12284                 error 'dir setstripe failed'
12285         setfattr -n trusted.lov $test_kdir
12286         local stripe_size=$($LFS getstripe -S $test_kdir)
12287         local stripe_count=$($LFS getstripe -c $test_kdir)
12288         local stripe_offset=$($LFS getstripe -i $test_kdir)
12289         [ $stripe_size -eq $default_size ] ||
12290                 error "stripe size $stripe_size != $default_size"
12291         [ $stripe_count -eq $default_count ] ||
12292                 error "stripe count $stripe_count != $default_count"
12293         [ $stripe_offset -eq $default_offset ] ||
12294                 error "stripe offset $stripe_offset != $default_offset"
12295         rm -rf $DIR/$tfile $test_kdir
12296 }
12297 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12298
12299 test_102l() {
12300         [ -z "$(which getfattr 2>/dev/null)" ] &&
12301                 skip "could not find getfattr"
12302
12303         # LU-532 trusted. xattr is invisible to non-root
12304         local testfile=$DIR/$tfile
12305
12306         touch $testfile
12307
12308         echo "listxattr as user..."
12309         chown $RUNAS_ID $testfile
12310         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12311             grep -q "trusted" &&
12312                 error "$testfile trusted xattrs are user visible"
12313
12314         return 0;
12315 }
12316 run_test 102l "listxattr size test =================================="
12317
12318 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12319         local path=$DIR/$tfile
12320         touch $path
12321
12322         listxattr_size_check $path || error "listattr_size_check $path failed"
12323 }
12324 run_test 102m "Ensure listxattr fails on small bufffer ========"
12325
12326 cleanup_test102
12327
12328 getxattr() { # getxattr path name
12329         # Return the base64 encoding of the value of xattr name on path.
12330         local path=$1
12331         local name=$2
12332
12333         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12334         # file: $path
12335         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12336         #
12337         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12338
12339         getfattr --absolute-names --encoding=base64 --name=$name $path |
12340                 awk -F= -v name=$name '$1 == name {
12341                         print substr($0, index($0, "=") + 1);
12342         }'
12343 }
12344
12345 test_102n() { # LU-4101 mdt: protect internal xattrs
12346         [ -z "$(which setfattr 2>/dev/null)" ] &&
12347                 skip "could not find setfattr"
12348         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12349         then
12350                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12351         fi
12352
12353         local file0=$DIR/$tfile.0
12354         local file1=$DIR/$tfile.1
12355         local xattr0=$TMP/$tfile.0
12356         local xattr1=$TMP/$tfile.1
12357         local namelist="lov lma lmv link fid version som hsm"
12358         local name
12359         local value
12360
12361         rm -rf $file0 $file1 $xattr0 $xattr1
12362         touch $file0 $file1
12363
12364         # Get 'before' xattrs of $file1.
12365         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12366
12367         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12368                 namelist+=" lfsck_namespace"
12369         for name in $namelist; do
12370                 # Try to copy xattr from $file0 to $file1.
12371                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12372
12373                 setfattr --name=trusted.$name --value="$value" $file1 ||
12374                         error "setxattr 'trusted.$name' failed"
12375
12376                 # Try to set a garbage xattr.
12377                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12378
12379                 if [[ x$name == "xlov" ]]; then
12380                         setfattr --name=trusted.lov --value="$value" $file1 &&
12381                         error "setxattr invalid 'trusted.lov' success"
12382                 else
12383                         setfattr --name=trusted.$name --value="$value" $file1 ||
12384                                 error "setxattr invalid 'trusted.$name' failed"
12385                 fi
12386
12387                 # Try to remove the xattr from $file1. We don't care if this
12388                 # appears to succeed or fail, we just don't want there to be
12389                 # any changes or crashes.
12390                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12391         done
12392
12393         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12394         then
12395                 name="lfsck_ns"
12396                 # Try to copy xattr from $file0 to $file1.
12397                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12398
12399                 setfattr --name=trusted.$name --value="$value" $file1 ||
12400                         error "setxattr 'trusted.$name' failed"
12401
12402                 # Try to set a garbage xattr.
12403                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12404
12405                 setfattr --name=trusted.$name --value="$value" $file1 ||
12406                         error "setxattr 'trusted.$name' failed"
12407
12408                 # Try to remove the xattr from $file1. We don't care if this
12409                 # appears to succeed or fail, we just don't want there to be
12410                 # any changes or crashes.
12411                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12412         fi
12413
12414         # Get 'after' xattrs of file1.
12415         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12416
12417         if ! diff $xattr0 $xattr1; then
12418                 error "before and after xattrs of '$file1' differ"
12419         fi
12420
12421         rm -rf $file0 $file1 $xattr0 $xattr1
12422
12423         return 0
12424 }
12425 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12426
12427 test_102p() { # LU-4703 setxattr did not check ownership
12428         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12429                 skip "MDS needs to be at least 2.5.56"
12430
12431         local testfile=$DIR/$tfile
12432
12433         touch $testfile
12434
12435         echo "setfacl as user..."
12436         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12437         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12438
12439         echo "setfattr as user..."
12440         setfacl -m "u:$RUNAS_ID:---" $testfile
12441         $RUNAS setfattr -x system.posix_acl_access $testfile
12442         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12443 }
12444 run_test 102p "check setxattr(2) correctly fails without permission"
12445
12446 test_102q() {
12447         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12448                 skip "MDS needs to be at least 2.6.92"
12449
12450         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12451 }
12452 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12453
12454 test_102r() {
12455         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12456                 skip "MDS needs to be at least 2.6.93"
12457
12458         touch $DIR/$tfile || error "touch"
12459         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12460         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12461         rm $DIR/$tfile || error "rm"
12462
12463         #normal directory
12464         mkdir -p $DIR/$tdir || error "mkdir"
12465         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12466         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12467         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12468                 error "$testfile error deleting user.author1"
12469         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12470                 grep "user.$(basename $tdir)" &&
12471                 error "$tdir did not delete user.$(basename $tdir)"
12472         rmdir $DIR/$tdir || error "rmdir"
12473
12474         #striped directory
12475         test_mkdir $DIR/$tdir
12476         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12477         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12478         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12479                 error "$testfile error deleting user.author1"
12480         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12481                 grep "user.$(basename $tdir)" &&
12482                 error "$tdir did not delete user.$(basename $tdir)"
12483         rmdir $DIR/$tdir || error "rm striped dir"
12484 }
12485 run_test 102r "set EAs with empty values"
12486
12487 test_102s() {
12488         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12489                 skip "MDS needs to be at least 2.11.52"
12490
12491         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12492
12493         save_lustre_params client "llite.*.xattr_cache" > $save
12494
12495         for cache in 0 1; do
12496                 lctl set_param llite.*.xattr_cache=$cache
12497
12498                 rm -f $DIR/$tfile
12499                 touch $DIR/$tfile || error "touch"
12500                 for prefix in lustre security system trusted user; do
12501                         # Note getxattr() may fail with 'Operation not
12502                         # supported' or 'No such attribute' depending
12503                         # on prefix and cache.
12504                         getfattr -n $prefix.n102s $DIR/$tfile &&
12505                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12506                 done
12507         done
12508
12509         restore_lustre_params < $save
12510 }
12511 run_test 102s "getting nonexistent xattrs should fail"
12512
12513 test_102t() {
12514         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12515                 skip "MDS needs to be at least 2.11.52"
12516
12517         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12518
12519         save_lustre_params client "llite.*.xattr_cache" > $save
12520
12521         for cache in 0 1; do
12522                 lctl set_param llite.*.xattr_cache=$cache
12523
12524                 for buf_size in 0 256; do
12525                         rm -f $DIR/$tfile
12526                         touch $DIR/$tfile || error "touch"
12527                         setfattr -n user.multiop $DIR/$tfile
12528                         $MULTIOP $DIR/$tfile oa$buf_size ||
12529                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12530                 done
12531         done
12532
12533         restore_lustre_params < $save
12534 }
12535 run_test 102t "zero length xattr values handled correctly"
12536
12537 run_acl_subtest()
12538 {
12539         local test=$LUSTRE/tests/acl/$1.test
12540         local tmp=$(mktemp -t $1-XXXXXX).test
12541         local bin=$2
12542         local dmn=$3
12543         local grp=$4
12544         local nbd=$5
12545         export LANG=C
12546
12547
12548         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12549         local sedgroups="-e s/:users/:$grp/g"
12550         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12551
12552         sed $sedusers $sedgroups < $test > $tmp
12553         stack_trap "rm -f $tmp"
12554         [[ -s $tmp ]] || error "sed failed to create test script"
12555
12556         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12557         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12558 }
12559
12560 test_103a() {
12561         [ "$UID" != 0 ] && skip "must run as root"
12562         $GSS && skip_env "could not run under gss"
12563         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12564                 skip_env "must have acl enabled"
12565         which setfacl || skip_env "could not find setfacl"
12566         remote_mds_nodsh && skip "remote MDS with nodsh"
12567
12568         local mdts=$(comma_list $(mdts_nodes))
12569         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12570
12571         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12572         stack_trap "[[ -z \"$saved\" ]] || \
12573                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12574
12575         ACLBIN=${ACLBIN:-"bin"}
12576         ACLDMN=${ACLDMN:-"daemon"}
12577         ACLGRP=${ACLGRP:-"users"}
12578         ACLNBD=${ACLNBD:-"nobody"}
12579
12580         if ! id $ACLBIN ||
12581            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12582                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12583                 ACLBIN=$USER0
12584                 if ! id $ACLBIN ; then
12585                         cat /etc/passwd
12586                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12587                 fi
12588         fi
12589         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12590            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12591                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12592                 ACLDMN=$USER1
12593                 if ! id $ACLDMN ; then
12594                         cat /etc/passwd
12595                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12596                 fi
12597         fi
12598         if ! getent group $ACLGRP; then
12599                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12600                 ACLGRP="$TSTUSR"
12601                 if ! getent group $ACLGRP; then
12602                         echo "cannot find group '$ACLGRP', adding it"
12603                         cat /etc/group
12604                         add_group 60000 $ACLGRP
12605                 fi
12606         fi
12607
12608         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12609         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12610         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12611
12612         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12613                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12614                 ACLGRP="$TSTUSR"
12615                 if ! getent group $ACLGRP; then
12616                         echo "cannot find group '$ACLGRP', adding it"
12617                         cat /etc/group
12618                         add_group 60000 $ACLGRP
12619                 fi
12620                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12621                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12622                         cat /etc/group
12623                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12624                 fi
12625         fi
12626
12627         gpasswd -a $ACLDMN $ACLBIN ||
12628                 error "setting client group failed"             # LU-5641
12629         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12630                 error "setting MDS group failed"                # LU-5641
12631
12632         declare -a identity_old
12633
12634         for ((num = 1; num <= $MDSCOUNT; num++)); do
12635                 switch_identity $num true || identity_old[$num]=$?
12636         done
12637
12638         SAVE_UMASK=$(umask)
12639         umask 0022
12640         mkdir -p $DIR/$tdir
12641         cd $DIR/$tdir
12642
12643         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12644         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12645         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12646         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12647         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12648         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12649         if ! id -u $ACLNBD ||
12650            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12651                 ACLNBD="nfsnobody"
12652                 if ! id -u $ACLNBD; then
12653                         ACLNBD=""
12654                 fi
12655         fi
12656         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12657                 add_group $(id -u $ACLNBD) $ACLNBD
12658                 if ! getent group $ACLNBD; then
12659                         ACLNBD=""
12660                 fi
12661         fi
12662         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12663            [[ -n "$ACLNBD" ]] && which setfattr; then
12664                 run_acl_subtest permissions_xattr \
12665                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12666         elif [[ -z "$ACLNBD" ]]; then
12667                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12668         else
12669                 echo "skip 'permission_xattr' test - missing setfattr command"
12670         fi
12671         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12672
12673         # inheritance test got from HP
12674         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12675         chmod +x make-tree || error "chmod +x failed"
12676         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12677         rm -f make-tree
12678
12679         echo "LU-974 ignore umask when acl is enabled..."
12680         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12681         if [ $MDSCOUNT -ge 2 ]; then
12682                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12683         fi
12684
12685         echo "LU-2561 newly created file is same size as directory..."
12686         if [ "$mds1_FSTYPE" != "zfs" ]; then
12687                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12688         else
12689                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12690         fi
12691
12692         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12693
12694         cd $SAVE_PWD
12695         umask $SAVE_UMASK
12696
12697         for ((num = 1; num <= $MDSCOUNT; num++)); do
12698                 if [[ "${identity_old[$num]}" == 1 ]]; then
12699                         switch_identity $num false || identity_old[$num]=$?
12700                 fi
12701         done
12702 }
12703 run_test 103a "acl test"
12704
12705 test_103b() {
12706         declare -a pids
12707         local U
12708
12709         stack_trap "rm -f $DIR/$tfile.*"
12710         for U in {0..511}; do
12711                 {
12712                 local O=$(printf "%04o" $U)
12713
12714                 umask $(printf "%04o" $((511 ^ $O)))
12715                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12716                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12717
12718                 (( $S == ($O & 0666) )) ||
12719                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12720
12721                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12722                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12723                 (( $S == ($O & 0666) )) ||
12724                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12725
12726                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12727                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12728                 (( $S == ($O & 0666) )) ||
12729                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12730                 rm -f $DIR/$tfile.[smp]$0
12731                 } &
12732                 local pid=$!
12733
12734                 # limit the concurrently running threads to 64. LU-11878
12735                 local idx=$((U % 64))
12736                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12737                 pids[idx]=$pid
12738         done
12739         wait
12740 }
12741 run_test 103b "umask lfs setstripe"
12742
12743 test_103c() {
12744         mkdir -p $DIR/$tdir
12745         cp -rp $DIR/$tdir $DIR/$tdir.bak
12746
12747         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12748                 error "$DIR/$tdir shouldn't contain default ACL"
12749         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12750                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12751         true
12752 }
12753 run_test 103c "'cp -rp' won't set empty acl"
12754
12755 test_103e() {
12756         local numacl
12757         local fileacl
12758         local saved_debug=$($LCTL get_param -n debug)
12759
12760         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12761                 skip "MDS needs to be at least 2.14.52"
12762
12763         large_xattr_enabled || skip_env "ea_inode feature disabled"
12764
12765         mkdir -p $DIR/$tdir
12766         # add big LOV EA to cause reply buffer overflow earlier
12767         $LFS setstripe -C 1000 $DIR/$tdir
12768         lctl set_param mdc.*-mdc*.stats=clear
12769
12770         $LCTL set_param debug=0
12771         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12772         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12773
12774         # add a large number of default ACLs (expect 8000+ for 2.13+)
12775         for U in {2..7000}; do
12776                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12777                         error "Able to add just $U default ACLs"
12778         done
12779         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12780         echo "$numacl default ACLs created"
12781
12782         stat $DIR/$tdir || error "Cannot stat directory"
12783         # check file creation
12784         touch $DIR/$tdir/$tfile ||
12785                 error "failed to create $tfile with $numacl default ACLs"
12786         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12787         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12788         echo "$fileacl ACLs were inherited"
12789         (( $fileacl == $numacl )) ||
12790                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12791         # check that new ACLs creation adds new ACLs to inherited ACLs
12792         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12793                 error "Cannot set new ACL"
12794         numacl=$((numacl + 1))
12795         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12796         (( $fileacl == $numacl )) ||
12797                 error "failed to add new ACL: $fileacl != $numacl as expected"
12798         # adds more ACLs to a file to reach their maximum at 8000+
12799         numacl=0
12800         for U in {20000..25000}; do
12801                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12802                 numacl=$((numacl + 1))
12803         done
12804         echo "Added $numacl more ACLs to the file"
12805         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12806         echo "Total $fileacl ACLs in file"
12807         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12808         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12809         rmdir $DIR/$tdir || error "Cannot remove directory"
12810 }
12811 run_test 103e "inheritance of big amount of default ACLs"
12812
12813 test_103f() {
12814         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12815                 skip "MDS needs to be at least 2.14.51"
12816
12817         large_xattr_enabled || skip_env "ea_inode feature disabled"
12818
12819         # enable changelog to consume more internal MDD buffers
12820         changelog_register
12821
12822         mkdir -p $DIR/$tdir
12823         # add big LOV EA
12824         $LFS setstripe -C 1000 $DIR/$tdir
12825         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12826         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12827         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12828         rmdir $DIR/$tdir || error "Cannot remove directory"
12829 }
12830 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12831
12832 test_104a() {
12833         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12834
12835         touch $DIR/$tfile
12836         lfs df || error "lfs df failed"
12837         lfs df -ih || error "lfs df -ih failed"
12838         lfs df -h $DIR || error "lfs df -h $DIR failed"
12839         lfs df -i $DIR || error "lfs df -i $DIR failed"
12840         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12841         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12842
12843         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12844         lctl --device %$OSC deactivate
12845         lfs df || error "lfs df with deactivated OSC failed"
12846         lctl --device %$OSC activate
12847         # wait the osc back to normal
12848         wait_osc_import_ready client ost
12849
12850         lfs df || error "lfs df with reactivated OSC failed"
12851         rm -f $DIR/$tfile
12852 }
12853 run_test 104a "lfs df [-ih] [path] test ========================="
12854
12855 test_104b() {
12856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12857         [ $RUNAS_ID -eq $UID ] &&
12858                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12859
12860         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12861                         grep "Permission denied" | wc -l)))
12862         if [ $denied_cnt -ne 0 ]; then
12863                 error "lfs check servers test failed"
12864         fi
12865 }
12866 run_test 104b "$RUNAS lfs check servers test ===================="
12867
12868 #
12869 # Verify $1 is within range of $2.
12870 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12871 # $1 is <= 2% of $2. Else Fail.
12872 #
12873 value_in_range() {
12874         # Strip all units (M, G, T)
12875         actual=$(echo $1 | tr -d A-Z)
12876         expect=$(echo $2 | tr -d A-Z)
12877
12878         expect_lo=$(($expect * 98 / 100)) # 2% below
12879         expect_hi=$(($expect * 102 / 100)) # 2% above
12880
12881         # permit 2% drift above and below
12882         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12883 }
12884
12885 test_104c() {
12886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12887         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12888
12889         local ost_param="osd-zfs.$FSNAME-OST0000."
12890         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12891         local ofacets=$(get_facets OST)
12892         local mfacets=$(get_facets MDS)
12893         local saved_ost_blocks=
12894         local saved_mdt_blocks=
12895
12896         echo "Before recordsize change"
12897         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12898         df=($(df -h | grep "$MOUNT"$))
12899
12900         # For checking.
12901         echo "lfs output : ${lfs_df[*]}"
12902         echo "df  output : ${df[*]}"
12903
12904         for facet in ${ofacets//,/ }; do
12905                 if [ -z $saved_ost_blocks ]; then
12906                         saved_ost_blocks=$(do_facet $facet \
12907                                 lctl get_param -n $ost_param.blocksize)
12908                         echo "OST Blocksize: $saved_ost_blocks"
12909                 fi
12910                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12911                 do_facet $facet zfs set recordsize=32768 $ost
12912         done
12913
12914         # BS too small. Sufficient for functional testing.
12915         for facet in ${mfacets//,/ }; do
12916                 if [ -z $saved_mdt_blocks ]; then
12917                         saved_mdt_blocks=$(do_facet $facet \
12918                                 lctl get_param -n $mdt_param.blocksize)
12919                         echo "MDT Blocksize: $saved_mdt_blocks"
12920                 fi
12921                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12922                 do_facet $facet zfs set recordsize=32768 $mdt
12923         done
12924
12925         # Give new values chance to reflect change
12926         sleep 2
12927
12928         echo "After recordsize change"
12929         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12930         df_after=($(df -h | grep "$MOUNT"$))
12931
12932         # For checking.
12933         echo "lfs output : ${lfs_df_after[*]}"
12934         echo "df  output : ${df_after[*]}"
12935
12936         # Verify lfs df
12937         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12938                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12939         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12940                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12941         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12942                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12943
12944         # Verify df
12945         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12946                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12947         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12948                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12949         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12950                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12951
12952         # Restore MDT recordize back to original
12953         for facet in ${mfacets//,/ }; do
12954                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12955                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12956         done
12957
12958         # Restore OST recordize back to original
12959         for facet in ${ofacets//,/ }; do
12960                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12961                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12962         done
12963
12964         return 0
12965 }
12966 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12967
12968 test_104d() {
12969         (( $RUNAS_ID != $UID )) ||
12970                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12971
12972         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12973                 skip "lustre version doesn't support lctl dl with non-root"
12974
12975         # debugfs only allows root users to access files, so the
12976         # previous move of the "devices" file to debugfs broke
12977         # "lctl dl" for non-root users. The LU-9680 Netlink
12978         # interface again allows non-root users to list devices.
12979         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12980                 error "lctl dl doesn't work for non root"
12981
12982         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12983         [ "$ost_count" -eq $OSTCOUNT ]  ||
12984                 error "lctl dl reports wrong number of OST devices"
12985
12986         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12987         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12988                 error "lctl dl reports wrong number of MDT devices"
12989 }
12990 run_test 104d "$RUNAS lctl dl test"
12991
12992 test_105a() {
12993         # doesn't work on 2.4 kernels
12994         touch $DIR/$tfile
12995         if $(flock_is_enabled); then
12996                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12997         else
12998                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12999         fi
13000         rm -f $DIR/$tfile
13001 }
13002 run_test 105a "flock when mounted without -o flock test ========"
13003
13004 test_105b() {
13005         touch $DIR/$tfile
13006         if $(flock_is_enabled); then
13007                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
13008         else
13009                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
13010         fi
13011         rm -f $DIR/$tfile
13012 }
13013 run_test 105b "fcntl when mounted without -o flock test ========"
13014
13015 test_105c() {
13016         touch $DIR/$tfile
13017         if $(flock_is_enabled); then
13018                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
13019         else
13020                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
13021         fi
13022         rm -f $DIR/$tfile
13023 }
13024 run_test 105c "lockf when mounted without -o flock test"
13025
13026 test_105d() { # bug 15924
13027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13028
13029         test_mkdir $DIR/$tdir
13030         flock_is_enabled || skip_env "mount w/o flock enabled"
13031         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
13032         $LCTL set_param fail_loc=0x80000315
13033         flocks_test 2 $DIR/$tdir
13034 }
13035 run_test 105d "flock race (should not freeze) ========"
13036
13037 test_105e() { # bug 22660 && 22040
13038         flock_is_enabled || skip_env "mount w/o flock enabled"
13039
13040         touch $DIR/$tfile
13041         flocks_test 3 $DIR/$tfile
13042 }
13043 run_test 105e "Two conflicting flocks from same process"
13044
13045 test_106() { #bug 10921
13046         test_mkdir $DIR/$tdir
13047         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
13048         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
13049 }
13050 run_test 106 "attempt exec of dir followed by chown of that dir"
13051
13052 test_107() {
13053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13054
13055         CDIR=`pwd`
13056         local file=core
13057
13058         cd $DIR
13059         rm -f $file
13060
13061         local save_pattern=$(sysctl -n kernel.core_pattern)
13062         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
13063         sysctl -w kernel.core_pattern=$file
13064         sysctl -w kernel.core_uses_pid=0
13065
13066         ulimit -c unlimited
13067         sleep 60 &
13068         SLEEPPID=$!
13069
13070         sleep 1
13071
13072         kill -s 11 $SLEEPPID
13073         wait $SLEEPPID
13074         if [ -e $file ]; then
13075                 size=`stat -c%s $file`
13076                 [ $size -eq 0 ] && error "Fail to create core file $file"
13077         else
13078                 error "Fail to create core file $file"
13079         fi
13080         rm -f $file
13081         sysctl -w kernel.core_pattern=$save_pattern
13082         sysctl -w kernel.core_uses_pid=$save_uses_pid
13083         cd $CDIR
13084 }
13085 run_test 107 "Coredump on SIG"
13086
13087 test_110() {
13088         test_mkdir $DIR/$tdir
13089         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13090         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13091                 error "mkdir with 256 char should fail, but did not"
13092         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13093                 error "create with 255 char failed"
13094         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13095                 error "create with 256 char should fail, but did not"
13096
13097         ls -l $DIR/$tdir
13098         rm -rf $DIR/$tdir
13099 }
13100 run_test 110 "filename length checking"
13101
13102 test_116a() { # was previously test_116()
13103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13104         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13105         remote_mds_nodsh && skip "remote MDS with nodsh"
13106
13107         echo -n "Free space priority "
13108         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13109                 head -n1
13110         declare -a AVAIL
13111         free_min_max
13112
13113         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13114         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13115         stack_trap simple_cleanup_common
13116
13117         # Check if we need to generate uneven OSTs
13118         test_mkdir -p $DIR/$tdir/OST${MINI}
13119         local FILL=$((MINV / 4))
13120         local DIFF=$((MAXV - MINV))
13121         local DIFF2=$((DIFF * 100 / MINV))
13122
13123         local threshold=$(do_facet $SINGLEMDS \
13124                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13125         threshold=${threshold%%%}
13126         echo -n "Check for uneven OSTs: "
13127         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13128
13129         if [[ $DIFF2 -gt $threshold ]]; then
13130                 echo "ok"
13131                 echo "Don't need to fill OST$MINI"
13132         else
13133                 # generate uneven OSTs. Write 2% over the QOS threshold value
13134                 echo "no"
13135                 DIFF=$((threshold - DIFF2 + 2))
13136                 DIFF2=$((MINV * DIFF / 100))
13137                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13138                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13139                         error "setstripe failed"
13140                 DIFF=$((DIFF2 / 2048))
13141                 i=0
13142                 while [ $i -lt $DIFF ]; do
13143                         i=$((i + 1))
13144                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13145                                 bs=2M count=1 2>/dev/null
13146                         echo -n .
13147                 done
13148                 echo .
13149                 sync
13150                 sleep_maxage
13151                 free_min_max
13152         fi
13153
13154         DIFF=$((MAXV - MINV))
13155         DIFF2=$((DIFF * 100 / MINV))
13156         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13157         if [ $DIFF2 -gt $threshold ]; then
13158                 echo "ok"
13159         else
13160                 skip "QOS imbalance criteria not met"
13161         fi
13162
13163         MINI1=$MINI
13164         MINV1=$MINV
13165         MAXI1=$MAXI
13166         MAXV1=$MAXV
13167
13168         # now fill using QOS
13169         $LFS setstripe -c 1 $DIR/$tdir
13170         FILL=$((FILL / 200))
13171         if [ $FILL -gt 600 ]; then
13172                 FILL=600
13173         fi
13174         echo "writing $FILL files to QOS-assigned OSTs"
13175         i=0
13176         while [ $i -lt $FILL ]; do
13177                 i=$((i + 1))
13178                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13179                         count=1 2>/dev/null
13180                 echo -n .
13181         done
13182         echo "wrote $i 200k files"
13183         sync
13184         sleep_maxage
13185
13186         echo "Note: free space may not be updated, so measurements might be off"
13187         free_min_max
13188         DIFF2=$((MAXV - MINV))
13189         echo "free space delta: orig $DIFF final $DIFF2"
13190         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13191         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13192         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13193         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13194         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13195         if [[ $DIFF -gt 0 ]]; then
13196                 FILL=$((DIFF2 * 100 / DIFF - 100))
13197                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13198         fi
13199
13200         # Figure out which files were written where
13201         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13202                awk '/'$MINI1': / {print $2; exit}')
13203         echo $UUID
13204         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13205         echo "$MINC files created on smaller OST $MINI1"
13206         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13207                awk '/'$MAXI1': / {print $2; exit}')
13208         echo $UUID
13209         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13210         echo "$MAXC files created on larger OST $MAXI1"
13211         if [[ $MINC -gt 0 ]]; then
13212                 FILL=$((MAXC * 100 / MINC - 100))
13213                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13214         fi
13215         [[ $MAXC -gt $MINC ]] ||
13216                 error_ignore LU-9 "stripe QOS didn't balance free space"
13217 }
13218 run_test 116a "stripe QOS: free space balance ==================="
13219
13220 test_116b() { # LU-2093
13221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13222         remote_mds_nodsh && skip "remote MDS with nodsh"
13223
13224 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13225         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13226                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13227         [ -z "$old_rr" ] && skip "no QOS"
13228         do_facet $SINGLEMDS lctl set_param \
13229                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13230         mkdir -p $DIR/$tdir
13231         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13232         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13233         do_facet $SINGLEMDS lctl set_param fail_loc=0
13234         rm -rf $DIR/$tdir
13235         do_facet $SINGLEMDS lctl set_param \
13236                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13237 }
13238 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13239
13240 test_117() # bug 10891
13241 {
13242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13243
13244         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13245         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13246         lctl set_param fail_loc=0x21e
13247         > $DIR/$tfile || error "truncate failed"
13248         lctl set_param fail_loc=0
13249         echo "Truncate succeeded."
13250         rm -f $DIR/$tfile
13251 }
13252 run_test 117 "verify osd extend =========="
13253
13254 NO_SLOW_RESENDCOUNT=4
13255 export OLD_RESENDCOUNT=""
13256 set_resend_count () {
13257         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13258         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13259         lctl set_param -n $PROC_RESENDCOUNT $1
13260         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13261 }
13262
13263 # for reduce test_118* time (b=14842)
13264 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13265
13266 # Reset async IO behavior after error case
13267 reset_async() {
13268         FILE=$DIR/reset_async
13269
13270         # Ensure all OSCs are cleared
13271         $LFS setstripe -c -1 $FILE
13272         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13273         sync
13274         rm $FILE
13275 }
13276
13277 test_118a() #bug 11710
13278 {
13279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13280
13281         reset_async
13282
13283         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13284         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13285         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13286
13287         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13288                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13289                 return 1;
13290         fi
13291         rm -f $DIR/$tfile
13292 }
13293 run_test 118a "verify O_SYNC works =========="
13294
13295 test_118b()
13296 {
13297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13298         remote_ost_nodsh && skip "remote OST with nodsh"
13299
13300         reset_async
13301
13302         #define OBD_FAIL_SRV_ENOENT 0x217
13303         set_nodes_failloc "$(osts_nodes)" 0x217
13304         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13305         RC=$?
13306         set_nodes_failloc "$(osts_nodes)" 0
13307         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13308         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13309                     grep -c writeback)
13310
13311         if [[ $RC -eq 0 ]]; then
13312                 error "Must return error due to dropped pages, rc=$RC"
13313                 return 1;
13314         fi
13315
13316         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13317                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13318                 return 1;
13319         fi
13320
13321         echo "Dirty pages not leaked on ENOENT"
13322
13323         # Due to the above error the OSC will issue all RPCs syncronously
13324         # until a subsequent RPC completes successfully without error.
13325         $MULTIOP $DIR/$tfile Ow4096yc
13326         rm -f $DIR/$tfile
13327
13328         return 0
13329 }
13330 run_test 118b "Reclaim dirty pages on fatal error =========="
13331
13332 test_118c()
13333 {
13334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13335
13336         # for 118c, restore the original resend count, LU-1940
13337         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13338                                 set_resend_count $OLD_RESENDCOUNT
13339         remote_ost_nodsh && skip "remote OST with nodsh"
13340
13341         reset_async
13342
13343         #define OBD_FAIL_OST_EROFS               0x216
13344         set_nodes_failloc "$(osts_nodes)" 0x216
13345
13346         # multiop should block due to fsync until pages are written
13347         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13348         MULTIPID=$!
13349         sleep 1
13350
13351         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13352                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13353         fi
13354
13355         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13356                     grep -c writeback)
13357         if [[ $WRITEBACK -eq 0 ]]; then
13358                 error "No page in writeback, writeback=$WRITEBACK"
13359         fi
13360
13361         set_nodes_failloc "$(osts_nodes)" 0
13362         wait $MULTIPID
13363         RC=$?
13364         if [[ $RC -ne 0 ]]; then
13365                 error "Multiop fsync failed, rc=$RC"
13366         fi
13367
13368         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13369         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13370                     grep -c writeback)
13371         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13372                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13373         fi
13374
13375         rm -f $DIR/$tfile
13376         echo "Dirty pages flushed via fsync on EROFS"
13377         return 0
13378 }
13379 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13380
13381 # continue to use small resend count to reduce test_118* time (b=14842)
13382 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13383
13384 test_118d()
13385 {
13386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13387         remote_ost_nodsh && skip "remote OST with nodsh"
13388
13389         reset_async
13390
13391         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13392         set_nodes_failloc "$(osts_nodes)" 0x214
13393         # multiop should block due to fsync until pages are written
13394         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13395         MULTIPID=$!
13396         sleep 1
13397
13398         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13399                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13400         fi
13401
13402         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13403                     grep -c writeback)
13404         if [[ $WRITEBACK -eq 0 ]]; then
13405                 error "No page in writeback, writeback=$WRITEBACK"
13406         fi
13407
13408         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13409         set_nodes_failloc "$(osts_nodes)" 0
13410
13411         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13412         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13413                     grep -c writeback)
13414         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13415                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13416         fi
13417
13418         rm -f $DIR/$tfile
13419         echo "Dirty pages gaurenteed flushed via fsync"
13420         return 0
13421 }
13422 run_test 118d "Fsync validation inject a delay of the bulk =========="
13423
13424 test_118f() {
13425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13426
13427         reset_async
13428
13429         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13430         lctl set_param fail_loc=0x8000040a
13431
13432         # Should simulate EINVAL error which is fatal
13433         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13434         RC=$?
13435         if [[ $RC -eq 0 ]]; then
13436                 error "Must return error due to dropped pages, rc=$RC"
13437         fi
13438
13439         lctl set_param fail_loc=0x0
13440
13441         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13442         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13443         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13444                     grep -c writeback)
13445         if [[ $LOCKED -ne 0 ]]; then
13446                 error "Locked pages remain in cache, locked=$LOCKED"
13447         fi
13448
13449         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13450                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13451         fi
13452
13453         rm -f $DIR/$tfile
13454         echo "No pages locked after fsync"
13455
13456         reset_async
13457         return 0
13458 }
13459 run_test 118f "Simulate unrecoverable OSC side error =========="
13460
13461 test_118g() {
13462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13463
13464         reset_async
13465
13466         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13467         lctl set_param fail_loc=0x406
13468
13469         # simulate local -ENOMEM
13470         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13471         RC=$?
13472
13473         lctl set_param fail_loc=0
13474         if [[ $RC -eq 0 ]]; then
13475                 error "Must return error due to dropped pages, rc=$RC"
13476         fi
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 118g "Don't stay in wait if we got local -ENOMEM  =========="
13497
13498 test_118h() {
13499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13500         remote_ost_nodsh && skip "remote OST with nodsh"
13501
13502         reset_async
13503
13504         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13505         set_nodes_failloc "$(osts_nodes)" 0x20e
13506         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13507         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13508         RC=$?
13509
13510         set_nodes_failloc "$(osts_nodes)" 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         return 0
13531 }
13532 run_test 118h "Verify timeout in handling recoverables errors  =========="
13533
13534 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13535
13536 test_118i() {
13537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13538         remote_ost_nodsh && skip "remote OST with nodsh"
13539
13540         reset_async
13541
13542         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13543         set_nodes_failloc "$(osts_nodes)" 0x20e
13544
13545         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13546         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13547         PID=$!
13548         sleep 5
13549         set_nodes_failloc "$(osts_nodes)" 0
13550
13551         wait $PID
13552         RC=$?
13553         if [[ $RC -ne 0 ]]; then
13554                 error "got error, but should be not, rc=$RC"
13555         fi
13556
13557         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13558         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13559         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13560         if [[ $LOCKED -ne 0 ]]; then
13561                 error "Locked pages remain in cache, locked=$LOCKED"
13562         fi
13563
13564         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13565                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13566         fi
13567
13568         rm -f $DIR/$tfile
13569         echo "No pages locked after fsync"
13570
13571         return 0
13572 }
13573 run_test 118i "Fix error before timeout in recoverable error  =========="
13574
13575 [ "$SLOW" = "no" ] && set_resend_count 4
13576
13577 test_118j() {
13578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13579         remote_ost_nodsh && skip "remote OST with nodsh"
13580
13581         reset_async
13582
13583         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13584         set_nodes_failloc "$(osts_nodes)" 0x220
13585
13586         # return -EIO from OST
13587         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13588         RC=$?
13589         set_nodes_failloc "$(osts_nodes)" 0x0
13590         if [[ $RC -eq 0 ]]; then
13591                 error "Must return error due to dropped pages, 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         # in recoverable error on OST we want resend and stay until it finished
13602         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13603                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13604         fi
13605
13606         rm -f $DIR/$tfile
13607         echo "No pages locked after fsync"
13608
13609         return 0
13610 }
13611 run_test 118j "Simulate unrecoverable OST side error =========="
13612
13613 test_118k()
13614 {
13615         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13616         remote_ost_nodsh && skip "remote OSTs with nodsh"
13617
13618         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13619         set_nodes_failloc "$(osts_nodes)" 0x20e
13620         test_mkdir $DIR/$tdir
13621
13622         for ((i=0;i<10;i++)); do
13623                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13624                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13625                 SLEEPPID=$!
13626                 sleep 0.500s
13627                 kill $SLEEPPID
13628                 wait $SLEEPPID
13629         done
13630
13631         set_nodes_failloc "$(osts_nodes)" 0
13632         rm -rf $DIR/$tdir
13633 }
13634 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13635
13636 test_118l() # LU-646
13637 {
13638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13639
13640         test_mkdir $DIR/$tdir
13641         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13642         rm -rf $DIR/$tdir
13643 }
13644 run_test 118l "fsync dir"
13645
13646 test_118m() # LU-3066
13647 {
13648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13649
13650         test_mkdir $DIR/$tdir
13651         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13652         rm -rf $DIR/$tdir
13653 }
13654 run_test 118m "fdatasync dir ========="
13655
13656 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13657
13658 test_118n()
13659 {
13660         local begin
13661         local end
13662
13663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13664         remote_ost_nodsh && skip "remote OSTs with nodsh"
13665
13666         # Sleep to avoid a cached response.
13667         #define OBD_STATFS_CACHE_SECONDS 1
13668         sleep 2
13669
13670         # Inject a 10 second delay in the OST_STATFS handler.
13671         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13672         set_nodes_failloc "$(osts_nodes)" 0x242
13673
13674         begin=$SECONDS
13675         stat --file-system $MOUNT > /dev/null
13676         end=$SECONDS
13677
13678         set_nodes_failloc "$(osts_nodes)" 0
13679
13680         if ((end - begin > 20)); then
13681             error "statfs took $((end - begin)) seconds, expected 10"
13682         fi
13683 }
13684 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13685
13686 test_119a() # bug 11737
13687 {
13688         BSIZE=$((512 * 1024))
13689         directio write $DIR/$tfile 0 1 $BSIZE
13690         # We ask to read two blocks, which is more than a file size.
13691         # directio will indicate an error when requested and actual
13692         # sizes aren't equeal (a normal situation in this case) and
13693         # print actual read amount.
13694         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13695         if [ "$NOB" != "$BSIZE" ]; then
13696                 error "read $NOB bytes instead of $BSIZE"
13697         fi
13698         rm -f $DIR/$tfile
13699 }
13700 run_test 119a "Short directIO read must return actual read amount"
13701
13702 test_119b() # bug 11737
13703 {
13704         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13705
13706         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13707         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13708         sync
13709         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13710                 error "direct read failed"
13711         rm -f $DIR/$tfile
13712 }
13713 run_test 119b "Sparse directIO read must return actual read amount"
13714
13715 test_119c() # bug 13099
13716 {
13717         BSIZE=1048576
13718         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13719         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13720         rm -f $DIR/$tfile
13721 }
13722 run_test 119c "Testing for direct read hitting hole"
13723
13724 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13725 # Maloo test history
13726
13727 test_119e()
13728 {
13729         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13730                 skip "Need server version at least 2.15.58"
13731         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13732
13733         local stripe_size=$((1024 * 1024)) #1 MiB
13734         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13735         local file_size=$((25 * stripe_size))
13736         local bsizes
13737
13738         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13739         stack_trap "rm -f $DIR/$tfile*"
13740
13741         # Just a bit bigger than the largest size in the test set below
13742         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13743                 error "buffered i/o to create file failed"
13744
13745         # trivial test of unaligned DIO
13746         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13747                 iflag=direct oflag=direct ||
13748                 error "trivial unaligned dio failed"
13749
13750         # Test of disabling unaligned DIO support
13751         $LCTL set_param llite.*.unaligned_dio=0
13752         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13753         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13754         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13755                 iflag=direct oflag=direct &&
13756                 error "unaligned dio succeeded when disabled"
13757         $LCTL set_param llite.*.unaligned_dio=1
13758
13759         # Clean up before next part of test
13760         rm -f $DIR/$tfile.2
13761
13762         if zfs_or_rotational; then
13763                 # DIO on ZFS can take up to 2 seconds per IO
13764                 # rotational is better, but still slow.
13765                 # Limit testing on those media to larger sizes
13766                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13767                         $((stripe_size + 1024))"
13768         else
13769                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13770                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13771                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13772                         $((stripe_size - 1)) $stripe_size \
13773                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13774                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13775         fi
13776
13777         for bs in $bsizes; do
13778                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13779                 echo "Read/write with DIO at size $bs"
13780                 # Read and write with DIO from source to dest
13781                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13782                         iflag=direct oflag=direct ||
13783                         error "dio failed"
13784
13785                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13786                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13787                         error "size incorrect, file copy read/write bsize: $bs"
13788                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13789                         error "files differ, bsize $bs"
13790                 rm -f $DIR/$tfile.2
13791         done
13792 }
13793 run_test 119e "Basic tests of dio read and write at various sizes"
13794
13795 test_119f()
13796 {
13797         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13798
13799         local stripe_size=$((1024 * 1024)) #1 MiB
13800         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13801         local file_size=$((25 * stripe_size))
13802         local bsizes
13803
13804         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13805         stack_trap "rm -f $DIR/$tfile*"
13806
13807         # Just a bit bigger than the largest size in the test set below
13808         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13809                 error "buffered i/o to create file failed"
13810
13811         if zfs_or_rotational; then
13812                 # DIO on ZFS can take up to 2 seconds per IO
13813                 # rotational is better, but still slow.
13814                 # Limit testing on those media to larger sizes
13815                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13816                         $((stripe_size + 1024))"
13817         else
13818                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13819                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13820                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13821                         $((stripe_size - 1)) $stripe_size \
13822                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13823                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13824         fi
13825
13826         for bs in $bsizes; do
13827                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13828                 # Read and write with DIO from source to dest in two
13829                 # threads - should give correct copy of file
13830
13831                 echo "bs: $bs"
13832                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13833                         oflag=direct conv=notrunc &
13834                 pid_dio1=$!
13835                 # Note block size is different here for a more interesting race
13836                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13837                         iflag=direct oflag=direct conv=notrunc &
13838                 pid_dio2=$!
13839                 wait $pid_dio1
13840                 rc1=$?
13841                 wait $pid_dio2
13842                 rc2=$?
13843                 if (( rc1 != 0 )); then
13844                         error "dio copy 1 w/bsize $bs failed: $rc1"
13845                 fi
13846                 if (( rc2 != 0 )); then
13847                         error "dio copy 2 w/bsize $bs failed: $rc2"
13848                 fi
13849
13850
13851                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13852                         error "size incorrect, file copy read/write bsize: $bs"
13853                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13854                         error "files differ, bsize $bs"
13855                 rm -f $DIR/$tfile.2
13856         done
13857 }
13858 run_test 119f "dio vs dio race"
13859
13860 test_119g()
13861 {
13862         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13863
13864         local stripe_size=$((1024 * 1024)) #1 MiB
13865         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13866         local file_size=$((25 * stripe_size))
13867         local bsizes
13868
13869         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13870         stack_trap "rm -f $DIR/$tfile*"
13871
13872         # Just a bit bigger than the largest size in the test set below
13873         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13874                 error "buffered i/o to create file failed"
13875
13876         if zfs_or_rotational; then
13877                 # DIO on ZFS can take up to 2 seconds per IO
13878                 # rotational is better, but still slow.
13879                 # Limit testing on those media to larger sizes
13880                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13881                         $((stripe_size + 1024))"
13882         else
13883                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13884                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13885                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13886                         $((stripe_size - 1)) $stripe_size \
13887                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13888                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13889         fi
13890
13891         for bs in $bsizes; do
13892                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13893                 echo "bs: $bs"
13894                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13895                         oflag=direct conv=notrunc &
13896                 pid_dio1=$!
13897                 # Buffered I/O with similar but not the same block size
13898                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13899                 pid_bio2=$!
13900                 wait $pid_dio1
13901                 rc1=$?
13902                 wait $pid_bio2
13903                 rc2=$?
13904                 if (( rc1 != 0 )); then
13905                         error "dio copy 1 w/bsize $bs failed: $rc1"
13906                 fi
13907                 if (( rc2 != 0 )); then
13908                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13909                 fi
13910
13911                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13912                         error "size incorrect"
13913                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13914                         error "files differ, bsize $bs"
13915                 rm -f $DIR/$tfile.2
13916         done
13917 }
13918 run_test 119g "dio vs buffered I/O race"
13919
13920 test_119h()
13921 {
13922         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13923
13924         local stripe_size=$((1024 * 1024)) #1 MiB
13925         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13926         local file_size=$((25 * stripe_size))
13927         local bsizes
13928
13929         stack_trap "rm -f $DIR/$tfile.*"
13930
13931         if zfs_or_rotational; then
13932                 # DIO on ZFS can take up to 2 seconds per IO
13933                 # rotational is better, but still slow.
13934                 # Limit testing on those media to larger sizes
13935                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13936                         $((stripe_size + 1024))"
13937         else
13938                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13939                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13940                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13941                         $((stripe_size - 1)) $stripe_size \
13942                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13943                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13944         fi
13945
13946         for bs in $bsizes; do
13947                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13948                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13949                 echo "unaligned writes of blocksize: $bs"
13950                 # Write a file with unaligned DIO and regular DIO, and compare
13951                 # them
13952                 # with 'u', multiop randomly unaligns the io from the buffer
13953                 $MULTIOP $DIR/$tfile.1 \
13954                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13955                         error "multiop memory unaligned write failed, $bs"
13956                 $MULTIOP $DIR/$tfile.2 \
13957                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13958                         error "multiop memory aligned write failed, $bs"
13959
13960                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13961                         error "files differ, bsize $bs"
13962                 rm -f $DIR/$tfile.*
13963         done
13964
13965         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13966         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13967                 error "dd to create source file for read failed"
13968
13969         # Just a few quick tests to make sure unaligned DIO reads don't crash
13970         for bs in $bsizes; do
13971
13972                 echo "unaligned reads of blocksize: $bs"
13973                 # with 'u', multiop randomly unaligns the io from the buffer
13974                 $MULTIOP $DIR/$tfile.1 \
13975                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13976                         error "multiop memory unaligned read failed, $bs"
13977
13978         done
13979         rm -f $DIR/$tfile*
13980 }
13981 run_test 119h "basic tests of memory unaligned dio"
13982
13983 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13984 test_119i()
13985 {
13986         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13987         which aiocp || skip_env "no aiocp installed"
13988
13989         local stripe_size=$((1024 * 1024)) #1 MiB
13990         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13991         local file_size=$((25 * stripe_size))
13992         local bsizes
13993
13994         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13995         stack_trap "rm -f $DIR/$tfile.*"
13996
13997         # Just a bit bigger than the largest size in the test set below
13998         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13999                 error "buffered i/o to create file failed"
14000
14001         if zfs_or_rotational; then
14002                 # DIO on ZFS can take up to 2 seconds per IO
14003                 # rotational is better, but still slow.
14004                 # Limit testing on those media to larger sizes
14005                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
14006                         $((stripe_size + 1024))"
14007         else
14008                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
14009                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
14010                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
14011                         $((stripe_size - 1)) $stripe_size \
14012                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
14013                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
14014         fi
14015
14016         # Do page aligned and NOT page aligned AIO
14017         for align in 8 512 $((PAGE_SIZE)); do
14018         # Deliberately includes a few aligned sizes
14019         for bs in $bsizes; do
14020                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
14021
14022                 echo "bs: $bs, align: $align, file_size $file_size"
14023                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
14024                         $DIR/$tfile.1 $DIR/$tfile.2 ||
14025                         error "unaligned aio failed, bs: $bs, align: $align"
14026
14027                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
14028                         error "size incorrect"
14029                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
14030                         error "files differ"
14031                 rm -f $DIR/$tfile.2
14032         done
14033         done
14034 }
14035 run_test 119i "test unaligned aio at varying sizes"
14036
14037 test_120a() {
14038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14039         remote_mds_nodsh && skip "remote MDS with nodsh"
14040         test_mkdir -i0 -c1 $DIR/$tdir
14041         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14042                 skip_env "no early lock cancel on server"
14043
14044         lru_resize_disable mdc
14045         lru_resize_disable osc
14046         cancel_lru_locks mdc
14047         # asynchronous object destroy at MDT could cause bl ast to client
14048         cancel_lru_locks osc
14049
14050         stat $DIR/$tdir > /dev/null
14051         can1=$(do_facet mds1 \
14052                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14053                awk '/ldlm_cancel/ {print $2}')
14054         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14055                awk '/ldlm_bl_callback/ {print $2}')
14056         test_mkdir -i0 -c1 $DIR/$tdir/d1
14057         can2=$(do_facet mds1 \
14058                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14059                awk '/ldlm_cancel/ {print $2}')
14060         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14061                awk '/ldlm_bl_callback/ {print $2}')
14062         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14063         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14064         lru_resize_enable mdc
14065         lru_resize_enable osc
14066 }
14067 run_test 120a "Early Lock Cancel: mkdir test"
14068
14069 test_120b() {
14070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14071         remote_mds_nodsh && skip "remote MDS with nodsh"
14072         test_mkdir $DIR/$tdir
14073         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14074                 skip_env "no early lock cancel on server"
14075
14076         lru_resize_disable mdc
14077         lru_resize_disable osc
14078         cancel_lru_locks mdc
14079         stat $DIR/$tdir > /dev/null
14080         can1=$(do_facet $SINGLEMDS \
14081                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14082                awk '/ldlm_cancel/ {print $2}')
14083         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14084                awk '/ldlm_bl_callback/ {print $2}')
14085         touch $DIR/$tdir/f1
14086         can2=$(do_facet $SINGLEMDS \
14087                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14088                awk '/ldlm_cancel/ {print $2}')
14089         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14090                awk '/ldlm_bl_callback/ {print $2}')
14091         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14092         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14093         lru_resize_enable mdc
14094         lru_resize_enable osc
14095 }
14096 run_test 120b "Early Lock Cancel: create test"
14097
14098 test_120c() {
14099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14100         remote_mds_nodsh && skip "remote MDS with nodsh"
14101         test_mkdir -i0 -c1 $DIR/$tdir
14102         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14103                 skip "no early lock cancel on server"
14104
14105         lru_resize_disable mdc
14106         lru_resize_disable osc
14107         test_mkdir -i0 -c1 $DIR/$tdir/d1
14108         test_mkdir -i0 -c1 $DIR/$tdir/d2
14109         touch $DIR/$tdir/d1/f1
14110         cancel_lru_locks mdc
14111         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14112         can1=$(do_facet mds1 \
14113                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14114                awk '/ldlm_cancel/ {print $2}')
14115         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14116                awk '/ldlm_bl_callback/ {print $2}')
14117         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14118         can2=$(do_facet mds1 \
14119                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14120                awk '/ldlm_cancel/ {print $2}')
14121         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14122                awk '/ldlm_bl_callback/ {print $2}')
14123         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14124         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14125         lru_resize_enable mdc
14126         lru_resize_enable osc
14127 }
14128 run_test 120c "Early Lock Cancel: link test"
14129
14130 test_120d() {
14131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14132         remote_mds_nodsh && skip "remote MDS with nodsh"
14133         test_mkdir -i0 -c1 $DIR/$tdir
14134         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14135                 skip_env "no early lock cancel on server"
14136
14137         lru_resize_disable mdc
14138         lru_resize_disable osc
14139         touch $DIR/$tdir
14140         cancel_lru_locks mdc
14141         stat $DIR/$tdir > /dev/null
14142         can1=$(do_facet mds1 \
14143                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14144                awk '/ldlm_cancel/ {print $2}')
14145         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14146                awk '/ldlm_bl_callback/ {print $2}')
14147         chmod a+x $DIR/$tdir
14148         can2=$(do_facet mds1 \
14149                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14150                awk '/ldlm_cancel/ {print $2}')
14151         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14152                awk '/ldlm_bl_callback/ {print $2}')
14153         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14154         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14155         lru_resize_enable mdc
14156         lru_resize_enable osc
14157 }
14158 run_test 120d "Early Lock Cancel: setattr test"
14159
14160 test_120e() {
14161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14162         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14163                 skip_env "no early lock cancel on server"
14164         remote_mds_nodsh && skip "remote MDS with nodsh"
14165
14166         local dlmtrace_set=false
14167
14168         test_mkdir -i0 -c1 $DIR/$tdir
14169         lru_resize_disable mdc
14170         lru_resize_disable osc
14171         ! $LCTL get_param debug | grep -q dlmtrace &&
14172                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14173         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14174         cancel_lru_locks mdc
14175         cancel_lru_locks osc
14176         dd if=$DIR/$tdir/f1 of=/dev/null
14177         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14178         # XXX client can not do early lock cancel of OST lock
14179         # during unlink (LU-4206), so cancel osc lock now.
14180         sleep 2
14181         cancel_lru_locks osc
14182         can1=$(do_facet mds1 \
14183                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14184                awk '/ldlm_cancel/ {print $2}')
14185         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14186                awk '/ldlm_bl_callback/ {print $2}')
14187         unlink $DIR/$tdir/f1
14188         sleep 5
14189         can2=$(do_facet mds1 \
14190                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14191                awk '/ldlm_cancel/ {print $2}')
14192         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14193                awk '/ldlm_bl_callback/ {print $2}')
14194         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14195                 $LCTL dk $TMP/cancel.debug.txt
14196         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14197                 $LCTL dk $TMP/blocking.debug.txt
14198         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14199         lru_resize_enable mdc
14200         lru_resize_enable osc
14201 }
14202 run_test 120e "Early Lock Cancel: unlink test"
14203
14204 test_120f() {
14205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14206         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14207                 skip_env "no early lock cancel on server"
14208         remote_mds_nodsh && skip "remote MDS with nodsh"
14209
14210         test_mkdir -i0 -c1 $DIR/$tdir
14211         lru_resize_disable mdc
14212         lru_resize_disable osc
14213         test_mkdir -i0 -c1 $DIR/$tdir/d1
14214         test_mkdir -i0 -c1 $DIR/$tdir/d2
14215         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14216         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14217         cancel_lru_locks mdc
14218         cancel_lru_locks osc
14219         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14220         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14221         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14222         # XXX client can not do early lock cancel of OST lock
14223         # during rename (LU-4206), so cancel osc lock now.
14224         sleep 2
14225         cancel_lru_locks osc
14226         can1=$(do_facet mds1 \
14227                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14228                awk '/ldlm_cancel/ {print $2}')
14229         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14230                awk '/ldlm_bl_callback/ {print $2}')
14231         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14232         sleep 5
14233         can2=$(do_facet mds1 \
14234                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14235                awk '/ldlm_cancel/ {print $2}')
14236         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14237                awk '/ldlm_bl_callback/ {print $2}')
14238         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14239         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14240         lru_resize_enable mdc
14241         lru_resize_enable osc
14242 }
14243 run_test 120f "Early Lock Cancel: rename test"
14244
14245 test_120g() {
14246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14247         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14248                 skip_env "no early lock cancel on server"
14249         remote_mds_nodsh && skip "remote MDS with nodsh"
14250
14251         lru_resize_disable mdc
14252         lru_resize_disable osc
14253         count=10000
14254         echo create $count files
14255         test_mkdir $DIR/$tdir
14256         cancel_lru_locks mdc
14257         cancel_lru_locks osc
14258         t0=$(date +%s)
14259
14260         can0=$(do_facet $SINGLEMDS \
14261                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14262                awk '/ldlm_cancel/ {print $2}')
14263         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14264                awk '/ldlm_bl_callback/ {print $2}')
14265         createmany -o $DIR/$tdir/f $count
14266         sync
14267         can1=$(do_facet $SINGLEMDS \
14268                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14269                awk '/ldlm_cancel/ {print $2}')
14270         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14271                awk '/ldlm_bl_callback/ {print $2}')
14272         t1=$(date +%s)
14273         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14274         echo rm $count files
14275         rm -r $DIR/$tdir
14276         sync
14277         can2=$(do_facet $SINGLEMDS \
14278                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14279                awk '/ldlm_cancel/ {print $2}')
14280         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14281                awk '/ldlm_bl_callback/ {print $2}')
14282         t2=$(date +%s)
14283         echo total: $count removes in $((t2-t1))
14284         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14285         sleep 2
14286         # wait for commitment of removal
14287         lru_resize_enable mdc
14288         lru_resize_enable osc
14289 }
14290 run_test 120g "Early Lock Cancel: performance test"
14291
14292 test_121() { #bug #10589
14293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14294
14295         rm -rf $DIR/$tfile
14296         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14297 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14298         lctl set_param fail_loc=0x310
14299         cancel_lru_locks osc > /dev/null
14300         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14301         lctl set_param fail_loc=0
14302         [[ $reads -eq $writes ]] ||
14303                 error "read $reads blocks, must be $writes blocks"
14304 }
14305 run_test 121 "read cancel race ========="
14306
14307 test_123a_base() { # was test 123, statahead(bug 11401)
14308         local lsx="$1"
14309
14310         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14311
14312         SLOWOK=0
14313         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14314                 log "testing UP system. Performance may be lower than expected."
14315                 SLOWOK=1
14316         fi
14317         running_in_vm && SLOWOK=1
14318
14319         $LCTL set_param mdc.*.batch_stats=0
14320
14321         rm -rf $DIR/$tdir
14322         test_mkdir $DIR/$tdir
14323         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14324         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14325         MULT=10
14326         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14327                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14328
14329                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14330                 lctl set_param -n llite.*.statahead_max 0
14331                 lctl get_param llite.*.statahead_max
14332                 cancel_lru_locks mdc
14333                 cancel_lru_locks osc
14334                 stime=$(date +%s)
14335                 time $lsx $DIR/$tdir | wc -l
14336                 etime=$(date +%s)
14337                 delta=$((etime - stime))
14338                 log "$lsx $i files without statahead: $delta sec"
14339                 lctl set_param llite.*.statahead_max=$max
14340
14341                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14342                          awk '/statahead.wrong:/ { print $NF }')
14343                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14344                 cancel_lru_locks mdc
14345                 cancel_lru_locks osc
14346                 stime=$(date +%s)
14347                 time $lsx $DIR/$tdir | wc -l
14348                 etime=$(date +%s)
14349                 delta_sa=$((etime - stime))
14350                 log "$lsx $i files with statahead: $delta_sa sec"
14351                 lctl get_param -n llite.*.statahead_stats
14352                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14353                          awk '/statahead.wrong:/ { print $NF }')
14354
14355                 [[ $swrong -lt $ewrong ]] &&
14356                         log "statahead was stopped, maybe too many locks held!"
14357                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14358
14359                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14360                         max=$(lctl get_param -n llite.*.statahead_max |
14361                                 head -n 1)
14362                         lctl set_param -n llite.*.statahead_max 0
14363                         lctl get_param llite.*.statahead_max
14364                         cancel_lru_locks mdc
14365                         cancel_lru_locks osc
14366                         stime=$(date +%s)
14367                         time $lsx $DIR/$tdir | wc -l
14368                         etime=$(date +%s)
14369                         delta=$((etime - stime))
14370                         log "$lsx $i files again without statahead: $delta sec"
14371                         lctl set_param llite.*.statahead_max=$max
14372                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14373                                 if [ $SLOWOK -eq 0 ]; then
14374                                         error "$lsx $i files is slower with statahead!"
14375                                 else
14376                                         log "$lsx $i files is slower with statahead!"
14377                                 fi
14378                                 break
14379                         fi
14380                 fi
14381
14382                 [ $delta -gt 20 ] && break
14383                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14384                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14385         done
14386         log "$lsx done"
14387
14388         stime=$(date +%s)
14389         rm -r $DIR/$tdir
14390         sync
14391         etime=$(date +%s)
14392         delta=$((etime - stime))
14393         log "rm -r $DIR/$tdir/: $delta seconds"
14394         log "rm done"
14395         lctl get_param -n llite.*.statahead_stats
14396         $LCTL get_param mdc.*.batch_stats
14397 }
14398
14399 test_123aa() {
14400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14401
14402         test_123a_base "ls -l"
14403 }
14404 run_test 123aa "verify statahead work"
14405
14406 test_123ab() {
14407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14408
14409         statx_supported || skip_env "Test must be statx() syscall supported"
14410
14411         test_123a_base "$STATX -l"
14412 }
14413 run_test 123ab "verify statahead work by using statx"
14414
14415 test_123ac() {
14416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14417
14418         statx_supported || skip_env "Test must be statx() syscall supported"
14419
14420         local rpcs_before
14421         local rpcs_after
14422         local agl_before
14423         local agl_after
14424
14425         cancel_lru_locks $OSC
14426         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14427         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14428                      awk '/agl.total:/ { print $NF }')
14429         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14430         test_123a_base "$STATX --cached=always -D"
14431         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14432                     awk '/agl.total:/ { print $NF }')
14433         [ $agl_before -eq $agl_after ] ||
14434                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14435         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14436         [ $rpcs_after -eq $rpcs_before ] ||
14437                 error "$STATX should not send glimpse RPCs to $OSC"
14438 }
14439 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14440
14441 test_batch_statahead() {
14442         local max=$1
14443         local batch_max=$2
14444         local num=10000
14445         local batch_rpcs
14446         local unbatch_rpcs
14447         local hit_total
14448
14449         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14450         $LCTL set_param mdc.*.batch_stats=0
14451         $LCTL set_param llite.*.statahead_max=$max
14452         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14453         # Verify that batched statahead is faster than one without statahead
14454         test_123a_base "ls -l"
14455
14456         stack_trap "rm -rf $DIR/$tdir" EXIT
14457         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14458         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14459
14460         # unbatched statahead
14461         $LCTL set_param llite.*.statahead_batch_max=0
14462         $LCTL set_param llite.*.statahead_stats=clear
14463         $LCTL set_param mdc.*.stats=clear
14464         cancel_lru_locks mdc
14465         cancel_lru_locks osc
14466         time ls -l $DIR/$tdir | wc -l
14467         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14468         wait_update_facet client "pgrep ll_sa" "" 35 ||
14469                 error "ll_sa thread is still running"
14470         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14471                     awk '/hit.total:/ { print $NF }')
14472         # hit ratio should be larger than 75% (7500).
14473         (( $hit_total > 7500 )) ||
14474                 error "unbatched statahead hit count ($hit_total) is too low"
14475
14476         # batched statahead
14477         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14478         $LCTL set_param llite.*.statahead_stats=clear
14479         $LCTL set_param mdc.*.batch_stats=clear
14480         $LCTL set_param mdc.*.stats=clear
14481         cancel_lru_locks mdc
14482         cancel_lru_locks osc
14483         time ls -l $DIR/$tdir | wc -l
14484         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14485         # wait for statahead thread to quit and update statahead stats
14486         wait_update_facet client "pgrep ll_sa" "" 35 ||
14487                 error "ll_sa thread is still running"
14488         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14489                     awk '/hit.total:/ { print $NF }')
14490         # hit ratio should be larger than 75% (7500).
14491         (( $hit_total > 7500 )) ||
14492                 error "batched statahead hit count ($hit_total) is too low"
14493
14494         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14495         (( $unbatch_rpcs > $batch_rpcs )) ||
14496                 error "batched statahead does not reduce RPC count"
14497         $LCTL get_param mdc.*.batch_stats
14498 }
14499
14500 test_123ad() {
14501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14502
14503         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14504                 skip "Need server version at least 2.15.53"
14505
14506         local max
14507         local batch_max
14508
14509         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14510         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14511
14512         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14513         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14514
14515         test_batch_statahead 32 32
14516         test_batch_statahead 2048 256
14517 }
14518 run_test 123ad "Verify batching statahead works correctly"
14519
14520 test_123b () { # statahead(bug 15027)
14521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14522
14523         test_mkdir $DIR/$tdir
14524         createmany -o $DIR/$tdir/$tfile-%d 1000
14525
14526         cancel_lru_locks mdc
14527         cancel_lru_locks osc
14528
14529 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14530         lctl set_param fail_loc=0x80000803
14531         ls -lR $DIR/$tdir > /dev/null
14532         log "ls done"
14533         lctl set_param fail_loc=0x0
14534         lctl get_param -n llite.*.statahead_stats
14535         rm -r $DIR/$tdir
14536         sync
14537
14538 }
14539 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14540
14541 test_123c() {
14542         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14543
14544         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14545         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14546         touch $DIR/$tdir.1/{1..3}
14547         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14548
14549         remount_client $MOUNT
14550
14551         $MULTIOP $DIR/$tdir.0 Q
14552
14553         # let statahead to complete
14554         ls -l $DIR/$tdir.0 > /dev/null
14555
14556         testid=$(echo $TESTNAME | tr '_' ' ')
14557         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14558                 error "statahead warning" || true
14559 }
14560 run_test 123c "Can not initialize inode warning on DNE statahead"
14561
14562 test_123d() {
14563         local num=100
14564         local swrong
14565         local ewrong
14566
14567         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14568         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14569                 error "setdirstripe $DIR/$tdir failed"
14570         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14571         remount_client $MOUNT
14572         $LCTL get_param llite.*.statahead_max
14573         $LCTL set_param llite.*.statahead_stats=0 ||
14574                 error "clear statahead_stats failed"
14575         swrong=$(lctl get_param -n llite.*.statahead_stats |
14576                  awk '/statahead.wrong:/ { print $NF }')
14577         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14578         # wait for statahead thread finished to update hit/miss stats.
14579         sleep 1
14580         $LCTL get_param -n llite.*.statahead_stats
14581         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14582                  awk '/statahead.wrong:/ { print $NF }')
14583         (( $swrong == $ewrong )) ||
14584                 log "statahead was stopped, maybe too many locks held!"
14585 }
14586 run_test 123d "Statahead on striped directories works correctly"
14587
14588 test_123e() {
14589         local max
14590         local batch_max
14591         local dir=$DIR/$tdir
14592
14593         mkdir $dir || error "mkdir $dir failed"
14594         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14595         stack_trap "rm -rf $dir"
14596
14597         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14598
14599         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14600         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14601         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14602         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14603
14604         $LCTL set_param llite.*.statahead_max=2048
14605         $LCTL set_param llite.*.statahead_batch_max=1024
14606
14607         ls -l $dir
14608         $LCTL get_param mdc.*.batch_stats
14609         $LCTL get_param llite.*.statahead_*
14610 }
14611 run_test 123e "statahead with large wide striping"
14612
14613 test_123f() {
14614         local max
14615         local batch_max
14616         local dir=$DIR/$tdir
14617
14618         mkdir $dir || error "mkdir $dir failed"
14619         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14620         stack_trap "rm -rf $dir"
14621
14622         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14623
14624         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14625         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14626
14627         $LCTL set_param llite.*.statahead_max=64
14628         $LCTL set_param llite.*.statahead_batch_max=64
14629
14630         ls -l $dir
14631         lctl get_param mdc.*.batch_stats
14632         lctl get_param llite.*.statahead_*
14633
14634         $LCTL set_param llite.*.statahead_max=$max
14635         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14636 }
14637 run_test 123f "Retry mechanism with large wide striping files"
14638
14639 test_123g() {
14640         local dir=$DIR/$tdir
14641         local num=1000
14642
14643         mkdir $dir || error "failed to mkdir $dir"
14644         createmany -o $dir/$tfile $num || error "failed creatmany files"
14645         cancel_lru_locks mdc
14646         cancel_lru_locks osc
14647
14648         $LCTL set_param llite.*.statahead_stats=clear
14649         $LCTL set_param mdc.*.batch_stats=clear
14650         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14651                 error "aheadmany $dir with $tfile failed"
14652         wait_update_facet client "pgrep ll_sa" "" 35 ||
14653                 error "ll_sa thread is still running"
14654         $LCTL get_param -n llite.*.statahead_stats
14655         $LCTL get_param -n mdc.*.batch_stats
14656
14657         local count
14658
14659         count=$($LCTL get_param -n llite.*.statahead_stats |
14660                 awk '/hit.total:/ {print $2}')
14661         echo "Hit total: $count"
14662         # Hit ratio should be >= 75%
14663         (( $count > num * 75 / 100 )) ||
14664                 error "hit total $count is be > 75% of $num"
14665 }
14666 run_test 123g "Test for stat-ahead advise"
14667
14668 test_123h_base() {
14669         local dir=$DIR/$tdir
14670         local cmd="touch $dir/$tfile.{$1}"
14671         local fcnt=$2
14672
14673         stack_trap "rm -rf $dir"
14674         mkdir -p $dir || error "failed to mkdir $dir"
14675         eval $cmd
14676
14677         cancel_lru_locks mdc
14678         $LCTL set_param llite.*.statahead_stats=clear
14679         $LCTL set_param mdc.*.batch_stats=0
14680         $LCTL set_param llite.*.statahead_max=1024
14681         $LCTL set_param llite.*.statahead_batch_max=1024
14682         lctl get_param -n llite.*.statahead_stats
14683         du -a $dir > /dev/null
14684         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14685         wait_update_facet client "pgrep ll_sa" "" 35 ||
14686                 error "ll_sa statahead thread does not quit in 35s"
14687         $LCTL get_param -n llite.*.statahead_stats
14688         $LCTL get_param -n mdc.*.batch_stats
14689
14690         local count=$($LCTL get_param -n llite.*.statahead_stats |
14691                         awk '/fname.total:/ {print $2}')
14692
14693         [ $count == 1 ] || error "File name pattern statahead not trigger"
14694         count=$($LCTL get_param -n llite.*.statahead_stats |
14695                 awk '/hit.total:/ {print $2}')
14696         # Hit ratio should be >= 75%
14697         (( $count > fcnt * 75 / 100 )) ||
14698                 error "hit total is too low: $count"
14699         rm -rf $dir || error "rm -rf $dir failed"
14700 }
14701
14702 test_123h() {
14703         local max
14704         local batch_max
14705         local enabled
14706
14707         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14708         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14709         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14710         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14711         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14712         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14713
14714         $LCTL set_param llite.*.enable_statahead_fname=1
14715
14716         echo "Scan a directory with number regularized fname"
14717         test_123h_base "0..10000" 10000
14718
14719         echo "Scan a directory with zeroed padding number regularized fname"
14720         test_123h_base "000000..010000" 10000
14721 }
14722 run_test 123h "Verify statahead work with the fname pattern via du"
14723
14724 test_123i_base() {
14725         local fmt=$1
14726         local iocmd=$2
14727         local dir=$DIR/$tdir
14728         local cmd="createmany -m $fmt"
14729
14730         echo "Command:"
14731         echo "- $cmd"
14732         echo "- $iocmd"
14733         stack_trap "unlinkmany $fmt"
14734         mkdir -p $dir || error "failed to mkdir $dir"
14735         eval $cmd
14736
14737         cancel_lru_locks mdc
14738         $LCTL set_param llite.*.statahead_stats=clear
14739         $LCTL set_param mdc.*.batch_stats=0
14740
14741         echo "statahead_stats (Pre):"
14742         lctl get_param -n llite.*.statahead_stats
14743         eval $iocmd || error "$iocmd failed"
14744         echo "statahead_stats (Post):"
14745         $LCTL get_param -n llite.*.statahead_stats
14746         $LCTL get_param -n mdc.*.batch_stats
14747
14748         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14749         wait_update_facet client "pgrep ll_sa" "" 35 ||
14750                 error "ll_sa statahead thread does not quit in 35s"
14751         $LCTL get_param -n llite.*.statahead_stats
14752         $LCTL get_param -n mdc.*.batch_stats
14753
14754         local count=$($LCTL get_param -n llite.*.statahead_stats |
14755                         awk '/fname.total:/ {print $2}')
14756
14757         [ $count == 1 ] || error "File name pattern statahead not trigger"
14758         count=$($LCTL get_param -n llite.*.statahead_stats |
14759                 awk '/hit.total:/ {print $2}')
14760         # Hit ratio should be >= 75%
14761         (( $count > 750 )) || error "hit total is too low: $count"
14762 }
14763
14764 test_123i() {
14765         local dir=$DIR/$tdir
14766         local cnt=1000
14767         local max
14768         local batch_max
14769         local enabled
14770         local min
14771
14772         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14773         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14774         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14775         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14776         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14777         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14778         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14779         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14780         $LCTL set_param llite.*.statahead_max=1024
14781         $LCTL set_param llite.*.statahead_batch_max=32
14782         $LCTL set_param llite.*.statahead_min=64
14783         $LCTL set_param llite.*.enable_statahead_fname=1
14784
14785         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14786         test_123i_base "$dir/$tfile $cnt" \
14787                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14788 }
14789 run_test 123i "Verify statahead work with the fname indexing pattern"
14790
14791 test_124a() {
14792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14793         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14794                 skip_env "no lru resize on server"
14795
14796         local NR=2000
14797
14798         test_mkdir $DIR/$tdir
14799
14800         log "create $NR files at $DIR/$tdir"
14801         createmany -o $DIR/$tdir/f $NR ||
14802                 error "failed to create $NR files in $DIR/$tdir"
14803
14804         cancel_lru_locks mdc
14805         ls -l $DIR/$tdir > /dev/null
14806
14807         local NSDIR=""
14808         local LRU_SIZE=0
14809         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14810                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14811                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14812                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14813                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14814                         log "NSDIR=$NSDIR"
14815                         log "NS=$(basename $NSDIR)"
14816                         break
14817                 fi
14818         done
14819
14820         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14821                 skip "Not enough cached locks created!"
14822         fi
14823         log "LRU=$LRU_SIZE"
14824
14825         local SLEEP=30
14826
14827         # We know that lru resize allows one client to hold $LIMIT locks
14828         # for 10h. After that locks begin to be killed by client.
14829         local MAX_HRS=10
14830         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14831         log "LIMIT=$LIMIT"
14832         if [ $LIMIT -lt $LRU_SIZE ]; then
14833                 skip "Limit is too small $LIMIT"
14834         fi
14835
14836         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14837         # killing locks. Some time was spent for creating locks. This means
14838         # that up to the moment of sleep finish we must have killed some of
14839         # them (10-100 locks). This depends on how fast ther were created.
14840         # Many of them were touched in almost the same moment and thus will
14841         # be killed in groups.
14842         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14843
14844         # Use $LRU_SIZE_B here to take into account real number of locks
14845         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14846         local LRU_SIZE_B=$LRU_SIZE
14847         log "LVF=$LVF"
14848         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14849         log "OLD_LVF=$OLD_LVF"
14850         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14851
14852         # Let's make sure that we really have some margin. Client checks
14853         # cached locks every 10 sec.
14854         SLEEP=$((SLEEP+20))
14855         log "Sleep ${SLEEP} sec"
14856         local SEC=0
14857         while ((SEC<$SLEEP)); do
14858                 echo -n "..."
14859                 sleep 5
14860                 SEC=$((SEC+5))
14861                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14862                 echo -n "$LRU_SIZE"
14863         done
14864         echo ""
14865         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14866         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14867
14868         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14869                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14870                 unlinkmany $DIR/$tdir/f $NR
14871                 return
14872         }
14873
14874         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14875         log "unlink $NR files at $DIR/$tdir"
14876         unlinkmany $DIR/$tdir/f $NR
14877 }
14878 run_test 124a "lru resize ======================================="
14879
14880 get_max_pool_limit()
14881 {
14882         local limit=$($LCTL get_param \
14883                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14884         local max=0
14885         for l in $limit; do
14886                 if [[ $l -gt $max ]]; then
14887                         max=$l
14888                 fi
14889         done
14890         echo $max
14891 }
14892
14893 test_124b() {
14894         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14895         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14896                 skip_env "no lru resize on server"
14897
14898         LIMIT=$(get_max_pool_limit)
14899
14900         NR=$(($(default_lru_size)*20))
14901         if [[ $NR -gt $LIMIT ]]; then
14902                 log "Limit lock number by $LIMIT locks"
14903                 NR=$LIMIT
14904         fi
14905
14906         IFree=$(mdsrate_inodes_available)
14907         if [ $IFree -lt $NR ]; then
14908                 log "Limit lock number by $IFree inodes"
14909                 NR=$IFree
14910         fi
14911
14912         lru_resize_disable mdc
14913         test_mkdir -p $DIR/$tdir/disable_lru_resize
14914
14915         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14916         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14917         cancel_lru_locks mdc
14918         stime=`date +%s`
14919         PID=""
14920         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14921         PID="$PID $!"
14922         sleep 2
14923         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14924         PID="$PID $!"
14925         sleep 2
14926         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14927         PID="$PID $!"
14928         wait $PID
14929         etime=`date +%s`
14930         nolruresize_delta=$((etime-stime))
14931         log "ls -la time: $nolruresize_delta seconds"
14932         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14933         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14934
14935         lru_resize_enable mdc
14936         test_mkdir -p $DIR/$tdir/enable_lru_resize
14937
14938         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14939         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14940         cancel_lru_locks mdc
14941         stime=`date +%s`
14942         PID=""
14943         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14944         PID="$PID $!"
14945         sleep 2
14946         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14947         PID="$PID $!"
14948         sleep 2
14949         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14950         PID="$PID $!"
14951         wait $PID
14952         etime=`date +%s`
14953         lruresize_delta=$((etime-stime))
14954         log "ls -la time: $lruresize_delta seconds"
14955         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14956
14957         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14958                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14959         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14960                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14961         else
14962                 log "lru resize performs the same with no lru resize"
14963         fi
14964         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14965 }
14966 run_test 124b "lru resize (performance test) ======================="
14967
14968 test_124c() {
14969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14970         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14971                 skip_env "no lru resize on server"
14972
14973         # cache ununsed locks on client
14974         local nr=100
14975         cancel_lru_locks mdc
14976         test_mkdir $DIR/$tdir
14977         createmany -o $DIR/$tdir/f $nr ||
14978                 error "failed to create $nr files in $DIR/$tdir"
14979         ls -l $DIR/$tdir > /dev/null
14980
14981         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14982         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14983         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14984         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14985         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14986
14987         # set lru_max_age to 1 sec
14988         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14989         echo "sleep $((recalc_p * 2)) seconds..."
14990         sleep $((recalc_p * 2))
14991
14992         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14993         # restore lru_max_age
14994         $LCTL set_param -n $nsdir.lru_max_age $max_age
14995         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14996         unlinkmany $DIR/$tdir/f $nr
14997 }
14998 run_test 124c "LRUR cancel very aged locks"
14999
15000 test_124d() {
15001         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15002         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
15003                 skip_env "no lru resize on server"
15004
15005         # cache ununsed locks on client
15006         local nr=100
15007
15008         lru_resize_disable mdc
15009         stack_trap "lru_resize_enable mdc" EXIT
15010
15011         cancel_lru_locks mdc
15012
15013         # asynchronous object destroy at MDT could cause bl ast to client
15014         test_mkdir $DIR/$tdir
15015         createmany -o $DIR/$tdir/f $nr ||
15016                 error "failed to create $nr files in $DIR/$tdir"
15017         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
15018
15019         ls -l $DIR/$tdir > /dev/null
15020
15021         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15022         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15023         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
15024         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
15025
15026         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
15027
15028         # set lru_max_age to 1 sec
15029         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
15030         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
15031
15032         echo "sleep $((recalc_p * 2)) seconds..."
15033         sleep $((recalc_p * 2))
15034
15035         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
15036
15037         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
15038 }
15039 run_test 124d "cancel very aged locks if lru-resize disabled"
15040
15041 test_125() { # 13358
15042         $LCTL get_param -n llite.*.client_type | grep -q local ||
15043                 skip "must run as local client"
15044         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
15045                 skip_env "must have acl enabled"
15046         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
15047         id $USER0 || skip_env "missing user $USER0"
15048
15049         test_mkdir $DIR/$tdir
15050         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
15051         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
15052                 error "setfacl $DIR/$tdir failed"
15053         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
15054 }
15055 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
15056
15057 test_126() { # bug 12829/13455
15058         $GSS && skip_env "must run as gss disabled"
15059         $LCTL get_param -n llite.*.client_type | grep -q local ||
15060                 skip "must run as local client"
15061         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
15062
15063         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
15064         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
15065         rm -f $DIR/$tfile
15066         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
15067 }
15068 run_test 126 "check that the fsgid provided by the client is taken into account"
15069
15070 test_127a() { # bug 15521
15071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15072         local name count samp unit min max sum sumsq
15073         local tmpfile=$TMP/$tfile.tmp
15074
15075         # enable stats header if it is disabled
15076         $LCTL set_param enable_stats_header=1
15077
15078         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15079         echo "stats before reset"
15080         stack_trap "rm -f $tmpfile"
15081         local now=$(date +%s)
15082
15083         $LCTL get_param osc.*.stats | tee $tmpfile
15084
15085         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15086         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15087         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15088         local uptime=$(awk '{ print $1 }' /proc/uptime)
15089
15090         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15091         (( ${snapshot_time%\.*} >= $now - 5 &&
15092            ${snapshot_time%\.*} <= $now + 5 )) ||
15093                 error "snapshot_time=$snapshot_time != now=$now"
15094         # elapsed _should_ be from mount, but at least less than uptime
15095         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15096                 error "elapsed=$elapsed > uptime=$uptime"
15097         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15098            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15099                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15100
15101         $LCTL set_param osc.*.stats=0
15102         local reset=$(date +%s)
15103         local fsize=$((2048 * 1024))
15104
15105         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15106         cancel_lru_locks osc
15107         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15108
15109         now=$(date +%s)
15110         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15111         while read name count samp unit min max sum sumsq; do
15112                 [[ "$samp" == "samples" ]] || continue
15113
15114                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15115                 [ ! $min ] && error "Missing min value for $name proc entry"
15116                 eval $name=$count || error "Wrong proc format"
15117
15118                 case $name in
15119                 read_bytes|write_bytes)
15120                         [[ "$unit" =~ "bytes" ]] ||
15121                                 error "unit is not 'bytes': $unit"
15122                         (( $min >= 4096 )) || error "min is too small: $min"
15123                         (( $min <= $fsize )) || error "min is too big: $min"
15124                         (( $max >= 4096 )) || error "max is too small: $max"
15125                         (( $max <= $fsize )) || error "max is too big: $max"
15126                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15127                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15128                                 error "sumsquare is too small: $sumsq"
15129                         (( $sumsq <= $fsize * $fsize )) ||
15130                                 error "sumsquare is too big: $sumsq"
15131                         ;;
15132                 ost_read|ost_write)
15133                         [[ "$unit" =~ "usec" ]] ||
15134                                 error "unit is not 'usec': $unit"
15135                         ;;
15136                 *)      ;;
15137                 esac
15138         done < $tmpfile
15139
15140         #check that we actually got some stats
15141         [ "$read_bytes" ] || error "Missing read_bytes stats"
15142         [ "$write_bytes" ] || error "Missing write_bytes stats"
15143         [ "$read_bytes" != 0 ] || error "no read done"
15144         [ "$write_bytes" != 0 ] || error "no write done"
15145
15146         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15147         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15148         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15149
15150         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15151         (( ${snapshot_time%\.*} >= $now - 5 &&
15152            ${snapshot_time%\.*} <= $now + 5 )) ||
15153                 error "reset snapshot_time=$snapshot_time != now=$now"
15154         # elapsed should be from time of stats reset
15155         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15156            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15157                 error "reset elapsed=$elapsed > $now - $reset"
15158         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15159            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15160                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15161 }
15162 run_test 127a "verify the client stats are sane"
15163
15164 test_127b() { # bug LU-333
15165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15166         local name count samp unit min max sum sumsq
15167
15168         echo "stats before reset"
15169         $LCTL get_param llite.*.stats
15170         $LCTL set_param llite.*.stats=0
15171
15172         # perform 2 reads and writes so MAX is different from SUM.
15173         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15174         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15175         cancel_lru_locks osc
15176         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15177         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15178
15179         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15180         stack_trap "rm -f $TMP/$tfile.tmp"
15181         while read name count samp unit min max sum sumsq; do
15182                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15183                 eval $name=$count || error "Wrong proc format"
15184
15185                 case $name in
15186                 read_bytes|write_bytes)
15187                         [[ "$unit" =~ "bytes" ]] ||
15188                                 error "unit is not 'bytes': $unit"
15189                         (( $count == 2 )) || error "count is not 2: $count"
15190                         (( $min == $PAGE_SIZE )) ||
15191                                 error "min is not $PAGE_SIZE: $min"
15192                         (( $max == $PAGE_SIZE )) ||
15193                                 error "max is not $PAGE_SIZE: $max"
15194                         (( $sum == $PAGE_SIZE * 2 )) ||
15195                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15196                         ;;
15197                 read|write)
15198                         [[ "$unit" =~ "usec" ]] ||
15199                                 error "unit is not 'usec': $unit"
15200                         ;;
15201                 *)      ;;
15202                 esac
15203         done < $TMP/$tfile.tmp
15204
15205         #check that we actually got some stats
15206         [ "$read_bytes" ] || error "Missing read_bytes stats"
15207         [ "$write_bytes" ] || error "Missing write_bytes stats"
15208         [ "$read_bytes" != 0 ] || error "no read done"
15209         [ "$write_bytes" != 0 ] || error "no write done"
15210 }
15211 run_test 127b "verify the llite client stats are sane"
15212
15213 test_127c() { # LU-12394
15214         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15215         local size
15216         local bsize
15217         local reads
15218         local writes
15219         local count
15220
15221         $LCTL set_param llite.*.extents_stats=1
15222         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15223
15224         # Use two stripes so there is enough space in default config
15225         $LFS setstripe -c 2 $DIR/$tfile
15226
15227         # Extent stats start at 0-4K and go in power of two buckets
15228         # LL_HIST_START = 12 --> 2^12 = 4K
15229         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15230         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15231         # small configs
15232         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15233                 do
15234                 # Write and read, 2x each, second time at a non-zero offset
15235                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15236                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15237                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15238                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15239                 rm -f $DIR/$tfile
15240         done
15241
15242         $LCTL get_param llite.*.extents_stats
15243
15244         count=2
15245         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15246                 do
15247                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15248                                 grep -m 1 $bsize)
15249                 reads=$(echo $bucket | awk '{print $5}')
15250                 writes=$(echo $bucket | awk '{print $9}')
15251                 [ "$reads" -eq $count ] ||
15252                         error "$reads reads in < $bsize bucket, expect $count"
15253                 [ "$writes" -eq $count ] ||
15254                         error "$writes writes in < $bsize bucket, expect $count"
15255         done
15256
15257         # Test mmap write and read
15258         $LCTL set_param llite.*.extents_stats=c
15259         size=512
15260         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15261         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15262         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15263
15264         $LCTL get_param llite.*.extents_stats
15265
15266         count=$(((size*1024) / PAGE_SIZE))
15267
15268         bsize=$((2 * PAGE_SIZE / 1024))K
15269
15270         bucket=$($LCTL get_param -n llite.*.extents_stats |
15271                         grep -m 1 $bsize)
15272         reads=$(echo $bucket | awk '{print $5}')
15273         writes=$(echo $bucket | awk '{print $9}')
15274         # mmap writes fault in the page first, creating an additonal read
15275         [ "$reads" -eq $((2 * count)) ] ||
15276                 error "$reads reads in < $bsize bucket, expect $count"
15277         [ "$writes" -eq $count ] ||
15278                 error "$writes writes in < $bsize bucket, expect $count"
15279 }
15280 run_test 127c "test llite extent stats with regular & mmap i/o"
15281
15282 test_128() { # bug 15212
15283         touch $DIR/$tfile
15284         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15285                 find $DIR/$tfile
15286                 find $DIR/$tfile
15287         EOF
15288
15289         result=$(grep error $TMP/$tfile.log)
15290         rm -f $DIR/$tfile $TMP/$tfile.log
15291         [ -z "$result" ] ||
15292                 error "consecutive find's under interactive lfs failed"
15293 }
15294 run_test 128 "interactive lfs for 2 consecutive find's"
15295
15296 set_dir_limits () {
15297         local mntdev
15298         local canondev
15299         local node
15300
15301         local ldproc=/proc/fs/ldiskfs
15302         local facets=$(get_facets MDS)
15303
15304         for facet in ${facets//,/ }; do
15305                 canondev=$(ldiskfs_canon \
15306                            *.$(convert_facet2label $facet).mntdev $facet)
15307                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15308                         ldproc=/sys/fs/ldiskfs
15309                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15310                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15311         done
15312 }
15313
15314 check_mds_dmesg() {
15315         local facets=$(get_facets MDS)
15316         for facet in ${facets//,/ }; do
15317                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15318         done
15319         return 1
15320 }
15321
15322 test_129() {
15323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15324         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15325                 skip "Need MDS version with at least 2.5.56"
15326         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15327                 skip_env "ldiskfs only test"
15328         fi
15329         remote_mds_nodsh && skip "remote MDS with nodsh"
15330
15331         local ENOSPC=28
15332         local has_warning=false
15333
15334         rm -rf $DIR/$tdir
15335         mkdir -p $DIR/$tdir
15336
15337         # block size of mds1
15338         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15339         set_dir_limits $maxsize $((maxsize * 6 / 8))
15340         stack_trap "set_dir_limits 0 0"
15341         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15342         local dirsize=$(stat -c%s "$DIR/$tdir")
15343         local nfiles=0
15344         while (( $dirsize <= $maxsize )); do
15345                 $MCREATE $DIR/$tdir/file_base_$nfiles
15346                 rc=$?
15347                 # check two errors:
15348                 # ENOSPC for ext4 max_dir_size, which has been used since
15349                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15350                 if (( rc == ENOSPC )); then
15351                         set_dir_limits 0 0
15352                         echo "rc=$rc returned as expected after $nfiles files"
15353
15354                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15355                                 error "create failed w/o dir size limit"
15356
15357                         # messages may be rate limited if test is run repeatedly
15358                         check_mds_dmesg '"is approaching max"' ||
15359                                 echo "warning message should be output"
15360                         check_mds_dmesg '"has reached max"' ||
15361                                 echo "reached message should be output"
15362
15363                         dirsize=$(stat -c%s "$DIR/$tdir")
15364
15365                         [[ $dirsize -ge $maxsize ]] && return 0
15366                         error "dirsize $dirsize < $maxsize after $nfiles files"
15367                 elif (( rc != 0 )); then
15368                         break
15369                 fi
15370                 nfiles=$((nfiles + 1))
15371                 dirsize=$(stat -c%s "$DIR/$tdir")
15372         done
15373
15374         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15375 }
15376 run_test 129 "test directory size limit ========================"
15377
15378 OLDIFS="$IFS"
15379 cleanup_130() {
15380         trap 0
15381         IFS="$OLDIFS"
15382         rm -f $DIR/$tfile
15383 }
15384
15385 test_130a() {
15386         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15387         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15388
15389         trap cleanup_130 EXIT RETURN
15390
15391         local fm_file=$DIR/$tfile
15392         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15393         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15394                 error "dd failed for $fm_file"
15395
15396         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15397         filefrag -ves $fm_file
15398         local rc=$?
15399         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15400                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15401         (( $rc == 0 )) || error "filefrag $fm_file failed"
15402
15403         filefrag_op=$(filefrag -ve -k $fm_file |
15404                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15405         local lun=$($LFS getstripe -i $fm_file)
15406
15407         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15408         IFS=$'\n'
15409         local tot_len=0
15410         for line in $filefrag_op; do
15411                 local frag_lun=$(echo $line | cut -d: -f5)
15412                 local ext_len=$(echo $line | cut -d: -f4)
15413
15414                 if (( $frag_lun != $lun )); then
15415                         error "FIEMAP on 1-stripe file($fm_file) failed"
15416                         return
15417                 fi
15418                 (( tot_len += ext_len ))
15419         done
15420
15421         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15422                 error "FIEMAP on 1-stripe file($fm_file) failed"
15423                 return
15424         fi
15425
15426         echo "FIEMAP on single striped file succeeded"
15427 }
15428 run_test 130a "FIEMAP (1-stripe file)"
15429
15430 test_130b() {
15431         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15432
15433         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15434         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15435         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15436                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15437
15438         trap cleanup_130 EXIT RETURN
15439
15440         local fm_file=$DIR/$tfile
15441         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15442                 error "setstripe on $fm_file"
15443
15444         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15445                 error "dd failed on $fm_file"
15446
15447         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15448         filefrag_op=$(filefrag -ve -k $fm_file |
15449                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15450
15451         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15452                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15453
15454         IFS=$'\n'
15455         local tot_len=0
15456         local num_luns=1
15457
15458         for line in $filefrag_op; do
15459                 local frag_lun=$(echo $line | cut -d: -f5 |
15460                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15461                 local ext_len=$(echo $line | cut -d: -f4)
15462                 if (( $frag_lun != $last_lun )); then
15463                         if (( tot_len != 1024 )); then
15464                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15465                                 return
15466                         else
15467                                 (( num_luns += 1 ))
15468                                 tot_len=0
15469                         fi
15470                 fi
15471                 (( tot_len += ext_len ))
15472                 last_lun=$frag_lun
15473         done
15474         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15475                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15476                 return
15477         fi
15478
15479         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15480 }
15481 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15482
15483 test_130c() {
15484         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15485
15486         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15487         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15488         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15489                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15490
15491         trap cleanup_130 EXIT RETURN
15492
15493         local fm_file=$DIR/$tfile
15494         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15495
15496         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15497                 error "dd failed on $fm_file"
15498
15499         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15500         filefrag_op=$(filefrag -ve -k $fm_file |
15501                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15502
15503         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15504                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15505
15506         IFS=$'\n'
15507         local tot_len=0
15508         local num_luns=1
15509         for line in $filefrag_op; do
15510                 local frag_lun=$(echo $line | cut -d: -f5 |
15511                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15512                 local ext_len=$(echo $line | cut -d: -f4)
15513                 if (( $frag_lun != $last_lun )); then
15514                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15515                         if (( logical != 512 )); then
15516                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15517                                 return
15518                         fi
15519                         if (( tot_len != 512 )); then
15520                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15521                                 return
15522                         else
15523                                 (( num_luns += 1 ))
15524                                 tot_len=0
15525                         fi
15526                 fi
15527                 (( tot_len += ext_len ))
15528                 last_lun=$frag_lun
15529         done
15530         if (( num_luns != 2 || tot_len != 512 )); then
15531                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15532                 return
15533         fi
15534
15535         echo "FIEMAP on 2-stripe file with hole succeeded"
15536 }
15537 run_test 130c "FIEMAP (2-stripe file with hole)"
15538
15539 test_130d() {
15540         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15541
15542         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15543         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15544         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15545                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15546
15547         trap cleanup_130 EXIT RETURN
15548
15549         local fm_file=$DIR/$tfile
15550         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15551                         error "setstripe on $fm_file"
15552
15553         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15554         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15555                 error "dd failed on $fm_file"
15556
15557         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15558         filefrag_op=$(filefrag -ve -k $fm_file |
15559                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15560
15561         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15562                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15563
15564         IFS=$'\n'
15565         local tot_len=0
15566         local num_luns=1
15567         for line in $filefrag_op; do
15568                 local frag_lun=$(echo $line | cut -d: -f5 |
15569                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15570                 local ext_len=$(echo $line | cut -d: -f4)
15571                 if (( $frag_lun != $last_lun )); then
15572                         if (( tot_len != 1024 )); then
15573                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15574                                 return
15575                         else
15576                                 (( num_luns += 1 ))
15577                                 local tot_len=0
15578                         fi
15579                 fi
15580                 (( tot_len += ext_len ))
15581                 last_lun=$frag_lun
15582         done
15583         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15584                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15585                 return
15586         fi
15587
15588         echo "FIEMAP on N-stripe file succeeded"
15589 }
15590 run_test 130d "FIEMAP (N-stripe file)"
15591
15592 test_130e() {
15593         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15594
15595         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15596         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15597         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15598                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15599
15600         trap cleanup_130 EXIT RETURN
15601
15602         local fm_file=$DIR/$tfile
15603         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15604         stack_trap "rm -f $fm_file"
15605
15606         local num_blks=512
15607         local expected_len=$(( (num_blks / 2) * 64 ))
15608         for ((i = 0; i < $num_blks; i++)); do
15609                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15610                         conv=notrunc > /dev/null 2>&1
15611         done
15612
15613         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15614         filefrag_op=$(filefrag -ve -k $fm_file |
15615                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15616
15617         local last_lun=$(echo $filefrag_op | cut -d: -f5)
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                 local ext_len=$(echo $line | cut -d: -f4)
15625                 if (( $frag_lun != $last_lun )); then
15626                         if (( tot_len != $expected_len )); then
15627                                 error "OST$last_lun $tot_len != $expected_len"
15628                         else
15629                                 (( num_luns += 1 ))
15630                                 tot_len=0
15631                         fi
15632                 fi
15633                 (( tot_len += ext_len ))
15634                 last_lun=$frag_lun
15635         done
15636         if (( num_luns != 2 || tot_len != $expected_len )); then
15637                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15638         fi
15639
15640         echo "FIEMAP with continuation calls succeeded"
15641 }
15642 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15643
15644 test_130f() {
15645         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15646         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15647         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15648                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15649
15650         local fm_file=$DIR/$tfile
15651         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15652                 error "multiop create with lov_delay_create on $fm_file"
15653
15654         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15655         filefrag_extents=$(filefrag -vek $fm_file |
15656                            awk '/extents? found/ { print $2 }')
15657         if (( $filefrag_extents != 0 )); then
15658                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15659         fi
15660
15661         rm -f $fm_file
15662 }
15663 run_test 130f "FIEMAP (unstriped file)"
15664
15665 test_130g() {
15666         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15667                 skip "Need MDS version with at least 2.12.53 for overstriping"
15668         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15669         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15670         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15671                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15672
15673         local file=$DIR/$tfile
15674         local nr=$((OSTCOUNT * 100))
15675
15676         $LFS setstripe -C $nr -S1M $file ||
15677                 error "failed to setstripe -C $nr $file"
15678
15679         stack_trap "rm -f $file"
15680         dd if=/dev/zero of=$file count=$nr bs=1M
15681         sync
15682         nr=$($LFS getstripe -c $file)
15683
15684         local extents=$(filefrag -v $file |
15685                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15686
15687         echo "filefrag list $extents extents in file with stripecount $nr"
15688         if (( extents < nr )); then
15689                 $LFS getstripe $file
15690                 filefrag -v $file
15691                 error "filefrag printed $extents < $nr extents"
15692         fi
15693 }
15694 run_test 130g "FIEMAP (overstripe file)"
15695
15696 # Test for writev/readv
15697 test_131a() {
15698         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15699                 error "writev test failed"
15700         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15701                 error "readv failed"
15702         rm -f $DIR/$tfile
15703 }
15704 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15705
15706 test_131b() {
15707         local fsize=$((524288 + 1048576 + 1572864))
15708         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15709                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15710                         error "append writev test failed"
15711
15712         ((fsize += 1572864 + 1048576))
15713         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15714                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15715                         error "append writev test failed"
15716         rm -f $DIR/$tfile
15717 }
15718 run_test 131b "test append writev"
15719
15720 test_131c() {
15721         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15722         error "NOT PASS"
15723 }
15724 run_test 131c "test read/write on file w/o objects"
15725
15726 test_131d() {
15727         rwv -f $DIR/$tfile -w -n 1 1572864
15728         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15729         if [ "$NOB" != 1572864 ]; then
15730                 error "Short read filed: read $NOB bytes instead of 1572864"
15731         fi
15732         rm -f $DIR/$tfile
15733 }
15734 run_test 131d "test short read"
15735
15736 test_131e() {
15737         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15738         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15739         error "read hitting hole failed"
15740         rm -f $DIR/$tfile
15741 }
15742 run_test 131e "test read hitting hole"
15743
15744 check_stats() {
15745         local facet=$1
15746         local op=$2
15747         local want=${3:-0}
15748         local res
15749
15750         # open             11 samples [usecs] 468 4793 13658 35791898
15751         case $facet in
15752         mds*) res=($(do_facet $facet \
15753                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15754                  ;;
15755         ost*) res=($(do_facet $facet \
15756                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15757                  ;;
15758         *) error "Wrong facet '$facet'" ;;
15759         esac
15760         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15761         # if $want is zero, it means any stat increment is ok.
15762         if (( $want > 0 )); then
15763                 local count=${res[1]}
15764
15765                 if (( $count != $want )); then
15766                         if [[ $facet =~ "mds" ]]; then
15767                                 do_nodes $(comma_list $(mdts_nodes)) \
15768                                         $LCTL get_param mdt.*.md_stats
15769                         else
15770                                 do_nodes $(comma_list $(osts-nodes)) \
15771                                         $LCTL get_param obdfilter.*.stats
15772                         fi
15773                         error "The $op counter on $facet is $count, not $want"
15774                 fi
15775         fi
15776 }
15777
15778 test_133a() {
15779         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15780         remote_ost_nodsh && skip "remote OST with nodsh"
15781         remote_mds_nodsh && skip "remote MDS with nodsh"
15782         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15783                 skip_env "MDS doesn't support rename stats"
15784
15785         local testdir=$DIR/${tdir}/stats_testdir
15786
15787         mkdir_on_mdt0 $DIR/${tdir}
15788
15789         # clear stats.
15790         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15791         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15792
15793         # verify mdt stats first.
15794         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15795         check_stats $SINGLEMDS "mkdir" 1
15796
15797         # clear "open" from "lfs mkdir" above
15798         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15799         touch ${testdir}/${tfile} || error "touch failed"
15800         check_stats $SINGLEMDS "open" 1
15801         check_stats $SINGLEMDS "close" 1
15802         # open should match close
15803         ls -lR ${testdir}
15804         check_stats $SINGLEMDS "open" 2
15805         check_stats $SINGLEMDS "close" 2
15806         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15807                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15808                 check_stats $SINGLEMDS "mknod" 2
15809         }
15810         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15811         check_stats $SINGLEMDS "unlink" 1
15812         rm -f ${testdir}/${tfile} || error "file remove failed"
15813         check_stats $SINGLEMDS "unlink" 2
15814
15815         # remove working dir and check mdt stats again.
15816         rmdir ${testdir} || error "rmdir failed"
15817         check_stats $SINGLEMDS "rmdir" 1
15818
15819         local testdir1=$DIR/${tdir}/stats_testdir1
15820         mkdir_on_mdt0 ${testdir}
15821         mkdir_on_mdt0 ${testdir1}
15822         touch ${testdir1}/test1
15823         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15824         check_stats $SINGLEMDS "crossdir_rename" 1
15825
15826         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15827         check_stats $SINGLEMDS "samedir_rename" 1
15828
15829         rm -rf $DIR/${tdir}
15830 }
15831 run_test 133a "Verifying MDT stats ========================================"
15832
15833 test_133b() {
15834         local res
15835
15836         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15837         remote_ost_nodsh && skip "remote OST with nodsh"
15838         remote_mds_nodsh && skip "remote MDS with nodsh"
15839
15840         local testdir=$DIR/${tdir}/stats_testdir
15841
15842         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15843         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15844         touch ${testdir}/${tfile} || error "touch failed"
15845         cancel_lru_locks mdc
15846
15847         # clear stats.
15848         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15849         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15850
15851         # extra mdt stats verification.
15852         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15853         check_stats $SINGLEMDS "setattr" 1
15854         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15855         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15856         then            # LU-1740
15857                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15858                 check_stats $SINGLEMDS "getattr" 1
15859         fi
15860         rm -rf $DIR/${tdir}
15861
15862         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15863         # so the check below is not reliable
15864         [ $MDSCOUNT -eq 1 ] || return 0
15865
15866         # Sleep to avoid a cached response.
15867         #define OBD_STATFS_CACHE_SECONDS 1
15868         sleep 2
15869         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15870         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15871         $LFS df || error "lfs failed"
15872         check_stats $SINGLEMDS "statfs" 1
15873
15874         # check aggregated statfs (LU-10018)
15875         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15876                 return 0
15877         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15878                 return 0
15879         sleep 2
15880         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15881         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15882         df $DIR
15883         check_stats $SINGLEMDS "statfs" 1
15884
15885         # We want to check that the client didn't send OST_STATFS to
15886         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15887         # extra care is needed here.
15888         if remote_mds; then
15889                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15890                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15891
15892                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15893                 [ "$res" ] && error "OST got STATFS"
15894         fi
15895
15896         return 0
15897 }
15898 run_test 133b "Verifying extra MDT stats =================================="
15899
15900 test_133c() {
15901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15902         remote_ost_nodsh && skip "remote OST with nodsh"
15903         remote_mds_nodsh && skip "remote MDS with nodsh"
15904
15905         local testdir=$DIR/$tdir/stats_testdir
15906
15907         test_mkdir -p $testdir
15908
15909         # verify obdfilter stats.
15910         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15911         sync
15912         cancel_lru_locks osc
15913         wait_delete_completed
15914
15915         # clear stats.
15916         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15917         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15918
15919         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15920                 error "dd failed"
15921         sync
15922         cancel_lru_locks osc
15923         check_stats ost1 "write" 1
15924
15925         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15926         check_stats ost1 "read" 1
15927
15928         > $testdir/$tfile || error "truncate failed"
15929         check_stats ost1 "punch" 1
15930
15931         rm -f $testdir/$tfile || error "file remove failed"
15932         wait_delete_completed
15933         check_stats ost1 "destroy" 1
15934
15935         rm -rf $DIR/$tdir
15936 }
15937 run_test 133c "Verifying OST stats ========================================"
15938
15939 order_2() {
15940         local value=$1
15941         local orig=$value
15942         local order=1
15943
15944         while [ $value -ge 2 ]; do
15945                 order=$((order*2))
15946                 value=$((value/2))
15947         done
15948
15949         if [ $orig -gt $order ]; then
15950                 order=$((order*2))
15951         fi
15952         echo $order
15953 }
15954
15955 size_in_KMGT() {
15956     local value=$1
15957     local size=('K' 'M' 'G' 'T');
15958     local i=0
15959     local size_string=$value
15960
15961     while [ $value -ge 1024 ]; do
15962         if [ $i -gt 3 ]; then
15963             #T is the biggest unit we get here, if that is bigger,
15964             #just return XXXT
15965             size_string=${value}T
15966             break
15967         fi
15968         value=$((value >> 10))
15969         if [ $value -lt 1024 ]; then
15970             size_string=${value}${size[$i]}
15971             break
15972         fi
15973         i=$((i + 1))
15974     done
15975
15976     echo $size_string
15977 }
15978
15979 get_rename_size() {
15980         local size=$1
15981         local context=${2:-.}
15982         local sample=$(do_facet $SINGLEMDS $LCTL \
15983                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15984                 grep -A1 $context |
15985                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15986         echo $sample
15987 }
15988
15989 test_133d() {
15990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15991         remote_ost_nodsh && skip "remote OST with nodsh"
15992         remote_mds_nodsh && skip "remote MDS with nodsh"
15993         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15994                 skip_env "MDS doesn't support rename stats"
15995
15996         local testdir1=$DIR/${tdir}/stats_testdir1
15997         local testdir2=$DIR/${tdir}/stats_testdir2
15998         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15999
16000         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16001
16002         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
16003         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
16004
16005         createmany -o $testdir1/test 512 || error "createmany failed"
16006
16007         # check samedir rename size
16008         mv ${testdir1}/test0 ${testdir1}/test_0
16009
16010         local testdir1_size=$(ls -l $DIR/${tdir} |
16011                 awk '/stats_testdir1/ {print $5}')
16012         local testdir2_size=$(ls -l $DIR/${tdir} |
16013                 awk '/stats_testdir2/ {print $5}')
16014
16015         testdir1_size=$(order_2 $testdir1_size)
16016         testdir2_size=$(order_2 $testdir2_size)
16017
16018         testdir1_size=$(size_in_KMGT $testdir1_size)
16019         testdir2_size=$(size_in_KMGT $testdir2_size)
16020
16021         echo "source rename dir size: ${testdir1_size}"
16022         echo "target rename dir size: ${testdir2_size}"
16023
16024         local cmd="do_facet $SINGLEMDS $LCTL "
16025         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
16026
16027         eval $cmd || error "$cmd failed"
16028         local samedir=$($cmd | grep 'same_dir')
16029         local same_sample=$(get_rename_size $testdir1_size)
16030         [ -z "$samedir" ] && error "samedir_rename_size count error"
16031         [[ $same_sample -eq 1 ]] ||
16032                 error "samedir_rename_size error $same_sample"
16033         echo "Check same dir rename stats success"
16034
16035         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
16036
16037         # check crossdir rename size
16038         mv ${testdir1}/test_0 ${testdir2}/test_0
16039
16040         testdir1_size=$(ls -l $DIR/${tdir} |
16041                 awk '/stats_testdir1/ {print $5}')
16042         testdir2_size=$(ls -l $DIR/${tdir} |
16043                 awk '/stats_testdir2/ {print $5}')
16044
16045         testdir1_size=$(order_2 $testdir1_size)
16046         testdir2_size=$(order_2 $testdir2_size)
16047
16048         testdir1_size=$(size_in_KMGT $testdir1_size)
16049         testdir2_size=$(size_in_KMGT $testdir2_size)
16050
16051         echo "source rename dir size: ${testdir1_size}"
16052         echo "target rename dir size: ${testdir2_size}"
16053
16054         eval $cmd || error "$cmd failed"
16055         local crossdir=$($cmd | grep 'crossdir')
16056         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
16057         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
16058         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
16059         [[ $src_sample -eq 1 ]] ||
16060                 error "crossdir_rename_size error $src_sample"
16061         [[ $tgt_sample -eq 1 ]] ||
16062                 error "crossdir_rename_size error $tgt_sample"
16063         echo "Check cross dir rename stats success"
16064         rm -rf $DIR/${tdir}
16065 }
16066 run_test 133d "Verifying rename_stats ========================================"
16067
16068 test_133e() {
16069         remote_mds_nodsh && skip "remote MDS with nodsh"
16070         remote_ost_nodsh && skip "remote OST with nodsh"
16071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16072
16073         local testdir=$DIR/${tdir}/stats_testdir
16074         local ctr f0 f1 bs=32768 count=42 sum
16075
16076         mkdir -p ${testdir} || error "mkdir failed"
16077
16078         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16079
16080         for ctr in {write,read}_bytes; do
16081                 sync
16082                 cancel_lru_locks osc
16083
16084                 do_facet ost1 $LCTL set_param -n \
16085                         "obdfilter.*.exports.clear=clear"
16086
16087                 if [ $ctr = write_bytes ]; then
16088                         f0=/dev/zero
16089                         f1=${testdir}/${tfile}
16090                 else
16091                         f0=${testdir}/${tfile}
16092                         f1=/dev/null
16093                 fi
16094
16095                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16096                         error "dd failed"
16097                 sync
16098                 cancel_lru_locks osc
16099
16100                 sum=$(do_facet ost1 $LCTL get_param \
16101                         "obdfilter.*.exports.*.stats" |
16102                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16103                                 $1 == ctr { sum += $7 }
16104                                 END { printf("%0.0f", sum) }')
16105
16106                 if ((sum != bs * count)); then
16107                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16108                 fi
16109         done
16110
16111         rm -rf $DIR/${tdir}
16112 }
16113 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16114
16115 test_133f() {
16116         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16117                 skip "too old lustre for get_param -R ($facet_ver)"
16118
16119         # verifying readability.
16120         $LCTL get_param -R '*' &> /dev/null
16121
16122         # Verifing writability with badarea_io.
16123         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16124         local skipped_params='force_lbug|changelog_mask|daemon_file'
16125         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16126                 egrep -v "$skipped_params" |
16127                 xargs -n 1 find $proc_dirs -name |
16128                 xargs -n 1 badarea_io ||
16129                 error "client badarea_io failed"
16130
16131         # remount the FS in case writes/reads /proc break the FS
16132         cleanup || error "failed to unmount"
16133         setup || error "failed to setup"
16134 }
16135 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16136
16137 test_133g() {
16138         remote_mds_nodsh && skip "remote MDS with nodsh"
16139         remote_ost_nodsh && skip "remote OST with nodsh"
16140
16141         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16142         local proc_dirs_str=$(eval echo $proc_dirs)
16143         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16144         local facet
16145         for facet in mds1 ost1; do
16146                 local facet_ver=$(lustre_version_code $facet)
16147                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16148                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16149                 else
16150                         log "$facet: too old lustre for get_param -R"
16151                 fi
16152                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16153                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16154                                 tr -d = | egrep -v $skipped_params |
16155                                 xargs -n 1 find $proc_dirs_str -name |
16156                                 xargs -n 1 badarea_io" ||
16157                                         error "$facet badarea_io failed"
16158                 else
16159                         skip_noexit "$facet: too old lustre for get_param -R"
16160                 fi
16161         done
16162
16163         # remount the FS in case writes/reads /proc break the FS
16164         cleanup || error "failed to unmount"
16165         setup || error "failed to setup"
16166 }
16167 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16168
16169 test_133h() {
16170         remote_mds_nodsh && skip "remote MDS with nodsh"
16171         remote_ost_nodsh && skip "remote OST with nodsh"
16172         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16173                 skip "Need MDS version at least 2.9.54"
16174
16175         local facet
16176         for facet in client mds1 ost1; do
16177                 # Get the list of files that are missing the terminating newline
16178                 local plist=$(do_facet $facet
16179                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16180                 local ent
16181                 for ent in $plist; do
16182                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16183                                 awk -v FS='\v' -v RS='\v\v' \
16184                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16185                                         print FILENAME}'" 2>/dev/null)
16186                         [ -z $missing ] || {
16187                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16188                                 error "file does not end with newline: $facet-$ent"
16189                         }
16190                 done
16191         done
16192 }
16193 run_test 133h "Proc files should end with newlines"
16194
16195 test_134a() {
16196         remote_mds_nodsh && skip "remote MDS with nodsh"
16197         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16198                 skip "Need MDS version at least 2.7.54"
16199
16200         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16201         cancel_lru_locks mdc
16202
16203         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16204         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16205         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16206
16207         local nr=1000
16208         createmany -o $DIR/$tdir/f $nr ||
16209                 error "failed to create $nr files in $DIR/$tdir"
16210         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16211
16212         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16213         do_facet mds1 $LCTL set_param fail_loc=0x327
16214         do_facet mds1 $LCTL set_param fail_val=500
16215         touch $DIR/$tdir/m
16216
16217         echo "sleep 10 seconds ..."
16218         sleep 10
16219         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16220
16221         do_facet mds1 $LCTL set_param fail_loc=0
16222         do_facet mds1 $LCTL set_param fail_val=0
16223         [ $lck_cnt -lt $unused ] ||
16224                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16225
16226         rm $DIR/$tdir/m
16227         unlinkmany $DIR/$tdir/f $nr
16228 }
16229 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16230
16231 test_134b() {
16232         remote_mds_nodsh && skip "remote MDS with nodsh"
16233         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16234                 skip "Need MDS version at least 2.7.54"
16235
16236         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16237         cancel_lru_locks mdc
16238
16239         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16240                         ldlm.lock_reclaim_threshold_mb)
16241         # disable reclaim temporarily
16242         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16243
16244         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16245         do_facet mds1 $LCTL set_param fail_loc=0x328
16246         do_facet mds1 $LCTL set_param fail_val=500
16247
16248         $LCTL set_param debug=+trace
16249
16250         local nr=600
16251         createmany -o $DIR/$tdir/f $nr &
16252         local create_pid=$!
16253
16254         echo "Sleep $TIMEOUT seconds ..."
16255         sleep $TIMEOUT
16256         if ! ps -p $create_pid  > /dev/null 2>&1; then
16257                 do_facet mds1 $LCTL set_param fail_loc=0
16258                 do_facet mds1 $LCTL set_param fail_val=0
16259                 do_facet mds1 $LCTL set_param \
16260                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16261                 error "createmany finished incorrectly!"
16262         fi
16263         do_facet mds1 $LCTL set_param fail_loc=0
16264         do_facet mds1 $LCTL set_param fail_val=0
16265         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16266         wait $create_pid || return 1
16267
16268         unlinkmany $DIR/$tdir/f $nr
16269 }
16270 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16271
16272 test_135() {
16273         remote_mds_nodsh && skip "remote MDS with nodsh"
16274         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16275                 skip "Need MDS version at least 2.13.50"
16276         local fname
16277
16278         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16279
16280 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16281         #set only one record at plain llog
16282         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16283
16284         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16285
16286         #fill already existed plain llog each 64767
16287         #wrapping whole catalog
16288         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16289
16290         createmany -o $DIR/$tdir/$tfile_ 64700
16291         for (( i = 0; i < 64700; i = i + 2 ))
16292         do
16293                 rm $DIR/$tdir/$tfile_$i &
16294                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16295                 local pid=$!
16296                 wait $pid
16297         done
16298
16299         #waiting osp synchronization
16300         wait_delete_completed
16301 }
16302 run_test 135 "Race catalog processing"
16303
16304 test_136() {
16305         remote_mds_nodsh && skip "remote MDS with nodsh"
16306         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16307                 skip "Need MDS version at least 2.13.50"
16308         local fname
16309
16310         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16311         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16312         #set only one record at plain llog
16313 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16314         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16315
16316         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16317
16318         #fill already existed 2 plain llogs each 64767
16319         #wrapping whole catalog
16320         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16321         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16322         wait_delete_completed
16323
16324         createmany -o $DIR/$tdir/$tfile_ 10
16325         sleep 25
16326
16327         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16328         for (( i = 0; i < 10; i = i + 3 ))
16329         do
16330                 rm $DIR/$tdir/$tfile_$i &
16331                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16332                 local pid=$!
16333                 wait $pid
16334                 sleep 7
16335                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16336         done
16337
16338         #waiting osp synchronization
16339         wait_delete_completed
16340 }
16341 run_test 136 "Race catalog processing 2"
16342
16343 test_140() { #bug-17379
16344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16345
16346         test_mkdir $DIR/$tdir
16347         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16348         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16349
16350         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16351         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16352         local i=0
16353         while i=$((i + 1)); do
16354                 test_mkdir $i
16355                 cd $i || error "Changing to $i"
16356                 ln -s ../stat stat || error "Creating stat symlink"
16357                 # Read the symlink until ELOOP present,
16358                 # not LBUGing the system is considered success,
16359                 # we didn't overrun the stack.
16360                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16361                 if [ $ret -ne 0 ]; then
16362                         if [ $ret -eq 40 ]; then
16363                                 break  # -ELOOP
16364                         else
16365                                 error "Open stat symlink"
16366                                         return
16367                         fi
16368                 fi
16369         done
16370         i=$((i - 1))
16371         echo "The symlink depth = $i"
16372         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16373                 error "Invalid symlink depth"
16374
16375         # Test recursive symlink
16376         ln -s symlink_self symlink_self
16377         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16378         echo "open symlink_self returns $ret"
16379         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16380 }
16381 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16382
16383 test_150a() {
16384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16385
16386         local TF="$TMP/$tfile"
16387
16388         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16389         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16390         cp $TF $DIR/$tfile
16391         cancel_lru_locks $OSC
16392         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16393         remount_client $MOUNT
16394         df -P $MOUNT
16395         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16396
16397         $TRUNCATE $TF 6000
16398         $TRUNCATE $DIR/$tfile 6000
16399         cancel_lru_locks $OSC
16400         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16401
16402         echo "12345" >>$TF
16403         echo "12345" >>$DIR/$tfile
16404         cancel_lru_locks $OSC
16405         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16406
16407         echo "12345" >>$TF
16408         echo "12345" >>$DIR/$tfile
16409         cancel_lru_locks $OSC
16410         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16411 }
16412 run_test 150a "truncate/append tests"
16413
16414 test_150b() {
16415         check_set_fallocate_or_skip
16416         local out
16417
16418         touch $DIR/$tfile
16419         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16420         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16421                 skip_eopnotsupp "$out|check_fallocate failed"
16422 }
16423 run_test 150b "Verify fallocate (prealloc) functionality"
16424
16425 test_150bb() {
16426         check_set_fallocate_or_skip
16427
16428         touch $DIR/$tfile
16429         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16430         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16431         > $DIR/$tfile
16432         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16433         # precomputed md5sum for 20MB of zeroes
16434         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16435         local sum=($(md5sum $DIR/$tfile))
16436
16437         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16438
16439         check_set_fallocate 1
16440
16441         > $DIR/$tfile
16442         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16443         sum=($(md5sum $DIR/$tfile))
16444
16445         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16446 }
16447 run_test 150bb "Verify fallocate modes both zero space"
16448
16449 test_150c() {
16450         check_set_fallocate_or_skip
16451         local striping="-c2"
16452
16453         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16454         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16455         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16456         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16457         local want=$((OSTCOUNT * 1048576))
16458
16459         # Must allocate all requested space, not more than 5% extra
16460         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16461                 error "bytes $bytes is not $want"
16462
16463         rm -f $DIR/$tfile
16464
16465         echo "verify fallocate on PFL file"
16466
16467         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16468
16469         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16470                 error "Create $DIR/$tfile failed"
16471         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16472         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16473         want=$((512 * 1048576))
16474
16475         # Must allocate all requested space, not more than 5% extra
16476         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16477                 error "bytes $bytes is not $want"
16478 }
16479 run_test 150c "Verify fallocate Size and Blocks"
16480
16481 test_150d() {
16482         check_set_fallocate_or_skip
16483         local striping="-c2"
16484
16485         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16486
16487         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16488         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16489                 error "setstripe failed"
16490         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16491         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16492         local want=$((OSTCOUNT * 1048576))
16493
16494         # Must allocate all requested space, not more than 5% extra
16495         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16496                 error "bytes $bytes is not $want"
16497 }
16498 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16499
16500 test_150e() {
16501         check_set_fallocate_or_skip
16502
16503         echo "df before:"
16504         $LFS df
16505         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16506         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16507                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16508
16509         # Find OST with Minimum Size
16510         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16511                        sort -un | head -1)
16512
16513         # Get 100MB per OST of the available space to reduce run time
16514         # else 60% of the available space if we are running SLOW tests
16515         if [ $SLOW == "no" ]; then
16516                 local space=$((1024 * 100 * OSTCOUNT))
16517         else
16518                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16519         fi
16520
16521         fallocate -l${space}k $DIR/$tfile ||
16522                 error "fallocate ${space}k $DIR/$tfile failed"
16523         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16524
16525         # get size immediately after fallocate. This should be correctly
16526         # updated
16527         local size=$(stat -c '%s' $DIR/$tfile)
16528         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16529
16530         # Sleep for a while for statfs to get updated. And not pull from cache.
16531         sleep 2
16532
16533         echo "df after fallocate:"
16534         $LFS df
16535
16536         (( size / 1024 == space )) || error "size $size != requested $space"
16537         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16538                 error "used $used < space $space"
16539
16540         rm $DIR/$tfile || error "rm failed"
16541         sync
16542         wait_delete_completed
16543
16544         echo "df after unlink:"
16545         $LFS df
16546 }
16547 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16548
16549 test_150f() {
16550         local size
16551         local blocks
16552         local want_size_before=20480 # in bytes
16553         local want_blocks_before=40 # 512 sized blocks
16554         local want_blocks_after=24  # 512 sized blocks
16555         local length=$(((want_blocks_before - want_blocks_after) * 512))
16556
16557         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16558                 skip "need at least 2.14.0 for fallocate punch"
16559
16560         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16561                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16562         fi
16563
16564         check_set_fallocate_or_skip
16565         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16566
16567         [[ "x$DOM" == "xyes" ]] &&
16568                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16569
16570         echo "Verify fallocate punch: Range within the file range"
16571         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16572                 error "dd failed for bs 4096 and count 5"
16573
16574         # Call fallocate with punch range which is within the file range
16575         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16576                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16577         # client must see changes immediately after fallocate
16578         size=$(stat -c '%s' $DIR/$tfile)
16579         blocks=$(stat -c '%b' $DIR/$tfile)
16580
16581         # Verify punch worked.
16582         (( blocks == want_blocks_after )) ||
16583                 error "punch failed: blocks $blocks != $want_blocks_after"
16584
16585         (( size == want_size_before )) ||
16586                 error "punch failed: size $size != $want_size_before"
16587
16588         # Verify there is hole in file
16589         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16590         # precomputed md5sum
16591         local expect="4a9a834a2db02452929c0a348273b4aa"
16592
16593         cksum=($(md5sum $DIR/$tfile))
16594         [[ "${cksum[0]}" == "$expect" ]] ||
16595                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16596
16597         # Start second sub-case for fallocate punch.
16598         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16599         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16600                 error "dd failed for bs 4096 and count 5"
16601
16602         # Punch range less than block size will have no change in block count
16603         want_blocks_after=40  # 512 sized blocks
16604
16605         # Punch overlaps two blocks and less than blocksize
16606         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16607                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16608         size=$(stat -c '%s' $DIR/$tfile)
16609         blocks=$(stat -c '%b' $DIR/$tfile)
16610
16611         # Verify punch worked.
16612         (( blocks == want_blocks_after )) ||
16613                 error "punch failed: blocks $blocks != $want_blocks_after"
16614
16615         (( size == want_size_before )) ||
16616                 error "punch failed: size $size != $want_size_before"
16617
16618         # Verify if range is really zero'ed out. We expect Zeros.
16619         # precomputed md5sum
16620         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16621         cksum=($(md5sum $DIR/$tfile))
16622         [[ "${cksum[0]}" == "$expect" ]] ||
16623                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16624 }
16625 run_test 150f "Verify fallocate punch functionality"
16626
16627 test_150g() {
16628         local space
16629         local size
16630         local blocks
16631         local blocks_after
16632         local size_after
16633         local BS=4096 # Block size in bytes
16634
16635         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16636                 skip "need at least 2.14.0 for fallocate punch"
16637
16638         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16639                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16640         fi
16641
16642         check_set_fallocate_or_skip
16643         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16644
16645         if [[ "x$DOM" == "xyes" ]]; then
16646                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16647                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16648         else
16649                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16650                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16651         fi
16652
16653         # Get 100MB per OST of the available space to reduce run time
16654         # else 60% of the available space if we are running SLOW tests
16655         if [ $SLOW == "no" ]; then
16656                 space=$((1024 * 100 * OSTCOUNT))
16657         else
16658                 # Find OST with Minimum Size
16659                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16660                         sort -un | head -1)
16661                 echo "min size OST: $space"
16662                 space=$(((space * 60)/100 * OSTCOUNT))
16663         fi
16664         # space in 1k units, round to 4k blocks
16665         local blkcount=$((space * 1024 / $BS))
16666
16667         echo "Verify fallocate punch: Very large Range"
16668         fallocate -l${space}k $DIR/$tfile ||
16669                 error "fallocate ${space}k $DIR/$tfile failed"
16670         # write 1M at the end, start and in the middle
16671         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16672                 error "dd failed: bs $BS count 256"
16673         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16674                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16675         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16676                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16677
16678         # Gather stats.
16679         size=$(stat -c '%s' $DIR/$tfile)
16680
16681         # gather punch length.
16682         local punch_size=$((size - (BS * 2)))
16683
16684         echo "punch_size = $punch_size"
16685         echo "size - punch_size: $((size - punch_size))"
16686         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16687
16688         # Call fallocate to punch all except 2 blocks. We leave the
16689         # first and the last block
16690         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16691         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16692                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16693
16694         size_after=$(stat -c '%s' $DIR/$tfile)
16695         blocks_after=$(stat -c '%b' $DIR/$tfile)
16696
16697         # Verify punch worked.
16698         # Size should be kept
16699         (( size == size_after )) ||
16700                 error "punch failed: size $size != $size_after"
16701
16702         # two 4k data blocks to remain plus possible 1 extra extent block
16703         (( blocks_after <= ((BS / 512) * 3) )) ||
16704                 error "too many blocks remains: $blocks_after"
16705
16706         # Verify that file has hole between the first and the last blocks
16707         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16708         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16709
16710         echo "Hole at [$hole_start, $hole_end)"
16711         (( hole_start == BS )) ||
16712                 error "no hole at offset $BS after punch"
16713
16714         (( hole_end == BS + punch_size )) ||
16715                 error "data at offset $hole_end < $((BS + punch_size))"
16716 }
16717 run_test 150g "Verify fallocate punch on large range"
16718
16719 test_150h() {
16720         local file=$DIR/$tfile
16721         local size
16722
16723         check_set_fallocate_or_skip
16724         statx_supported || skip_env "Test must be statx() syscall supported"
16725
16726         # fallocate() does not update the size information on the MDT
16727         fallocate -l 16K $file || error "failed to fallocate $file"
16728         cancel_lru_locks $OSC
16729         # STATX with cached-always mode will not send glimpse RPCs to OST,
16730         # it uses the caching attrs on the client side as much as possible.
16731         size=$($STATX --cached=always -c %s $file)
16732         [ $size == 16384 ] ||
16733                 error "size after fallocate() is $size, expected 16384"
16734 }
16735 run_test 150h "Verify extend fallocate updates the file size"
16736
16737 #LU-2902 roc_hit was not able to read all values from lproc
16738 function roc_hit_init() {
16739         local list=$(comma_list $(osts_nodes))
16740         local dir=$DIR/$tdir-check
16741         local file=$dir/$tfile
16742         local BEFORE
16743         local AFTER
16744         local idx
16745
16746         test_mkdir $dir
16747         #use setstripe to do a write to every ost
16748         for i in $(seq 0 $((OSTCOUNT-1))); do
16749                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16750                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16751                 idx=$(printf %04x $i)
16752                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16753                         awk '$1 == "cache_access" {sum += $7}
16754                                 END { printf("%0.0f", sum) }')
16755
16756                 cancel_lru_locks osc
16757                 cat $file >/dev/null
16758
16759                 AFTER=$(get_osd_param $list *OST*$idx stats |
16760                         awk '$1 == "cache_access" {sum += $7}
16761                                 END { printf("%0.0f", sum) }')
16762
16763                 echo BEFORE:$BEFORE AFTER:$AFTER
16764                 if ! let "AFTER - BEFORE == 4"; then
16765                         rm -rf $dir
16766                         error "roc_hit is not safe to use"
16767                 fi
16768                 rm $file
16769         done
16770
16771         rm -rf $dir
16772 }
16773
16774 function roc_hit() {
16775         local list=$(comma_list $(osts_nodes))
16776         echo $(get_osd_param $list '' stats |
16777                 awk '$1 == "cache_hit" {sum += $7}
16778                         END { printf("%0.0f", sum) }')
16779 }
16780
16781 function set_cache() {
16782         local on=1
16783
16784         if [ "$2" == "off" ]; then
16785                 on=0;
16786         fi
16787         local list=$(comma_list $(osts_nodes))
16788         set_osd_param $list '' $1_cache_enable $on
16789
16790         cancel_lru_locks osc
16791 }
16792
16793 test_151() {
16794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16795         remote_ost_nodsh && skip "remote OST with nodsh"
16796         (( CLIENT_VERSION == OST1_VERSION )) ||
16797                 skip "LU-13081: no interop testing for OSS cache"
16798
16799         local CPAGES=3
16800         local list=$(comma_list $(osts_nodes))
16801
16802         # check whether obdfilter is cache capable at all
16803         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16804                 skip "not cache-capable obdfilter"
16805         fi
16806
16807         # check cache is enabled on all obdfilters
16808         if get_osd_param $list '' read_cache_enable | grep 0; then
16809                 skip "oss cache is disabled"
16810         fi
16811
16812         set_osd_param $list '' writethrough_cache_enable 1
16813
16814         # check write cache is enabled on all obdfilters
16815         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16816                 skip "oss write cache is NOT enabled"
16817         fi
16818
16819         roc_hit_init
16820
16821         #define OBD_FAIL_OBD_NO_LRU  0x609
16822         do_nodes $list $LCTL set_param fail_loc=0x609
16823
16824         # pages should be in the case right after write
16825         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16826                 error "dd failed"
16827
16828         local BEFORE=$(roc_hit)
16829         cancel_lru_locks osc
16830         cat $DIR/$tfile >/dev/null
16831         local AFTER=$(roc_hit)
16832
16833         do_nodes $list $LCTL set_param fail_loc=0
16834
16835         if ! let "AFTER - BEFORE == CPAGES"; then
16836                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16837         fi
16838
16839         cancel_lru_locks osc
16840         # invalidates OST cache
16841         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16842         set_osd_param $list '' read_cache_enable 0
16843         cat $DIR/$tfile >/dev/null
16844
16845         # now data shouldn't be found in the cache
16846         BEFORE=$(roc_hit)
16847         cancel_lru_locks osc
16848         cat $DIR/$tfile >/dev/null
16849         AFTER=$(roc_hit)
16850         if let "AFTER - BEFORE != 0"; then
16851                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16852         fi
16853
16854         set_osd_param $list '' read_cache_enable 1
16855         rm -f $DIR/$tfile
16856 }
16857 run_test 151 "test cache on oss and controls ==============================="
16858
16859 test_152() {
16860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16861
16862         local TF="$TMP/$tfile"
16863
16864         # simulate ENOMEM during write
16865 #define OBD_FAIL_OST_NOMEM      0x226
16866         lctl set_param fail_loc=0x80000226
16867         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16868         cp $TF $DIR/$tfile
16869         sync || error "sync failed"
16870         lctl set_param fail_loc=0
16871
16872         # discard client's cache
16873         cancel_lru_locks osc
16874
16875         # simulate ENOMEM during read
16876         lctl set_param fail_loc=0x80000226
16877         cmp $TF $DIR/$tfile || error "cmp failed"
16878         lctl set_param fail_loc=0
16879
16880         rm -f $TF
16881 }
16882 run_test 152 "test read/write with enomem ============================"
16883
16884 test_153() {
16885         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16886 }
16887 run_test 153 "test if fdatasync does not crash ======================="
16888
16889 dot_lustre_fid_permission_check() {
16890         local fid=$1
16891         local ffid=$MOUNT/.lustre/fid/$fid
16892         local test_dir=$2
16893
16894         echo "stat fid $fid"
16895         stat $ffid || error "stat $ffid failed."
16896         echo "touch fid $fid"
16897         touch $ffid || error "touch $ffid failed."
16898         echo "write to fid $fid"
16899         cat /etc/hosts > $ffid || error "write $ffid failed."
16900         echo "read fid $fid"
16901         diff /etc/hosts $ffid || error "read $ffid failed."
16902         echo "append write to fid $fid"
16903         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16904         echo "rename fid $fid"
16905         mv $ffid $test_dir/$tfile.1 &&
16906                 error "rename $ffid to $tfile.1 should fail."
16907         touch $test_dir/$tfile.1
16908         mv $test_dir/$tfile.1 $ffid &&
16909                 error "rename $tfile.1 to $ffid should fail."
16910         rm -f $test_dir/$tfile.1
16911         echo "truncate fid $fid"
16912         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16913         echo "link fid $fid"
16914         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16915         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16916                 id $USER0 || skip_env "missing user $USER0"
16917                 echo "setfacl fid $fid"
16918                 setfacl -R -m u:$USER0:rwx $ffid ||
16919                         error "setfacl $ffid failed"
16920                 echo "getfacl fid $fid"
16921                 getfacl $ffid || error "getfacl $ffid failed."
16922         fi
16923         echo "unlink fid $fid"
16924         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16925         echo "mknod fid $fid"
16926         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16927
16928         fid=[0xf00000400:0x1:0x0]
16929         ffid=$MOUNT/.lustre/fid/$fid
16930
16931         echo "stat non-exist fid $fid"
16932         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16933         echo "write to non-exist fid $fid"
16934         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16935         echo "link new fid $fid"
16936         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16937
16938         mkdir -p $test_dir/$tdir
16939         touch $test_dir/$tdir/$tfile
16940         fid=$($LFS path2fid $test_dir/$tdir)
16941         rc=$?
16942         [ $rc -ne 0 ] &&
16943                 error "error: could not get fid for $test_dir/$dir/$tfile."
16944
16945         ffid=$MOUNT/.lustre/fid/$fid
16946
16947         echo "ls $fid"
16948         ls $ffid || error "ls $ffid failed."
16949         echo "touch $fid/$tfile.1"
16950         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16951
16952         echo "touch $MOUNT/.lustre/fid/$tfile"
16953         touch $MOUNT/.lustre/fid/$tfile && \
16954                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16955
16956         echo "setxattr to $MOUNT/.lustre/fid"
16957         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16958
16959         echo "listxattr for $MOUNT/.lustre/fid"
16960         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16961
16962         echo "delxattr from $MOUNT/.lustre/fid"
16963         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16964
16965         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16966         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16967                 error "touch invalid fid should fail."
16968
16969         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16970         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16971                 error "touch non-normal fid should fail."
16972
16973         echo "rename $tdir to $MOUNT/.lustre/fid"
16974         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16975                 error "rename to $MOUNT/.lustre/fid should fail."
16976
16977         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16978         then            # LU-3547
16979                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16980                 local new_obf_mode=777
16981
16982                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16983                 chmod $new_obf_mode $DIR/.lustre/fid ||
16984                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16985
16986                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16987                 [ $obf_mode -eq $new_obf_mode ] ||
16988                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16989
16990                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16991                 chmod $old_obf_mode $DIR/.lustre/fid ||
16992                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16993         fi
16994
16995         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16996         fid=$($LFS path2fid $test_dir/$tfile-2)
16997
16998         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16999         then # LU-5424
17000                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
17001                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
17002                         error "create lov data thru .lustre failed"
17003         fi
17004         echo "cp /etc/passwd $test_dir/$tfile-2"
17005         cp /etc/passwd $test_dir/$tfile-2 ||
17006                 error "copy to $test_dir/$tfile-2 failed."
17007         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
17008         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
17009                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
17010
17011         rm -rf $test_dir/tfile.lnk
17012         rm -rf $test_dir/$tfile-2
17013 }
17014
17015 test_154A() {
17016         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17017                 skip "Need MDS version at least 2.4.1"
17018
17019         local tf=$DIR/$tfile
17020         touch $tf
17021
17022         local fid=$($LFS path2fid $tf)
17023         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
17024
17025         # check that we get the same pathname back
17026         local rootpath
17027         local found
17028         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
17029                 echo "$rootpath $fid"
17030                 found=$($LFS fid2path $rootpath "$fid")
17031                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
17032                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
17033         done
17034
17035         # check wrong root path format
17036         rootpath=$MOUNT"_wrong"
17037         found=$($LFS fid2path $rootpath "$fid")
17038         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
17039 }
17040 run_test 154A "lfs path2fid and fid2path basic checks"
17041
17042 test_154B() {
17043         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17044                 skip "Need MDS version at least 2.4.1"
17045
17046         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
17047         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
17048         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
17049         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
17050
17051         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
17052         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
17053
17054         # check that we get the same pathname
17055         echo "PFID: $PFID, name: $name"
17056         local FOUND=$($LFS fid2path $MOUNT "$PFID")
17057         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
17058         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
17059                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
17060
17061         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
17062 }
17063 run_test 154B "verify the ll_decode_linkea tool"
17064
17065 test_154a() {
17066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17067         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17068         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
17069                 skip "Need MDS version at least 2.2.51"
17070         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
17071
17072         cp /etc/hosts $DIR/$tfile
17073
17074         fid=$($LFS path2fid $DIR/$tfile)
17075         rc=$?
17076         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17077
17078         dot_lustre_fid_permission_check "$fid" $DIR ||
17079                 error "dot lustre permission check $fid failed"
17080
17081         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17082
17083         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17084
17085         touch $MOUNT/.lustre/file &&
17086                 error "creation is not allowed under .lustre"
17087
17088         mkdir $MOUNT/.lustre/dir &&
17089                 error "mkdir is not allowed under .lustre"
17090
17091         rm -rf $DIR/$tfile
17092 }
17093 run_test 154a "Open-by-FID"
17094
17095 test_154b() {
17096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17097         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17098         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17099         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17100                 skip "Need MDS version at least 2.2.51"
17101
17102         local remote_dir=$DIR/$tdir/remote_dir
17103         local MDTIDX=1
17104         local rc=0
17105
17106         mkdir -p $DIR/$tdir
17107         $LFS mkdir -i $MDTIDX $remote_dir ||
17108                 error "create remote directory failed"
17109
17110         cp /etc/hosts $remote_dir/$tfile
17111
17112         fid=$($LFS path2fid $remote_dir/$tfile)
17113         rc=$?
17114         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17115
17116         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17117                 error "dot lustre permission check $fid failed"
17118         rm -rf $DIR/$tdir
17119 }
17120 run_test 154b "Open-by-FID for remote directory"
17121
17122 test_154c() {
17123         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17124                 skip "Need MDS version at least 2.4.1"
17125
17126         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17127         local FID1=$($LFS path2fid $DIR/$tfile.1)
17128         local FID2=$($LFS path2fid $DIR/$tfile.2)
17129         local FID3=$($LFS path2fid $DIR/$tfile.3)
17130
17131         local N=1
17132         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17133                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17134                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17135                 local want=FID$N
17136                 [ "$FID" = "${!want}" ] ||
17137                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17138                 N=$((N + 1))
17139         done
17140
17141         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17142         do
17143                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17144                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17145                 N=$((N + 1))
17146         done
17147 }
17148 run_test 154c "lfs path2fid and fid2path multiple arguments"
17149
17150 test_154d() {
17151         remote_mds_nodsh && skip "remote MDS with nodsh"
17152         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17153                 skip "Need MDS version at least 2.5.53"
17154
17155         if remote_mds; then
17156                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17157         else
17158                 nid="0@lo"
17159         fi
17160         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17161         local fd
17162         local cmd
17163
17164         rm -f $DIR/$tfile
17165         touch $DIR/$tfile
17166
17167         local fid=$($LFS path2fid $DIR/$tfile)
17168         # Open the file
17169         fd=$(free_fd)
17170         cmd="exec $fd<$DIR/$tfile"
17171         eval $cmd
17172         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17173         echo "$fid_list" | grep "$fid"
17174         rc=$?
17175
17176         cmd="exec $fd>/dev/null"
17177         eval $cmd
17178         if [ $rc -ne 0 ]; then
17179                 error "FID $fid not found in open files list $fid_list"
17180         fi
17181 }
17182 run_test 154d "Verify open file fid"
17183
17184 test_154e()
17185 {
17186         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17187                 skip "Need MDS version at least 2.6.50"
17188
17189         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17190                 error ".lustre returned by readdir"
17191         fi
17192 }
17193 run_test 154e ".lustre is not returned by readdir"
17194
17195 test_154f() {
17196         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17197
17198         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17199         mkdir_on_mdt0 $DIR/$tdir
17200         # test dirs inherit from its stripe
17201         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17202         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17203         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17204         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17205         touch $DIR/f
17206
17207         # get fid of parents
17208         local FID0=$($LFS path2fid $DIR/$tdir)
17209         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17210         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17211         local FID3=$($LFS path2fid $DIR)
17212
17213         # check that path2fid --parents returns expected <parent_fid>/name
17214         # 1) test for a directory (single parent)
17215         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17216         [ "$parent" == "$FID0/foo1" ] ||
17217                 error "expected parent: $FID0/foo1, got: $parent"
17218
17219         # 2) test for a file with nlink > 1 (multiple parents)
17220         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17221         echo "$parent" | grep -F "$FID1/$tfile" ||
17222                 error "$FID1/$tfile not returned in parent list"
17223         echo "$parent" | grep -F "$FID2/link" ||
17224                 error "$FID2/link not returned in parent list"
17225
17226         # 3) get parent by fid
17227         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17228         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17229         echo "$parent" | grep -F "$FID1/$tfile" ||
17230                 error "$FID1/$tfile not returned in parent list (by fid)"
17231         echo "$parent" | grep -F "$FID2/link" ||
17232                 error "$FID2/link not returned in parent list (by fid)"
17233
17234         # 4) test for entry in root directory
17235         parent=$($LFS path2fid --parents $DIR/f)
17236         echo "$parent" | grep -F "$FID3/f" ||
17237                 error "$FID3/f not returned in parent list"
17238
17239         # 5) test it on root directory
17240         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17241                 error "$MOUNT should not have parents"
17242
17243         # enable xattr caching and check that linkea is correctly updated
17244         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17245         save_lustre_params client "llite.*.xattr_cache" > $save
17246         lctl set_param llite.*.xattr_cache 1
17247
17248         # 6.1) linkea update on rename
17249         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17250
17251         # get parents by fid
17252         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17253         # foo1 should no longer be returned in parent list
17254         echo "$parent" | grep -F "$FID1" &&
17255                 error "$FID1 should no longer be in parent list"
17256         # the new path should appear
17257         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17258                 error "$FID2/$tfile.moved is not in parent list"
17259
17260         # 6.2) linkea update on unlink
17261         rm -f $DIR/$tdir/foo2/link
17262         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17263         # foo2/link should no longer be returned in parent list
17264         echo "$parent" | grep -F "$FID2/link" &&
17265                 error "$FID2/link should no longer be in parent list"
17266         true
17267
17268         rm -f $DIR/f
17269         restore_lustre_params < $save
17270         rm -f $save
17271 }
17272 run_test 154f "get parent fids by reading link ea"
17273
17274 test_154g()
17275 {
17276         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17277            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17278                 skip "Need MDS version at least 2.6.92"
17279
17280         mkdir_on_mdt0 $DIR/$tdir
17281         llapi_fid_test -d $DIR/$tdir
17282 }
17283 run_test 154g "various llapi FID tests"
17284
17285 test_154h()
17286 {
17287         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17288                 skip "Need client at least version 2.15.55.1"
17289
17290         # Create an empty file
17291         touch $DIR/$tfile
17292
17293         # Get FID (interactive mode) and save under $TMP/$tfile.log
17294         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17295                 path2fid $DIR/$tfile
17296         EOF
17297
17298         fid=$(cat $TMP/$tfile.log)
17299         # $fid should not be empty
17300         [[ ! -z $fid ]] || error "FID is empty"
17301         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17302 }
17303 run_test 154h "Verify interactive path2fid"
17304
17305 test_155_small_load() {
17306     local temp=$TMP/$tfile
17307     local file=$DIR/$tfile
17308
17309     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17310         error "dd of=$temp bs=6096 count=1 failed"
17311     cp $temp $file
17312     cancel_lru_locks $OSC
17313     cmp $temp $file || error "$temp $file differ"
17314
17315     $TRUNCATE $temp 6000
17316     $TRUNCATE $file 6000
17317     cmp $temp $file || error "$temp $file differ (truncate1)"
17318
17319     echo "12345" >>$temp
17320     echo "12345" >>$file
17321     cmp $temp $file || error "$temp $file differ (append1)"
17322
17323     echo "12345" >>$temp
17324     echo "12345" >>$file
17325     cmp $temp $file || error "$temp $file differ (append2)"
17326
17327     rm -f $temp $file
17328     true
17329 }
17330
17331 test_155_big_load() {
17332         remote_ost_nodsh && skip "remote OST with nodsh"
17333
17334         local temp=$TMP/$tfile
17335         local file=$DIR/$tfile
17336
17337         free_min_max
17338         local cache_size=$(do_facet ost$((MAXI+1)) \
17339                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17340
17341         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17342         # pre-set value
17343         if [ -z "$cache_size" ]; then
17344                 cache_size=256
17345         fi
17346         local large_file_size=$((cache_size * 2))
17347
17348         echo "OSS cache size: $cache_size KB"
17349         echo "Large file size: $large_file_size KB"
17350
17351         [ $MAXV -le $large_file_size ] &&
17352                 skip_env "max available OST size needs > $large_file_size KB"
17353
17354         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17355
17356         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17357                 error "dd of=$temp bs=$large_file_size count=1k failed"
17358         cp $temp $file
17359         ls -lh $temp $file
17360         cancel_lru_locks osc
17361         cmp $temp $file || error "$temp $file differ"
17362
17363         rm -f $temp $file
17364         true
17365 }
17366
17367 save_writethrough() {
17368         local facets=$(get_facets OST)
17369
17370         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17371 }
17372
17373 test_155a() {
17374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17375
17376         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17377
17378         save_writethrough $p
17379
17380         set_cache read on
17381         set_cache writethrough on
17382         test_155_small_load
17383         restore_lustre_params < $p
17384         rm -f $p
17385 }
17386 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17387
17388 test_155b() {
17389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17390
17391         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17392
17393         save_writethrough $p
17394
17395         set_cache read on
17396         set_cache writethrough off
17397         test_155_small_load
17398         restore_lustre_params < $p
17399         rm -f $p
17400 }
17401 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17402
17403 test_155c() {
17404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17405
17406         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17407
17408         save_writethrough $p
17409
17410         set_cache read off
17411         set_cache writethrough on
17412         test_155_small_load
17413         restore_lustre_params < $p
17414         rm -f $p
17415 }
17416 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17417
17418 test_155d() {
17419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17420
17421         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17422
17423         save_writethrough $p
17424
17425         set_cache read off
17426         set_cache writethrough off
17427         test_155_small_load
17428         restore_lustre_params < $p
17429         rm -f $p
17430 }
17431 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17432
17433 test_155e() {
17434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17435
17436         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17437
17438         save_writethrough $p
17439
17440         set_cache read on
17441         set_cache writethrough on
17442         test_155_big_load
17443         restore_lustre_params < $p
17444         rm -f $p
17445 }
17446 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17447
17448 test_155f() {
17449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17450
17451         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17452
17453         save_writethrough $p
17454
17455         set_cache read on
17456         set_cache writethrough off
17457         test_155_big_load
17458         restore_lustre_params < $p
17459         rm -f $p
17460 }
17461 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17462
17463 test_155g() {
17464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17465
17466         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17467
17468         save_writethrough $p
17469
17470         set_cache read off
17471         set_cache writethrough on
17472         test_155_big_load
17473         restore_lustre_params < $p
17474         rm -f $p
17475 }
17476 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17477
17478 test_155h() {
17479         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17480
17481         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17482
17483         save_writethrough $p
17484
17485         set_cache read off
17486         set_cache writethrough off
17487         test_155_big_load
17488         restore_lustre_params < $p
17489         rm -f $p
17490 }
17491 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17492
17493 test_156() {
17494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17495         remote_ost_nodsh && skip "remote OST with nodsh"
17496         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17497                 skip "stats not implemented on old servers"
17498         [ "$ost1_FSTYPE" = "zfs" ] &&
17499                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17500         (( CLIENT_VERSION == OST1_VERSION )) ||
17501                 skip "LU-13081: no interop testing for OSS cache"
17502
17503         local CPAGES=3
17504         local BEFORE
17505         local AFTER
17506         local file="$DIR/$tfile"
17507         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17508
17509         save_writethrough $p
17510         roc_hit_init
17511
17512         log "Turn on read and write cache"
17513         set_cache read on
17514         set_cache writethrough on
17515
17516         log "Write data and read it back."
17517         log "Read should be satisfied from the cache."
17518         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17519         BEFORE=$(roc_hit)
17520         cancel_lru_locks osc
17521         cat $file >/dev/null
17522         AFTER=$(roc_hit)
17523         if ! let "AFTER - BEFORE == CPAGES"; then
17524                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17525         else
17526                 log "cache hits: before: $BEFORE, after: $AFTER"
17527         fi
17528
17529         log "Read again; it should be satisfied from the cache."
17530         BEFORE=$AFTER
17531         cancel_lru_locks osc
17532         cat $file >/dev/null
17533         AFTER=$(roc_hit)
17534         if ! let "AFTER - BEFORE == CPAGES"; then
17535                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17536         else
17537                 log "cache hits:: before: $BEFORE, after: $AFTER"
17538         fi
17539
17540         log "Turn off the read cache and turn on the write cache"
17541         set_cache read off
17542         set_cache writethrough on
17543
17544         log "Read again; it should be satisfied from the cache."
17545         BEFORE=$(roc_hit)
17546         cancel_lru_locks osc
17547         cat $file >/dev/null
17548         AFTER=$(roc_hit)
17549         if ! let "AFTER - BEFORE == CPAGES"; then
17550                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17551         else
17552                 log "cache hits:: before: $BEFORE, after: $AFTER"
17553         fi
17554
17555         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17556                 # > 2.12.56 uses pagecache if cached
17557                 log "Read again; it should not be satisfied from the cache."
17558                 BEFORE=$AFTER
17559                 cancel_lru_locks osc
17560                 cat $file >/dev/null
17561                 AFTER=$(roc_hit)
17562                 if ! let "AFTER - BEFORE == 0"; then
17563                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17564                 else
17565                         log "cache hits:: before: $BEFORE, after: $AFTER"
17566                 fi
17567         fi
17568
17569         log "Write data and read it back."
17570         log "Read should be satisfied from the cache."
17571         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17572         BEFORE=$(roc_hit)
17573         cancel_lru_locks osc
17574         cat $file >/dev/null
17575         AFTER=$(roc_hit)
17576         if ! let "AFTER - BEFORE == CPAGES"; then
17577                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17578         else
17579                 log "cache hits:: before: $BEFORE, after: $AFTER"
17580         fi
17581
17582         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17583                 # > 2.12.56 uses pagecache if cached
17584                 log "Read again; it should not be satisfied from the cache."
17585                 BEFORE=$AFTER
17586                 cancel_lru_locks osc
17587                 cat $file >/dev/null
17588                 AFTER=$(roc_hit)
17589                 if ! let "AFTER - BEFORE == 0"; then
17590                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17591                 else
17592                         log "cache hits:: before: $BEFORE, after: $AFTER"
17593                 fi
17594         fi
17595
17596         log "Turn off read and write cache"
17597         set_cache read off
17598         set_cache writethrough off
17599
17600         log "Write data and read it back"
17601         log "It should not be satisfied from the cache."
17602         rm -f $file
17603         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17604         cancel_lru_locks osc
17605         BEFORE=$(roc_hit)
17606         cat $file >/dev/null
17607         AFTER=$(roc_hit)
17608         if ! let "AFTER - BEFORE == 0"; then
17609                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17610         else
17611                 log "cache hits:: before: $BEFORE, after: $AFTER"
17612         fi
17613
17614         log "Turn on the read cache and turn off the write cache"
17615         set_cache read on
17616         set_cache writethrough off
17617
17618         log "Write data and read it back"
17619         log "It should not be satisfied from the cache."
17620         rm -f $file
17621         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17622         BEFORE=$(roc_hit)
17623         cancel_lru_locks osc
17624         cat $file >/dev/null
17625         AFTER=$(roc_hit)
17626         if ! let "AFTER - BEFORE == 0"; then
17627                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17628         else
17629                 log "cache hits:: before: $BEFORE, after: $AFTER"
17630         fi
17631
17632         log "Read again; it should be satisfied from the cache."
17633         BEFORE=$(roc_hit)
17634         cancel_lru_locks osc
17635         cat $file >/dev/null
17636         AFTER=$(roc_hit)
17637         if ! let "AFTER - BEFORE == CPAGES"; then
17638                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17639         else
17640                 log "cache hits:: before: $BEFORE, after: $AFTER"
17641         fi
17642
17643         restore_lustre_params < $p
17644         rm -f $p $file
17645 }
17646 run_test 156 "Verification of tunables"
17647
17648 test_160a() {
17649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17650         remote_mds_nodsh && skip "remote MDS with nodsh"
17651         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17652                 skip "Need MDS version at least 2.2.0"
17653
17654         changelog_register || error "changelog_register failed"
17655         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17656         changelog_users $SINGLEMDS | grep -q $cl_user ||
17657                 error "User $cl_user not found in changelog_users"
17658
17659         mkdir_on_mdt0 $DIR/$tdir
17660
17661         # change something
17662         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17663         changelog_clear 0 || error "changelog_clear failed"
17664         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17665         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17666         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17667         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17668         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17669         rm $DIR/$tdir/pics/desktop.jpg
17670
17671         echo "verifying changelog mask"
17672         changelog_chmask "-MKDIR"
17673         changelog_chmask "-CLOSE"
17674
17675         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17676         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17677
17678         changelog_chmask "+MKDIR"
17679         changelog_chmask "+CLOSE"
17680
17681         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17682         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17683
17684         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17685         CLOSES=$(changelog_dump | grep -c "CLOSE")
17686         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17687         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17688
17689         # verify contents
17690         echo "verifying target fid"
17691         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17692         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17693         [ "$fidc" == "$fidf" ] ||
17694                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17695         echo "verifying parent fid"
17696         # The FID returned from the Changelog may be the directory shard on
17697         # a different MDT, and not the FID returned by path2fid on the parent.
17698         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17699         # since this is what will matter when recreating this file in the tree.
17700         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17701         local pathp=$($LFS fid2path $MOUNT "$fidp")
17702         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17703                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17704
17705         echo "getting records for $cl_user"
17706         changelog_users $SINGLEMDS
17707         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17708         local nclr=3
17709         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17710                 error "changelog_clear failed"
17711         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17712         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17713         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17714                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17715
17716         local min0_rec=$(changelog_users $SINGLEMDS |
17717                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17718         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17719                           awk '{ print $1; exit; }')
17720
17721         changelog_dump | tail -n 5
17722         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17723         [ $first_rec == $((min0_rec + 1)) ] ||
17724                 error "first index should be $min0_rec + 1 not $first_rec"
17725
17726         # LU-3446 changelog index reset on MDT restart
17727         local cur_rec1=$(changelog_users $SINGLEMDS |
17728                          awk '/^current.index:/ { print $NF }')
17729         changelog_clear 0 ||
17730                 error "clear all changelog records for $cl_user failed"
17731         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17732         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17733                 error "Fail to start $SINGLEMDS"
17734         local cur_rec2=$(changelog_users $SINGLEMDS |
17735                          awk '/^current.index:/ { print $NF }')
17736         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17737         [ $cur_rec1 == $cur_rec2 ] ||
17738                 error "current index should be $cur_rec1 not $cur_rec2"
17739
17740         echo "verifying users from this test are deregistered"
17741         changelog_deregister || error "changelog_deregister failed"
17742         changelog_users $SINGLEMDS | grep -q $cl_user &&
17743                 error "User '$cl_user' still in changelog_users"
17744
17745         # lctl get_param -n mdd.*.changelog_users
17746         # current_index: 144
17747         # ID    index (idle seconds)
17748         # cl3   144   (2) mask=<list>
17749         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17750                 # this is the normal case where all users were deregistered
17751                 # make sure no new records are added when no users are present
17752                 local last_rec1=$(changelog_users $SINGLEMDS |
17753                                   awk '/^current.index:/ { print $NF }')
17754                 touch $DIR/$tdir/chloe
17755                 local last_rec2=$(changelog_users $SINGLEMDS |
17756                                   awk '/^current.index:/ { print $NF }')
17757                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17758                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17759         else
17760                 # any changelog users must be leftovers from a previous test
17761                 changelog_users $SINGLEMDS
17762                 echo "other changelog users; can't verify off"
17763         fi
17764 }
17765 run_test 160a "changelog sanity"
17766
17767 test_160b() { # LU-3587
17768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17769         remote_mds_nodsh && skip "remote MDS with nodsh"
17770         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17771                 skip "Need MDS version at least 2.2.0"
17772
17773         changelog_register || error "changelog_register failed"
17774         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17775         changelog_users $SINGLEMDS | grep -q $cl_user ||
17776                 error "User '$cl_user' not found in changelog_users"
17777
17778         local longname1=$(str_repeat a 255)
17779         local longname2=$(str_repeat b 255)
17780
17781         cd $DIR
17782         echo "creating very long named file"
17783         touch $longname1 || error "create of '$longname1' failed"
17784         echo "renaming very long named file"
17785         mv $longname1 $longname2
17786
17787         changelog_dump | grep RENME | tail -n 5
17788         rm -f $longname2
17789 }
17790 run_test 160b "Verify that very long rename doesn't crash in changelog"
17791
17792 test_160c() {
17793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17794         remote_mds_nodsh && skip "remote MDS with nodsh"
17795
17796         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17797                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17798                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17799                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17800
17801         local rc=0
17802
17803         # Registration step
17804         changelog_register || error "changelog_register failed"
17805
17806         rm -rf $DIR/$tdir
17807         mkdir -p $DIR/$tdir
17808         $MCREATE $DIR/$tdir/foo_160c
17809         changelog_chmask "-TRUNC"
17810         $TRUNCATE $DIR/$tdir/foo_160c 200
17811         changelog_chmask "+TRUNC"
17812         $TRUNCATE $DIR/$tdir/foo_160c 199
17813         changelog_dump | tail -n 5
17814         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17815         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17816 }
17817 run_test 160c "verify that changelog log catch the truncate event"
17818
17819 test_160d() {
17820         remote_mds_nodsh && skip "remote MDS with nodsh"
17821         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17823         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17824                 skip "Need MDS version at least 2.7.60"
17825
17826         # Registration step
17827         changelog_register || error "changelog_register failed"
17828
17829         mkdir -p $DIR/$tdir/migrate_dir
17830         changelog_clear 0 || error "changelog_clear failed"
17831
17832         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17833         changelog_dump | tail -n 5
17834         local migrates=$(changelog_dump | grep -c "MIGRT")
17835         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17836 }
17837 run_test 160d "verify that changelog log catch the migrate event"
17838
17839 test_160e() {
17840         remote_mds_nodsh && skip "remote MDS with nodsh"
17841
17842         # Create a user
17843         changelog_register || error "changelog_register failed"
17844
17845         local MDT0=$(facet_svc $SINGLEMDS)
17846         local rc
17847
17848         # No user (expect fail)
17849         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17850         rc=$?
17851         if [ $rc -eq 0 ]; then
17852                 error "Should fail without user"
17853         elif [ $rc -ne 4 ]; then
17854                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17855         fi
17856
17857         # Delete a future user (expect fail)
17858         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17859         rc=$?
17860         if [ $rc -eq 0 ]; then
17861                 error "Deleted non-existant user cl77"
17862         elif [ $rc -ne 2 ]; then
17863                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17864         fi
17865
17866         # Clear to a bad index (1 billion should be safe)
17867         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17868         rc=$?
17869
17870         if [ $rc -eq 0 ]; then
17871                 error "Successfully cleared to invalid CL index"
17872         elif [ $rc -ne 22 ]; then
17873                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17874         fi
17875 }
17876 run_test 160e "changelog negative testing (should return errors)"
17877
17878 test_160f() {
17879         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17880         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17881                 skip "Need MDS version at least 2.10.56"
17882
17883         local mdts=$(comma_list $(mdts_nodes))
17884
17885         # Create a user
17886         changelog_register || error "first changelog_register failed"
17887         changelog_register || error "second changelog_register failed"
17888         local cl_users
17889         declare -A cl_user1
17890         declare -A cl_user2
17891         local user_rec1
17892         local user_rec2
17893         local i
17894
17895         # generate some changelog records to accumulate on each MDT
17896         # use all_char because created files should be evenly distributed
17897         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17898                 error "test_mkdir $tdir failed"
17899         log "$(date +%s): creating first files"
17900         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17901                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17902                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17903         done
17904
17905         # check changelogs have been generated
17906         local start=$SECONDS
17907         local idle_time=$((MDSCOUNT * 5 + 5))
17908         local nbcl=$(changelog_dump | wc -l)
17909         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17910
17911         for param in "changelog_max_idle_time=$idle_time" \
17912                      "changelog_gc=1" \
17913                      "changelog_min_gc_interval=2" \
17914                      "changelog_min_free_cat_entries=3"; do
17915                 local MDT0=$(facet_svc $SINGLEMDS)
17916                 local var="${param%=*}"
17917                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17918
17919                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17920                 do_nodes $mdts $LCTL set_param mdd.*.$param
17921         done
17922
17923         # force cl_user2 to be idle (1st part), but also cancel the
17924         # cl_user1 records so that it is not evicted later in the test.
17925         local sleep1=$((idle_time / 2))
17926         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17927         sleep $sleep1
17928
17929         # simulate changelog catalog almost full
17930         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17931         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17932
17933         for i in $(seq $MDSCOUNT); do
17934                 cl_users=(${CL_USERS[mds$i]})
17935                 cl_user1[mds$i]="${cl_users[0]}"
17936                 cl_user2[mds$i]="${cl_users[1]}"
17937
17938                 [ -n "${cl_user1[mds$i]}" ] ||
17939                         error "mds$i: no user registered"
17940                 [ -n "${cl_user2[mds$i]}" ] ||
17941                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17942
17943                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17944                 [ -n "$user_rec1" ] ||
17945                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17946                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17947                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17948                 [ -n "$user_rec2" ] ||
17949                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17950                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17951                      "$user_rec1 + 2 == $user_rec2"
17952                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17953                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17954                               "$user_rec1 + 2, but is $user_rec2"
17955                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17956                 [ -n "$user_rec2" ] ||
17957                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17958                 [ $user_rec1 == $user_rec2 ] ||
17959                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17960                               "$user_rec1, but is $user_rec2"
17961         done
17962
17963         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17964         local sleep2=$((idle_time - (SECONDS - start) + 1))
17965         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17966         sleep $sleep2
17967
17968         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17969         # cl_user1 should be OK because it recently processed records.
17970         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17971         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17972                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17973                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17974         done
17975
17976         # ensure gc thread is done
17977         for i in $(mdts_nodes); do
17978                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17979                         error "$i: GC-thread not done"
17980         done
17981
17982         local first_rec
17983         for (( i = 1; i <= MDSCOUNT; i++ )); do
17984                 # check cl_user1 still registered
17985                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17986                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17987                 # check cl_user2 unregistered
17988                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17989                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17990
17991                 # check changelogs are present and starting at $user_rec1 + 1
17992                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17993                 [ -n "$user_rec1" ] ||
17994                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17995                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17996                             awk '{ print $1; exit; }')
17997
17998                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17999                 [ $((user_rec1 + 1)) == $first_rec ] ||
18000                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18001         done
18002 }
18003 run_test 160f "changelog garbage collect (timestamped users)"
18004
18005 test_160g() {
18006         remote_mds_nodsh && skip "remote MDS with nodsh"
18007         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
18008                 skip "Need MDS version at least 2.14.55"
18009
18010         local mdts=$(comma_list $(mdts_nodes))
18011
18012         # Create a user
18013         changelog_register || error "first changelog_register failed"
18014         changelog_register || error "second changelog_register failed"
18015         local cl_users
18016         declare -A cl_user1
18017         declare -A cl_user2
18018         local user_rec1
18019         local user_rec2
18020         local i
18021
18022         # generate some changelog records to accumulate on each MDT
18023         # use all_char because created files should be evenly distributed
18024         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18025                 error "test_mkdir $tdir failed"
18026         for ((i = 0; i < MDSCOUNT; i++)); do
18027                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18028                         error "create $DIR/$tdir/d$i.1 failed"
18029         done
18030
18031         # check changelogs have been generated
18032         local nbcl=$(changelog_dump | wc -l)
18033         (( $nbcl > 0 )) || error "no changelogs found"
18034
18035         # reduce the max_idle_indexes value to make sure we exceed it
18036         for param in "changelog_max_idle_indexes=2" \
18037                      "changelog_gc=1" \
18038                      "changelog_min_gc_interval=2"; do
18039                 local MDT0=$(facet_svc $SINGLEMDS)
18040                 local var="${param%=*}"
18041                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18042
18043                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18044                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18045                         error "unable to set mdd.*.$param"
18046         done
18047
18048         local start=$SECONDS
18049         for i in $(seq $MDSCOUNT); do
18050                 cl_users=(${CL_USERS[mds$i]})
18051                 cl_user1[mds$i]="${cl_users[0]}"
18052                 cl_user2[mds$i]="${cl_users[1]}"
18053
18054                 [ -n "${cl_user1[mds$i]}" ] ||
18055                         error "mds$i: user1 is not registered"
18056                 [ -n "${cl_user2[mds$i]}" ] ||
18057                         error "mds$i: only ${cl_user1[mds$i]} is registered"
18058
18059                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18060                 [ -n "$user_rec1" ] ||
18061                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
18062                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18063                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18064                 [ -n "$user_rec2" ] ||
18065                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
18066                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
18067                      "$user_rec1 + 2 == $user_rec2"
18068                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18069                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
18070                               "expected $user_rec1 + 2, but is $user_rec2"
18071                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18072                 [ -n "$user_rec2" ] ||
18073                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
18074                 [ $user_rec1 == $user_rec2 ] ||
18075                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18076                               "expected $user_rec1, but is $user_rec2"
18077         done
18078
18079         # ensure we are past the previous changelog_min_gc_interval set above
18080         local sleep2=$((start + 2 - SECONDS))
18081         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18082         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18083         # cl_user1 should be OK because it recently processed records.
18084         for ((i = 0; i < MDSCOUNT; i++)); do
18085                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18086                         error "create $DIR/$tdir/d$i.3 failed"
18087         done
18088
18089         # ensure gc thread is done
18090         for i in $(mdts_nodes); do
18091                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18092                         error "$i: GC-thread not done"
18093         done
18094
18095         local first_rec
18096         for (( i = 1; i <= MDSCOUNT; i++ )); do
18097                 # check cl_user1 still registered
18098                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18099                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18100                 # check cl_user2 unregistered
18101                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18102                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18103
18104                 # check changelogs are present and starting at $user_rec1 + 1
18105                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18106                 [ -n "$user_rec1" ] ||
18107                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18108                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18109                             awk '{ print $1; exit; }')
18110
18111                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18112                 [ $((user_rec1 + 1)) == $first_rec ] ||
18113                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18114         done
18115 }
18116 run_test 160g "changelog garbage collect on idle records"
18117
18118 test_160h() {
18119         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18120         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18121                 skip "Need MDS version at least 2.10.56"
18122
18123         local mdts=$(comma_list $(mdts_nodes))
18124
18125         # Create a user
18126         changelog_register || error "first changelog_register failed"
18127         changelog_register || error "second changelog_register failed"
18128         local cl_users
18129         declare -A cl_user1
18130         declare -A cl_user2
18131         local user_rec1
18132         local user_rec2
18133         local i
18134
18135         # generate some changelog records to accumulate on each MDT
18136         # use all_char because created files should be evenly distributed
18137         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18138                 error "test_mkdir $tdir failed"
18139         for ((i = 0; i < MDSCOUNT; i++)); do
18140                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18141                         error "create $DIR/$tdir/d$i.1 failed"
18142         done
18143
18144         # check changelogs have been generated
18145         local nbcl=$(changelog_dump | wc -l)
18146         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18147
18148         for param in "changelog_max_idle_time=10" \
18149                      "changelog_gc=1" \
18150                      "changelog_min_gc_interval=2"; do
18151                 local MDT0=$(facet_svc $SINGLEMDS)
18152                 local var="${param%=*}"
18153                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18154
18155                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18156                 do_nodes $mdts $LCTL set_param mdd.*.$param
18157         done
18158
18159         # force cl_user2 to be idle (1st part)
18160         sleep 9
18161
18162         for i in $(seq $MDSCOUNT); do
18163                 cl_users=(${CL_USERS[mds$i]})
18164                 cl_user1[mds$i]="${cl_users[0]}"
18165                 cl_user2[mds$i]="${cl_users[1]}"
18166
18167                 [ -n "${cl_user1[mds$i]}" ] ||
18168                         error "mds$i: no user registered"
18169                 [ -n "${cl_user2[mds$i]}" ] ||
18170                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18171
18172                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18173                 [ -n "$user_rec1" ] ||
18174                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18175                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18176                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18177                 [ -n "$user_rec2" ] ||
18178                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18179                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18180                      "$user_rec1 + 2 == $user_rec2"
18181                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18182                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18183                               "$user_rec1 + 2, but is $user_rec2"
18184                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18185                 [ -n "$user_rec2" ] ||
18186                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18187                 [ $user_rec1 == $user_rec2 ] ||
18188                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18189                               "$user_rec1, but is $user_rec2"
18190         done
18191
18192         # force cl_user2 to be idle (2nd part) and to reach
18193         # changelog_max_idle_time
18194         sleep 2
18195
18196         # force each GC-thread start and block then
18197         # one per MDT/MDD, set fail_val accordingly
18198         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18199         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18200
18201         # generate more changelogs to trigger fail_loc
18202         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18203                 error "create $DIR/$tdir/${tfile}bis failed"
18204
18205         # stop MDT to stop GC-thread, should be done in back-ground as it will
18206         # block waiting for the thread to be released and exit
18207         declare -A stop_pids
18208         for i in $(seq $MDSCOUNT); do
18209                 stop mds$i &
18210                 stop_pids[mds$i]=$!
18211         done
18212
18213         for i in $(mdts_nodes); do
18214                 local facet
18215                 local nb=0
18216                 local facets=$(facets_up_on_host $i)
18217
18218                 for facet in ${facets//,/ }; do
18219                         if [[ $facet == mds* ]]; then
18220                                 nb=$((nb + 1))
18221                         fi
18222                 done
18223                 # ensure each MDS's gc threads are still present and all in "R"
18224                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18225                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18226                         error "$i: expected $nb GC-thread"
18227                 wait_update $i \
18228                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18229                         "R" 20 ||
18230                         error "$i: GC-thread not found in R-state"
18231                 # check umounts of each MDT on MDS have reached kthread_stop()
18232                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18233                         error "$i: expected $nb umount"
18234                 wait_update $i \
18235                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18236                         error "$i: umount not found in D-state"
18237         done
18238
18239         # release all GC-threads
18240         do_nodes $mdts $LCTL set_param fail_loc=0
18241
18242         # wait for MDT stop to complete
18243         for i in $(seq $MDSCOUNT); do
18244                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18245         done
18246
18247         # XXX
18248         # may try to check if any orphan changelog records are present
18249         # via ldiskfs/zfs and llog_reader...
18250
18251         # re-start/mount MDTs
18252         for i in $(seq $MDSCOUNT); do
18253                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18254                         error "Fail to start mds$i"
18255         done
18256
18257         local first_rec
18258         for i in $(seq $MDSCOUNT); do
18259                 # check cl_user1 still registered
18260                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18261                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18262                 # check cl_user2 unregistered
18263                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18264                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18265
18266                 # check changelogs are present and starting at $user_rec1 + 1
18267                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18268                 [ -n "$user_rec1" ] ||
18269                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18270                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18271                             awk '{ print $1; exit; }')
18272
18273                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18274                 [ $((user_rec1 + 1)) == $first_rec ] ||
18275                         error "mds$i: first index should be $user_rec1 + 1, " \
18276                               "but is $first_rec"
18277         done
18278 }
18279 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18280               "during mount"
18281
18282 test_160i() {
18283
18284         local mdts=$(comma_list $(mdts_nodes))
18285
18286         changelog_register || error "first changelog_register failed"
18287
18288         # generate some changelog records to accumulate on each MDT
18289         # use all_char because created files should be evenly distributed
18290         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18291                 error "test_mkdir $tdir failed"
18292         for ((i = 0; i < MDSCOUNT; i++)); do
18293                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18294                         error "create $DIR/$tdir/d$i.1 failed"
18295         done
18296
18297         # check changelogs have been generated
18298         local nbcl=$(changelog_dump | wc -l)
18299         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18300
18301         # simulate race between register and unregister
18302         # XXX as fail_loc is set per-MDS, with DNE configs the race
18303         # simulation will only occur for one MDT per MDS and for the
18304         # others the normal race scenario will take place
18305         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18306         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18307         do_nodes $mdts $LCTL set_param fail_val=1
18308
18309         # unregister 1st user
18310         changelog_deregister &
18311         local pid1=$!
18312         # wait some time for deregister work to reach race rdv
18313         sleep 2
18314         # register 2nd user
18315         changelog_register || error "2nd user register failed"
18316
18317         wait $pid1 || error "1st user deregister failed"
18318
18319         local i
18320         local last_rec
18321         declare -A LAST_REC
18322         for i in $(seq $MDSCOUNT); do
18323                 if changelog_users mds$i | grep "^cl"; then
18324                         # make sure new records are added with one user present
18325                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18326                                           awk '/^current.index:/ { print $NF }')
18327                 else
18328                         error "mds$i has no user registered"
18329                 fi
18330         done
18331
18332         # generate more changelog records to accumulate on each MDT
18333         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18334                 error "create $DIR/$tdir/${tfile}bis failed"
18335
18336         for i in $(seq $MDSCOUNT); do
18337                 last_rec=$(changelog_users $SINGLEMDS |
18338                            awk '/^current.index:/ { print $NF }')
18339                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18340                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18341                         error "changelogs are off on mds$i"
18342         done
18343 }
18344 run_test 160i "changelog user register/unregister race"
18345
18346 test_160j() {
18347         remote_mds_nodsh && skip "remote MDS with nodsh"
18348         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18349                 skip "Need MDS version at least 2.12.56"
18350
18351         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18352         stack_trap "umount $MOUNT2" EXIT
18353
18354         changelog_register || error "first changelog_register failed"
18355         stack_trap "changelog_deregister" EXIT
18356
18357         # generate some changelog
18358         # use all_char because created files should be evenly distributed
18359         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18360                 error "mkdir $tdir failed"
18361         for ((i = 0; i < MDSCOUNT; i++)); do
18362                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18363                         error "create $DIR/$tdir/d$i.1 failed"
18364         done
18365
18366         # open the changelog device
18367         exec 3>/dev/changelog-$FSNAME-MDT0000
18368         stack_trap "exec 3>&-" EXIT
18369         exec 4</dev/changelog-$FSNAME-MDT0000
18370         stack_trap "exec 4<&-" EXIT
18371
18372         # umount the first lustre mount
18373         umount $MOUNT
18374         stack_trap "mount_client $MOUNT" EXIT
18375
18376         # read changelog, which may or may not fail, but should not crash
18377         cat <&4 >/dev/null
18378
18379         # clear changelog
18380         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18381         changelog_users $SINGLEMDS | grep -q $cl_user ||
18382                 error "User $cl_user not found in changelog_users"
18383
18384         printf 'clear:'$cl_user':0' >&3
18385 }
18386 run_test 160j "client can be umounted while its chanangelog is being used"
18387
18388 test_160k() {
18389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18390         remote_mds_nodsh && skip "remote MDS with nodsh"
18391
18392         mkdir -p $DIR/$tdir/1/1
18393
18394         changelog_register || error "changelog_register failed"
18395         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18396
18397         changelog_users $SINGLEMDS | grep -q $cl_user ||
18398                 error "User '$cl_user' not found in changelog_users"
18399 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18400         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18401         rmdir $DIR/$tdir/1/1 & sleep 1
18402         mkdir $DIR/$tdir/2
18403         touch $DIR/$tdir/2/2
18404         rm -rf $DIR/$tdir/2
18405
18406         wait
18407         sleep 4
18408
18409         changelog_dump | grep rmdir || error "rmdir not recorded"
18410 }
18411 run_test 160k "Verify that changelog records are not lost"
18412
18413 # Verifies that a file passed as a parameter has recently had an operation
18414 # performed on it that has generated an MTIME changelog which contains the
18415 # correct parent FID. As files might reside on a different MDT from the
18416 # parent directory in DNE configurations, the FIDs are translated to paths
18417 # before being compared, which should be identical
18418 compare_mtime_changelog() {
18419         local file="${1}"
18420         local mdtidx
18421         local mtime
18422         local cl_fid
18423         local pdir
18424         local dir
18425
18426         mdtidx=$($LFS getstripe --mdt-index $file)
18427         mdtidx=$(printf "%04x" $mdtidx)
18428
18429         # Obtain the parent FID from the MTIME changelog
18430         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18431         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18432
18433         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18434         [ -z "$cl_fid" ] && error "parent FID not present"
18435
18436         # Verify that the path for the parent FID is the same as the path for
18437         # the test directory
18438         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18439
18440         dir=$(dirname $1)
18441
18442         [[ "${pdir%/}" == "$dir" ]] ||
18443                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18444 }
18445
18446 test_160l() {
18447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18448
18449         remote_mds_nodsh && skip "remote MDS with nodsh"
18450         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18451                 skip "Need MDS version at least 2.13.55"
18452
18453         local cl_user
18454
18455         changelog_register || error "changelog_register failed"
18456         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18457
18458         changelog_users $SINGLEMDS | grep -q $cl_user ||
18459                 error "User '$cl_user' not found in changelog_users"
18460
18461         # Clear some types so that MTIME changelogs are generated
18462         changelog_chmask "-CREAT"
18463         changelog_chmask "-CLOSE"
18464
18465         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18466
18467         # Test CL_MTIME during setattr
18468         touch $DIR/$tdir/$tfile
18469         compare_mtime_changelog $DIR/$tdir/$tfile
18470
18471         # Test CL_MTIME during close
18472         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18473         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18474 }
18475 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18476
18477 test_160m() {
18478         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18479         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18480                 skip "Need MDS version at least 2.14.51"
18481         local cl_users
18482         local cl_user1
18483         local cl_user2
18484         local pid1
18485
18486         # Create a user
18487         changelog_register || error "first changelog_register failed"
18488         changelog_register || error "second changelog_register failed"
18489
18490         cl_users=(${CL_USERS[mds1]})
18491         cl_user1="${cl_users[0]}"
18492         cl_user2="${cl_users[1]}"
18493         # generate some changelog records to accumulate on MDT0
18494         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18495         createmany -m $DIR/$tdir/$tfile 50 ||
18496                 error "create $DIR/$tdir/$tfile failed"
18497         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18498         rm -f $DIR/$tdir
18499
18500         # check changelogs have been generated
18501         local nbcl=$(changelog_dump | wc -l)
18502         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18503
18504 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18505         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18506
18507         __changelog_clear mds1 $cl_user1 +10
18508         __changelog_clear mds1 $cl_user2 0 &
18509         pid1=$!
18510         sleep 2
18511         __changelog_clear mds1 $cl_user1 0 ||
18512                 error "fail to cancel record for $cl_user1"
18513         wait $pid1
18514         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18515 }
18516 run_test 160m "Changelog clear race"
18517
18518 test_160n() {
18519         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18520         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18521                 skip "Need MDS version at least 2.14.51"
18522         local cl_users
18523         local cl_user1
18524         local cl_user2
18525         local pid1
18526         local first_rec
18527         local last_rec=0
18528
18529         # Create a user
18530         changelog_register || error "first changelog_register failed"
18531
18532         cl_users=(${CL_USERS[mds1]})
18533         cl_user1="${cl_users[0]}"
18534
18535         # generate some changelog records to accumulate on MDT0
18536         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18537         first_rec=$(changelog_users $SINGLEMDS |
18538                         awk '/^current.index:/ { print $NF }')
18539         while (( last_rec < (( first_rec + 65000)) )); do
18540                 createmany -m $DIR/$tdir/$tfile 10000 ||
18541                         error "create $DIR/$tdir/$tfile failed"
18542
18543                 for i in $(seq 0 10000); do
18544                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18545                                 > /dev/null
18546                 done
18547
18548                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18549                         error "unlinkmany failed unlink"
18550                 last_rec=$(changelog_users $SINGLEMDS |
18551                         awk '/^current.index:/ { print $NF }')
18552                 echo last record $last_rec
18553                 (( last_rec == 0 )) && error "no changelog found"
18554         done
18555
18556 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18557         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18558
18559         __changelog_clear mds1 $cl_user1 0 &
18560         pid1=$!
18561         sleep 2
18562         __changelog_clear mds1 $cl_user1 0 ||
18563                 error "fail to cancel record for $cl_user1"
18564         wait $pid1
18565         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18566 }
18567 run_test 160n "Changelog destroy race"
18568
18569 test_160o() {
18570         local mdt="$(facet_svc $SINGLEMDS)"
18571
18572         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18573         remote_mds_nodsh && skip "remote MDS with nodsh"
18574         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18575                 skip "Need MDS version at least 2.14.52"
18576
18577         changelog_register --user test_160o -m unlnk+close+open ||
18578                 error "changelog_register failed"
18579
18580         do_facet $SINGLEMDS $LCTL --device $mdt \
18581                                 changelog_register -u "Tt3_-#" &&
18582                 error "bad symbols in name should fail"
18583
18584         do_facet $SINGLEMDS $LCTL --device $mdt \
18585                                 changelog_register -u test_160o &&
18586                 error "the same name registration should fail"
18587
18588         do_facet $SINGLEMDS $LCTL --device $mdt \
18589                         changelog_register -u test_160toolongname &&
18590                 error "too long name registration should fail"
18591
18592         changelog_chmask "MARK+HSM"
18593         lctl get_param mdd.*.changelog*mask
18594         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18595         changelog_users $SINGLEMDS | grep -q $cl_user ||
18596                 error "User $cl_user not found in changelog_users"
18597         #verify username
18598         echo $cl_user | grep -q test_160o ||
18599                 error "User $cl_user has no specific name 'test160o'"
18600
18601         # change something
18602         changelog_clear 0 || error "changelog_clear failed"
18603         # generate some changelog records to accumulate on MDT0
18604         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18605         touch $DIR/$tdir/$tfile                 # open 1
18606
18607         OPENS=$(changelog_dump | grep -c "OPEN")
18608         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18609
18610         # must be no MKDIR it wasn't set as user mask
18611         MKDIR=$(changelog_dump | grep -c "MKDIR")
18612         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18613
18614         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18615                                 mdd.$mdt.changelog_current_mask -n)
18616         # register maskless user
18617         changelog_register || error "changelog_register failed"
18618         # effective mask should be not changed because it is not minimal
18619         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18620                                 mdd.$mdt.changelog_current_mask -n)
18621         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18622         # set server mask to minimal value
18623         changelog_chmask "MARK"
18624         # check effective mask again, should be treated as DEFMASK now
18625         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18626                                 mdd.$mdt.changelog_current_mask -n)
18627         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18628
18629         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18630                 # set server mask back to some value
18631                 changelog_chmask "CLOSE,UNLNK"
18632                 # check effective mask again, should not remain as DEFMASK
18633                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18634                                 mdd.$mdt.changelog_current_mask -n)
18635                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18636         fi
18637
18638         do_facet $SINGLEMDS $LCTL --device $mdt \
18639                                 changelog_deregister -u test_160o ||
18640                 error "cannot deregister by name"
18641 }
18642 run_test 160o "changelog user name and mask"
18643
18644 test_160p() {
18645         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18646         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18647                 skip "Need MDS version at least 2.14.51"
18648         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18649         local cl_users
18650         local cl_user1
18651         local entry_count
18652
18653         # Create a user
18654         changelog_register || error "first changelog_register failed"
18655
18656         cl_users=(${CL_USERS[mds1]})
18657         cl_user1="${cl_users[0]}"
18658
18659         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18660         createmany -m $DIR/$tdir/$tfile 50 ||
18661                 error "create $DIR/$tdir/$tfile failed"
18662         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18663         rm -rf $DIR/$tdir
18664
18665         # check changelogs have been generated
18666         entry_count=$(changelog_dump | wc -l)
18667         ((entry_count != 0)) || error "no changelog entries found"
18668
18669         # remove changelog_users and check that orphan entries are removed
18670         stop mds1
18671         local dev=$(mdsdevname 1)
18672         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18673         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18674         entry_count=$(changelog_dump | wc -l)
18675         ((entry_count == 0)) ||
18676                 error "found $entry_count changelog entries, expected none"
18677 }
18678 run_test 160p "Changelog orphan cleanup with no users"
18679
18680 test_160q() {
18681         local mdt="$(facet_svc $SINGLEMDS)"
18682         local clu
18683
18684         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18685         remote_mds_nodsh && skip "remote MDS with nodsh"
18686         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18687                 skip "Need MDS version at least 2.14.54"
18688
18689         # set server mask to minimal value like server init does
18690         changelog_chmask "MARK"
18691         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18692                 error "changelog_register failed"
18693         # check effective mask again, should be treated as DEFMASK now
18694         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18695                                 mdd.$mdt.changelog_current_mask -n)
18696         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18697                 error "changelog_deregister failed"
18698         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18699 }
18700 run_test 160q "changelog effective mask is DEFMASK if not set"
18701
18702 test_160s() {
18703         remote_mds_nodsh && skip "remote MDS with nodsh"
18704         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18705                 skip "Need MDS version at least 2.14.55"
18706
18707         local mdts=$(comma_list $(mdts_nodes))
18708
18709         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18710         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18711                                        fail_val=$((24 * 3600 * 10))
18712
18713         # Create a user which is 10 days old
18714         changelog_register || error "first changelog_register failed"
18715         local cl_users
18716         declare -A cl_user1
18717         local i
18718
18719         # generate some changelog records to accumulate on each MDT
18720         # use all_char because created files should be evenly distributed
18721         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18722                 error "test_mkdir $tdir failed"
18723         for ((i = 0; i < MDSCOUNT; i++)); do
18724                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18725                         error "create $DIR/$tdir/d$i.1 failed"
18726         done
18727
18728         # check changelogs have been generated
18729         local nbcl=$(changelog_dump | wc -l)
18730         (( nbcl > 0 )) || error "no changelogs found"
18731
18732         # reduce the max_idle_indexes value to make sure we exceed it
18733         for param in "changelog_max_idle_indexes=2097446912" \
18734                      "changelog_max_idle_time=2592000" \
18735                      "changelog_gc=1" \
18736                      "changelog_min_gc_interval=2"; do
18737                 local MDT0=$(facet_svc $SINGLEMDS)
18738                 local var="${param%=*}"
18739                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18740
18741                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18742                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18743                         error "unable to set mdd.*.$param"
18744         done
18745
18746         local start=$SECONDS
18747         for i in $(seq $MDSCOUNT); do
18748                 cl_users=(${CL_USERS[mds$i]})
18749                 cl_user1[mds$i]="${cl_users[0]}"
18750
18751                 [[ -n "${cl_user1[mds$i]}" ]] ||
18752                         error "mds$i: no user registered"
18753         done
18754
18755         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18756         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18757
18758         # ensure we are past the previous changelog_min_gc_interval set above
18759         local sleep2=$((start + 2 - SECONDS))
18760         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18761
18762         # Generate one more changelog to trigger GC
18763         for ((i = 0; i < MDSCOUNT; i++)); do
18764                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18765                         error "create $DIR/$tdir/d$i.3 failed"
18766         done
18767
18768         # ensure gc thread is done
18769         for node in $(mdts_nodes); do
18770                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18771                         error "$node: GC-thread not done"
18772         done
18773
18774         do_nodes $mdts $LCTL set_param fail_loc=0
18775
18776         for (( i = 1; i <= MDSCOUNT; i++ )); do
18777                 # check cl_user1 is purged
18778                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18779                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18780         done
18781         return 0
18782 }
18783 run_test 160s "changelog garbage collect on idle records * time"
18784
18785 test_160t() {
18786         remote_mds_nodsh && skip "remote MDS with nodsh"
18787         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18788                 skip "Need MDS version at least 2.15.50"
18789
18790         local MDT0=$(facet_svc $SINGLEMDS)
18791         local cl_users
18792         local cl_user1
18793         local cl_user2
18794         local start
18795
18796         changelog_register --user user1 -m all ||
18797                 error "user1 failed to register"
18798
18799         mkdir_on_mdt0 $DIR/$tdir
18800         # create default overstripe to maximize changelog size
18801         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18802         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18803         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18804
18805         # user2 consumes less records so less space
18806         changelog_register --user user2 || error "user2 failed to register"
18807         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18808         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18809
18810         # check changelogs have been generated
18811         local nbcl=$(changelog_dump | wc -l)
18812         (( nbcl > 0 )) || error "no changelogs found"
18813
18814         # reduce the changelog_min_gc_interval to force check
18815         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18816                 local var="${param%=*}"
18817                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18818
18819                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18820                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18821                         error "unable to set mdd.*.$param"
18822         done
18823
18824         start=$SECONDS
18825         cl_users=(${CL_USERS[mds1]})
18826         cl_user1="${cl_users[0]}"
18827         cl_user2="${cl_users[1]}"
18828
18829         [[ -n $cl_user1 ]] ||
18830                 error "mds1: user #1 isn't registered"
18831         [[ -n $cl_user2 ]] ||
18832                 error "mds1: user #2 isn't registered"
18833
18834         # ensure we are past the previous changelog_min_gc_interval set above
18835         local sleep2=$((start + 2 - SECONDS))
18836         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18837
18838         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18839         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18840                         fail_val=$(((llog_size1 + llog_size2) / 2))
18841
18842         # Generate more changelog to trigger GC
18843         createmany -o $DIR/$tdir/u3_ 4 ||
18844                 error "create failed for more files"
18845
18846         # ensure gc thread is done
18847         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18848                 error "mds1: GC-thread not done"
18849
18850         do_facet mds1 $LCTL set_param fail_loc=0
18851
18852         # check cl_user1 is purged
18853         changelog_users mds1 | grep -q "$cl_user1" &&
18854                 error "User $cl_user1 is registered"
18855         # check cl_user2 is not purged
18856         changelog_users mds1 | grep -q "$cl_user2" ||
18857                 error "User $cl_user2 is not registered"
18858 }
18859 run_test 160t "changelog garbage collect on lack of space"
18860
18861 test_160u() { # LU-17400
18862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18863         remote_mds_nodsh && skip "remote MDS with nodsh"
18864         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18865                 skip "Need MDS version at least 2.2.0"
18866
18867         cd $DIR || error "cd $DIR failed"
18868
18869         # ensure changelog has a clean view if tests are run multiple times
18870         [ -d rename ] && rm -rf rename
18871
18872         changelog_register || error "changelog_register failed"
18873         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18874
18875         changelog_users $SINGLEMDS | grep -q $cl_user ||
18876                 error "User '$cl_user' not found in changelog_users"
18877
18878         local longname1=$(str_repeat a 255)
18879
18880         echo "creating simple directory tree"
18881         mkdir -p rename/a || error "create of simple directory tree failed"
18882         echo "creating rename/hw file"
18883         echo "hello world" > rename/hw || error "create of rename/hw failed"
18884         echo "creating very long named file"
18885         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18886         echo "move rename/hw to rename/a/a.hw"
18887         mv rename/hw rename/a/a.hw || error "mv failed"
18888
18889         RENME=($(changelog_dump | grep "RENME"))
18890         #declare -p RENME # for debugging captured value with indexes
18891
18892         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18893                 error "changelog rename record type name/sname error"
18894 }
18895 run_test 160u "changelog rename record type name and sname strings are correct"
18896
18897 test_161a() {
18898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18899
18900         test_mkdir -c1 $DIR/$tdir
18901         cp /etc/hosts $DIR/$tdir/$tfile
18902         test_mkdir -c1 $DIR/$tdir/foo1
18903         test_mkdir -c1 $DIR/$tdir/foo2
18904         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18905         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18906         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18907         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18908         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18909         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18910                 $LFS fid2path $DIR $FID
18911                 error "bad link ea"
18912         fi
18913         # middle
18914         rm $DIR/$tdir/foo2/zachary
18915         # last
18916         rm $DIR/$tdir/foo2/thor
18917         # first
18918         rm $DIR/$tdir/$tfile
18919         # rename
18920         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18921         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18922                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18923         rm $DIR/$tdir/foo2/maggie
18924
18925         # overflow the EA
18926         local longname=$tfile.avg_len_is_thirty_two_
18927         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18928                 error_noexit 'failed to unlink many hardlinks'" EXIT
18929         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18930                 error "failed to hardlink many files"
18931         links=$($LFS fid2path $DIR $FID | wc -l)
18932         echo -n "${links}/1000 links in link EA"
18933         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18934 }
18935 run_test 161a "link ea sanity"
18936
18937 test_161b() {
18938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18939         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18940
18941         local MDTIDX=1
18942         local remote_dir=$DIR/$tdir/remote_dir
18943
18944         mkdir -p $DIR/$tdir
18945         $LFS mkdir -i $MDTIDX $remote_dir ||
18946                 error "create remote directory failed"
18947
18948         cp /etc/hosts $remote_dir/$tfile
18949         mkdir -p $remote_dir/foo1
18950         mkdir -p $remote_dir/foo2
18951         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18952         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18953         ln $remote_dir/$tfile $remote_dir/foo1/luna
18954         ln $remote_dir/$tfile $remote_dir/foo2/thor
18955
18956         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18957                      tr -d ']')
18958         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18959                 $LFS fid2path $DIR $FID
18960                 error "bad link ea"
18961         fi
18962         # middle
18963         rm $remote_dir/foo2/zachary
18964         # last
18965         rm $remote_dir/foo2/thor
18966         # first
18967         rm $remote_dir/$tfile
18968         # rename
18969         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18970         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18971         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18972                 $LFS fid2path $DIR $FID
18973                 error "bad link rename"
18974         fi
18975         rm $remote_dir/foo2/maggie
18976
18977         # overflow the EA
18978         local longname=filename_avg_len_is_thirty_two_
18979         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18980                 error "failed to hardlink many files"
18981         links=$($LFS fid2path $DIR $FID | wc -l)
18982         echo -n "${links}/1000 links in link EA"
18983         [[ ${links} -gt 60 ]] ||
18984                 error "expected at least 60 links in link EA"
18985         unlinkmany $remote_dir/foo2/$longname 1000 ||
18986         error "failed to unlink many hardlinks"
18987 }
18988 run_test 161b "link ea sanity under remote directory"
18989
18990 test_161c() {
18991         remote_mds_nodsh && skip "remote MDS with nodsh"
18992         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18993         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18994                 skip "Need MDS version at least 2.1.5"
18995
18996         # define CLF_RENAME_LAST 0x0001
18997         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18998         changelog_register || error "changelog_register failed"
18999
19000         rm -rf $DIR/$tdir
19001         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
19002         touch $DIR/$tdir/foo_161c
19003         touch $DIR/$tdir/bar_161c
19004         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19005         changelog_dump | grep RENME | tail -n 5
19006         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19007         changelog_clear 0 || error "changelog_clear failed"
19008         if [ x$flags != "x0x1" ]; then
19009                 error "flag $flags is not 0x1"
19010         fi
19011
19012         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
19013         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
19014         touch $DIR/$tdir/foo_161c
19015         touch $DIR/$tdir/bar_161c
19016         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19017         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
19018         changelog_dump | grep RENME | tail -n 5
19019         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
19020         changelog_clear 0 || error "changelog_clear failed"
19021         if [ x$flags != "x0x0" ]; then
19022                 error "flag $flags is not 0x0"
19023         fi
19024         echo "rename overwrite a target having nlink > 1," \
19025                 "changelog record has flags of $flags"
19026
19027         # rename doesn't overwrite a target (changelog flag 0x0)
19028         touch $DIR/$tdir/foo_161c
19029         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
19030         changelog_dump | grep RENME | tail -n 5
19031         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
19032         changelog_clear 0 || error "changelog_clear failed"
19033         if [ x$flags != "x0x0" ]; then
19034                 error "flag $flags is not 0x0"
19035         fi
19036         echo "rename doesn't overwrite a target," \
19037                 "changelog record has flags of $flags"
19038
19039         # define CLF_UNLINK_LAST 0x0001
19040         # unlink a file having nlink = 1 (changelog flag 0x1)
19041         rm -f $DIR/$tdir/foo2_161c
19042         changelog_dump | grep UNLNK | tail -n 5
19043         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19044         changelog_clear 0 || error "changelog_clear failed"
19045         if [ x$flags != "x0x1" ]; then
19046                 error "flag $flags is not 0x1"
19047         fi
19048         echo "unlink a file having nlink = 1," \
19049                 "changelog record has flags of $flags"
19050
19051         # unlink a file having nlink > 1 (changelog flag 0x0)
19052         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
19053         rm -f $DIR/$tdir/foobar_161c
19054         changelog_dump | grep UNLNK | tail -n 5
19055         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
19056         changelog_clear 0 || error "changelog_clear failed"
19057         if [ x$flags != "x0x0" ]; then
19058                 error "flag $flags is not 0x0"
19059         fi
19060         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
19061 }
19062 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
19063
19064 test_161d() {
19065         remote_mds_nodsh && skip "remote MDS with nodsh"
19066         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19067
19068         local pid
19069         local fid
19070
19071         changelog_register || error "changelog_register failed"
19072
19073         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
19074         # interfer with $MOUNT/.lustre/fid/ access
19075         mkdir $DIR/$tdir
19076         [[ $? -eq 0 ]] || error "mkdir failed"
19077
19078         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19079         $LCTL set_param fail_loc=0x8000140c
19080         # 5s pause
19081         $LCTL set_param fail_val=5
19082
19083         # create file
19084         echo foofoo > $DIR/$tdir/$tfile &
19085         pid=$!
19086
19087         # wait for create to be delayed
19088         sleep 2
19089
19090         ps -p $pid
19091         [[ $? -eq 0 ]] || error "create should be blocked"
19092
19093         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19094         stack_trap "rm -f $tempfile"
19095         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19096         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19097         # some delay may occur during ChangeLog publishing and file read just
19098         # above, that could allow file write to happen finally
19099         [[ -s $tempfile ]] && echo "file should be empty"
19100
19101         $LCTL set_param fail_loc=0
19102
19103         wait $pid
19104         [[ $? -eq 0 ]] || error "create failed"
19105 }
19106 run_test 161d "create with concurrent .lustre/fid access"
19107
19108 check_path() {
19109         local expected="$1"
19110         shift
19111         local fid="$2"
19112
19113         local path
19114         path=$($LFS fid2path "$@")
19115         local rc=$?
19116
19117         if [ $rc -ne 0 ]; then
19118                 error "path looked up of '$expected' failed: rc=$rc"
19119         elif [ "$path" != "$expected" ]; then
19120                 error "path looked up '$path' instead of '$expected'"
19121         else
19122                 echo "FID '$fid' resolves to path '$path' as expected"
19123         fi
19124 }
19125
19126 test_162a() { # was test_162
19127         test_mkdir -p -c1 $DIR/$tdir/d2
19128         touch $DIR/$tdir/d2/$tfile
19129         touch $DIR/$tdir/d2/x1
19130         touch $DIR/$tdir/d2/x2
19131         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19132         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19133         # regular file
19134         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19135         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19136
19137         # softlink
19138         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19139         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19140         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19141
19142         # softlink to wrong file
19143         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19144         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19145         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19146
19147         # hardlink
19148         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19149         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19150         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19151         # fid2path dir/fsname should both work
19152         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19153         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19154
19155         # hardlink count: check that there are 2 links
19156         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19157         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19158
19159         # hardlink indexing: remove the first link
19160         rm $DIR/$tdir/d2/p/q/r/hlink
19161         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19162 }
19163 run_test 162a "path lookup sanity"
19164
19165 test_162b() {
19166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19167         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19168
19169         mkdir $DIR/$tdir
19170         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19171                                 error "create striped dir failed"
19172
19173         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19174                                         tail -n 1 | awk '{print $2}')
19175         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19176
19177         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19178         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19179
19180         # regular file
19181         for ((i=0;i<5;i++)); do
19182                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19183                         error "get fid for f$i failed"
19184                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19185
19186                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19187                         error "get fid for d$i failed"
19188                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19189         done
19190
19191         return 0
19192 }
19193 run_test 162b "striped directory path lookup sanity"
19194
19195 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19196 test_162c() {
19197         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19198                 skip "Need MDS version at least 2.7.51"
19199
19200         local lpath=$tdir.local
19201         local rpath=$tdir.remote
19202
19203         test_mkdir $DIR/$lpath
19204         test_mkdir $DIR/$rpath
19205
19206         for ((i = 0; i <= 101; i++)); do
19207                 lpath="$lpath/$i"
19208                 mkdir $DIR/$lpath
19209                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19210                         error "get fid for local directory $DIR/$lpath failed"
19211                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19212
19213                 rpath="$rpath/$i"
19214                 test_mkdir $DIR/$rpath
19215                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19216                         error "get fid for remote directory $DIR/$rpath failed"
19217                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19218         done
19219
19220         return 0
19221 }
19222 run_test 162c "fid2path works with paths 100 or more directories deep"
19223
19224 oalr_event_count() {
19225         local event="${1}"
19226         local trace="${2}"
19227
19228         awk -v name="${FSNAME}-OST0000" \
19229             -v event="${event}" \
19230             '$1 == "TRACE" && $2 == event && $3 == name' \
19231             "${trace}" |
19232         wc -l
19233 }
19234
19235 oalr_expect_event_count() {
19236         local event="${1}"
19237         local trace="${2}"
19238         local expect="${3}"
19239         local count
19240
19241         count=$(oalr_event_count "${event}" "${trace}")
19242         if ((count == expect)); then
19243                 return 0
19244         fi
19245
19246         error_noexit "${event} event count was '${count}', expected ${expect}"
19247         cat "${trace}" >&2
19248         exit 1
19249 }
19250
19251 cleanup_165() {
19252         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19253         stop ost1
19254         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19255 }
19256
19257 setup_165() {
19258         sync # Flush previous IOs so we can count log entries.
19259         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19260         stack_trap cleanup_165 EXIT
19261 }
19262
19263 test_165a() {
19264         local trace="/tmp/${tfile}.trace"
19265         local rc
19266         local count
19267
19268         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19269                 skip "OFD access log unsupported"
19270
19271         setup_165
19272         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19273         sleep 5
19274
19275         do_facet ost1 ofd_access_log_reader --list
19276         stop ost1
19277
19278         do_facet ost1 killall -TERM ofd_access_log_reader
19279         wait
19280         rc=$?
19281
19282         if ((rc != 0)); then
19283                 error "ofd_access_log_reader exited with rc = '${rc}'"
19284         fi
19285
19286         # Parse trace file for discovery events:
19287         oalr_expect_event_count alr_log_add "${trace}" 1
19288         oalr_expect_event_count alr_log_eof "${trace}" 1
19289         oalr_expect_event_count alr_log_free "${trace}" 1
19290 }
19291 run_test 165a "ofd access log discovery"
19292
19293 test_165b() {
19294         local trace="/tmp/${tfile}.trace"
19295         local file="${DIR}/${tfile}"
19296         local pfid1
19297         local pfid2
19298         local -a entry
19299         local rc
19300         local count
19301         local size
19302         local flags
19303
19304         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19305                 skip "OFD access log unsupported"
19306
19307         setup_165
19308         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19309         sleep 5
19310
19311         do_facet ost1 ofd_access_log_reader --list
19312
19313         lfs setstripe -c 1 -i 0 "${file}"
19314         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19315                 error "cannot create '${file}'"
19316
19317         sleep 5
19318         do_facet ost1 killall -TERM ofd_access_log_reader
19319         wait
19320         rc=$?
19321
19322         if ((rc != 0)); then
19323                 error "ofd_access_log_reader exited with rc = '${rc}'"
19324         fi
19325
19326         oalr_expect_event_count alr_log_entry "${trace}" 1
19327
19328         pfid1=$($LFS path2fid "${file}")
19329
19330         # 1     2             3   4    5     6   7    8    9     10
19331         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19332         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19333
19334         echo "entry = '${entry[*]}'" >&2
19335
19336         pfid2=${entry[4]}
19337         if [[ "${pfid1}" != "${pfid2}" ]]; then
19338                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19339         fi
19340
19341         size=${entry[8]}
19342         if ((size != 1048576)); then
19343                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19344         fi
19345
19346         flags=${entry[10]}
19347         if [[ "${flags}" != "w" ]]; then
19348                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19349         fi
19350
19351         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19352         sleep 5
19353
19354         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19355                 error "cannot read '${file}'"
19356         sleep 5
19357
19358         do_facet ost1 killall -TERM ofd_access_log_reader
19359         wait
19360         rc=$?
19361
19362         if ((rc != 0)); then
19363                 error "ofd_access_log_reader exited with rc = '${rc}'"
19364         fi
19365
19366         oalr_expect_event_count alr_log_entry "${trace}" 1
19367
19368         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19369         echo "entry = '${entry[*]}'" >&2
19370
19371         pfid2=${entry[4]}
19372         if [[ "${pfid1}" != "${pfid2}" ]]; then
19373                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19374         fi
19375
19376         size=${entry[8]}
19377         if ((size != 524288)); then
19378                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19379         fi
19380
19381         flags=${entry[10]}
19382         if [[ "${flags}" != "r" ]]; then
19383                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19384         fi
19385 }
19386 run_test 165b "ofd access log entries are produced and consumed"
19387
19388 test_165c() {
19389         local trace="/tmp/${tfile}.trace"
19390         local file="${DIR}/${tdir}/${tfile}"
19391
19392         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19393                 skip "OFD access log unsupported"
19394
19395         test_mkdir "${DIR}/${tdir}"
19396
19397         setup_165
19398         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19399         sleep 5
19400
19401         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19402
19403         # 4096 / 64 = 64. Create twice as many entries.
19404         for ((i = 0; i < 128; i++)); do
19405                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19406                         error "cannot create file"
19407         done
19408
19409         sync
19410
19411         do_facet ost1 killall -TERM ofd_access_log_reader
19412         wait
19413         rc=$?
19414         if ((rc != 0)); then
19415                 error "ofd_access_log_reader exited with rc = '${rc}'"
19416         fi
19417
19418         unlinkmany  "${file}-%d" 128
19419 }
19420 run_test 165c "full ofd access logs do not block IOs"
19421
19422 oal_get_read_count() {
19423         local stats="$1"
19424
19425         # STATS lustre-OST0001 alr_read_count 1
19426
19427         do_facet ost1 cat "${stats}" |
19428         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19429              END { print count; }'
19430 }
19431
19432 oal_expect_read_count() {
19433         local stats="$1"
19434         local count
19435         local expect="$2"
19436
19437         # Ask ofd_access_log_reader to write stats.
19438         do_facet ost1 killall -USR1 ofd_access_log_reader
19439
19440         # Allow some time for things to happen.
19441         sleep 1
19442
19443         count=$(oal_get_read_count "${stats}")
19444         if ((count == expect)); then
19445                 return 0
19446         fi
19447
19448         error_noexit "bad read count, got ${count}, expected ${expect}"
19449         do_facet ost1 cat "${stats}" >&2
19450         exit 1
19451 }
19452
19453 test_165d() {
19454         local stats="/tmp/${tfile}.stats"
19455         local file="${DIR}/${tdir}/${tfile}"
19456         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19457
19458         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19459                 skip "OFD access log unsupported"
19460
19461         test_mkdir "${DIR}/${tdir}"
19462
19463         setup_165
19464         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19465         sleep 5
19466
19467         lfs setstripe -c 1 -i 0 "${file}"
19468
19469         do_facet ost1 lctl set_param "${param}=rw"
19470         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19471                 error "cannot create '${file}'"
19472         oal_expect_read_count "${stats}" 1
19473
19474         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19475                 error "cannot read '${file}'"
19476         oal_expect_read_count "${stats}" 2
19477
19478         do_facet ost1 lctl set_param "${param}=r"
19479         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19480                 error "cannot create '${file}'"
19481         oal_expect_read_count "${stats}" 2
19482
19483         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19484                 error "cannot read '${file}'"
19485         oal_expect_read_count "${stats}" 3
19486
19487         do_facet ost1 lctl set_param "${param}=w"
19488         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19489                 error "cannot create '${file}'"
19490         oal_expect_read_count "${stats}" 4
19491
19492         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19493                 error "cannot read '${file}'"
19494         oal_expect_read_count "${stats}" 4
19495
19496         do_facet ost1 lctl set_param "${param}=0"
19497         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19498                 error "cannot create '${file}'"
19499         oal_expect_read_count "${stats}" 4
19500
19501         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19502                 error "cannot read '${file}'"
19503         oal_expect_read_count "${stats}" 4
19504
19505         do_facet ost1 killall -TERM ofd_access_log_reader
19506         wait
19507         rc=$?
19508         if ((rc != 0)); then
19509                 error "ofd_access_log_reader exited with rc = '${rc}'"
19510         fi
19511 }
19512 run_test 165d "ofd_access_log mask works"
19513
19514 test_165e() {
19515         local stats="/tmp/${tfile}.stats"
19516         local file0="${DIR}/${tdir}-0/${tfile}"
19517         local file1="${DIR}/${tdir}-1/${tfile}"
19518
19519         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19520                 skip "OFD access log unsupported"
19521
19522         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19523
19524         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19525         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19526
19527         lfs setstripe -c 1 -i 0 "${file0}"
19528         lfs setstripe -c 1 -i 0 "${file1}"
19529
19530         setup_165
19531         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19532         sleep 5
19533
19534         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19535                 error "cannot create '${file0}'"
19536         sync
19537         oal_expect_read_count "${stats}" 0
19538
19539         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19540                 error "cannot create '${file1}'"
19541         sync
19542         oal_expect_read_count "${stats}" 1
19543
19544         do_facet ost1 killall -TERM ofd_access_log_reader
19545         wait
19546         rc=$?
19547         if ((rc != 0)); then
19548                 error "ofd_access_log_reader exited with rc = '${rc}'"
19549         fi
19550 }
19551 run_test 165e "ofd_access_log MDT index filter works"
19552
19553 test_165f() {
19554         local trace="/tmp/${tfile}.trace"
19555         local rc
19556         local count
19557
19558         setup_165
19559         do_facet ost1 timeout 60 ofd_access_log_reader \
19560                 --exit-on-close --debug=- --trace=- > "${trace}" &
19561         sleep 5
19562         stop ost1
19563
19564         wait
19565         rc=$?
19566
19567         if ((rc != 0)); then
19568                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19569                 cat "${trace}"
19570                 exit 1
19571         fi
19572 }
19573 run_test 165f "ofd_access_log_reader --exit-on-close works"
19574
19575 test_169() {
19576         # do directio so as not to populate the page cache
19577         log "creating a 10 Mb file"
19578         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19579                 error "multiop failed while creating a file"
19580         log "starting reads"
19581         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19582         log "truncating the file"
19583         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19584                 error "multiop failed while truncating the file"
19585         log "killing dd"
19586         kill %+ || true # reads might have finished
19587         echo "wait until dd is finished"
19588         wait
19589         log "removing the temporary file"
19590         rm -rf $DIR/$tfile || error "tmp file removal failed"
19591 }
19592 run_test 169 "parallel read and truncate should not deadlock"
19593
19594 test_170() {
19595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19596
19597         $LCTL clear     # bug 18514
19598         $LCTL debug_daemon start $TMP/${tfile}_log_good
19599         touch $DIR/$tfile
19600         $LCTL debug_daemon stop
19601         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19602                 error "sed failed to read log_good"
19603
19604         $LCTL debug_daemon start $TMP/${tfile}_log_good
19605         rm -rf $DIR/$tfile
19606         $LCTL debug_daemon stop
19607
19608         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19609                error "lctl df log_bad failed"
19610
19611         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19612         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19613
19614         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19615         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19616
19617         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19618                 error "bad_line good_line1 good_line2 are empty"
19619
19620         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19621         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19622         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19623
19624         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19625         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19626         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19627
19628         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19629                 error "bad_line_new good_line_new are empty"
19630
19631         local expected_good=$((good_line1 + good_line2*2))
19632
19633         rm -f $TMP/${tfile}*
19634         # LU-231, short malformed line may not be counted into bad lines
19635         if [ $bad_line -ne $bad_line_new ] &&
19636                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19637                 error "expected $bad_line bad lines, but got $bad_line_new"
19638                 return 1
19639         fi
19640
19641         if [ $expected_good -ne $good_line_new ]; then
19642                 error "expected $expected_good good lines, but got $good_line_new"
19643                 return 2
19644         fi
19645         true
19646 }
19647 run_test 170 "test lctl df to handle corrupted log ====================="
19648
19649 test_171() { # bug20592
19650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19651
19652         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19653         $LCTL set_param fail_loc=0x50e
19654         $LCTL set_param fail_val=3000
19655         multiop_bg_pause $DIR/$tfile O_s || true
19656         local MULTIPID=$!
19657         kill -USR1 $MULTIPID
19658         # cause log dump
19659         sleep 3
19660         wait $MULTIPID
19661         if dmesg | grep "recursive fault"; then
19662                 error "caught a recursive fault"
19663         fi
19664         $LCTL set_param fail_loc=0
19665         true
19666 }
19667 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19668
19669 test_172() {
19670
19671         #define OBD_FAIL_OBD_CLEANUP  0x60e
19672         $LCTL set_param fail_loc=0x60e
19673         umount $MOUNT || error "umount $MOUNT failed"
19674         stack_trap "mount_client $MOUNT"
19675
19676         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19677                 error "no client OBDs are remained"
19678
19679         $LCTL dl | while read devno state type name foo; do
19680                 case $type in
19681                 lov|osc|lmv|mdc)
19682                         $LCTL --device $name cleanup
19683                         $LCTL --device $name detach
19684                         ;;
19685                 *)
19686                         # skip server devices
19687                         ;;
19688                 esac
19689         done
19690
19691         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19692                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19693                 error "some client OBDs are still remained"
19694         fi
19695
19696 }
19697 run_test 172 "manual device removal with lctl cleanup/detach ======"
19698
19699 # it would be good to share it with obdfilter-survey/iokit-libecho code
19700 setup_obdecho_osc () {
19701         local rc=0
19702         local ost_nid=$1
19703         local obdfilter_name=$2
19704         echo "Creating new osc for $obdfilter_name on $ost_nid"
19705         # make sure we can find loopback nid
19706         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19707
19708         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19709                            ${obdfilter_name}_osc_UUID || rc=2; }
19710         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19711                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19712         return $rc
19713 }
19714
19715 cleanup_obdecho_osc () {
19716         local obdfilter_name=$1
19717         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19718         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19719         return 0
19720 }
19721
19722 obdecho_test() {
19723         local OBD=$1
19724         local node=$2
19725         local pages=${3:-64}
19726         local rc=0
19727         local id
19728
19729         local count=10
19730         local obd_size=$(get_obd_size $node $OBD)
19731         local page_size=$(get_page_size $node)
19732         if [[ -n "$obd_size" ]]; then
19733                 local new_count=$((obd_size / (pages * page_size / 1024)))
19734                 [[ $new_count -ge $count ]] || count=$new_count
19735         fi
19736
19737         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19738         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19739                            rc=2; }
19740         if [ $rc -eq 0 ]; then
19741             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19742             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19743         fi
19744         echo "New object id is $id"
19745         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19746                            rc=4; }
19747         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19748                            "test_brw $count w v $pages $id" || rc=4; }
19749         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19750                            rc=4; }
19751         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19752                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19753         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19754                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19755         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19756         return $rc
19757 }
19758
19759 test_180a() {
19760         skip "obdecho on osc is no longer supported"
19761 }
19762 run_test 180a "test obdecho on osc"
19763
19764 test_180b() {
19765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19766         remote_ost_nodsh && skip "remote OST with nodsh"
19767
19768         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19769                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19770                 error "failed to load module obdecho"
19771
19772         local target=$(do_facet ost1 $LCTL dl |
19773                        awk '/obdfilter/ { print $4; exit; }')
19774
19775         if [ -n "$target" ]; then
19776                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19777         else
19778                 do_facet ost1 $LCTL dl
19779                 error "there is no obdfilter target on ost1"
19780         fi
19781 }
19782 run_test 180b "test obdecho directly on obdfilter"
19783
19784 test_180c() { # LU-2598
19785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19786         remote_ost_nodsh && skip "remote OST with nodsh"
19787         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19788                 skip "Need MDS version at least 2.4.0"
19789
19790         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19791                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19792                 error "failed to load module obdecho"
19793
19794         local target=$(do_facet ost1 $LCTL dl |
19795                        awk '/obdfilter/ { print $4; exit; }')
19796
19797         if [ -n "$target" ]; then
19798                 local pages=16384 # 64MB bulk I/O RPC size
19799
19800                 obdecho_test "$target" ost1 "$pages" ||
19801                         error "obdecho_test with pages=$pages failed with $?"
19802         else
19803                 do_facet ost1 $LCTL dl
19804                 error "there is no obdfilter target on ost1"
19805         fi
19806 }
19807 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19808
19809 test_181() { # bug 22177
19810         test_mkdir $DIR/$tdir
19811         # create enough files to index the directory
19812         createmany -o $DIR/$tdir/foobar 4000
19813         # print attributes for debug purpose
19814         lsattr -d .
19815         # open dir
19816         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19817         MULTIPID=$!
19818         # remove the files & current working dir
19819         unlinkmany $DIR/$tdir/foobar 4000
19820         rmdir $DIR/$tdir
19821         kill -USR1 $MULTIPID
19822         wait $MULTIPID
19823         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19824         return 0
19825 }
19826 run_test 181 "Test open-unlinked dir ========================"
19827
19828 test_182a() {
19829         local fcount=1000
19830         local tcount=10
19831
19832         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19833
19834         $LCTL set_param mdc.*.rpc_stats=clear
19835
19836         for (( i = 0; i < $tcount; i++ )) ; do
19837                 mkdir $DIR/$tdir/$i
19838         done
19839
19840         for (( i = 0; i < $tcount; i++ )) ; do
19841                 createmany -o $DIR/$tdir/$i/f- $fcount &
19842         done
19843         wait
19844
19845         for (( i = 0; i < $tcount; i++ )) ; do
19846                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19847         done
19848         wait
19849
19850         $LCTL get_param mdc.*.rpc_stats
19851
19852         rm -rf $DIR/$tdir
19853 }
19854 run_test 182a "Test parallel modify metadata operations from mdc"
19855
19856 test_182b() {
19857         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19858         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19859         local dcount=1000
19860         local tcount=10
19861         local stime
19862         local etime
19863         local delta
19864
19865         do_facet mds1 $LCTL list_param \
19866                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19867                 skip "MDS lacks parallel RPC handling"
19868
19869         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19870
19871         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19872                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19873
19874         stime=$(date +%s)
19875         createmany -i 0 -d $DIR/$tdir/t- $tcount
19876
19877         for (( i = 0; i < $tcount; i++ )) ; do
19878                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19879         done
19880         wait
19881         etime=$(date +%s)
19882         delta=$((etime - stime))
19883         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19884
19885         stime=$(date +%s)
19886         for (( i = 0; i < $tcount; i++ )) ; do
19887                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19888         done
19889         wait
19890         etime=$(date +%s)
19891         delta=$((etime - stime))
19892         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19893
19894         rm -rf $DIR/$tdir
19895
19896         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19897
19898         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19899
19900         stime=$(date +%s)
19901         createmany -i 0 -d $DIR/$tdir/t- $tcount
19902
19903         for (( i = 0; i < $tcount; i++ )) ; do
19904                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19905         done
19906         wait
19907         etime=$(date +%s)
19908         delta=$((etime - stime))
19909         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19910
19911         stime=$(date +%s)
19912         for (( i = 0; i < $tcount; i++ )) ; do
19913                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19914         done
19915         wait
19916         etime=$(date +%s)
19917         delta=$((etime - stime))
19918         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19919
19920         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19921 }
19922 run_test 182b "Test parallel modify metadata operations from osp"
19923
19924 test_183() { # LU-2275
19925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19926         remote_mds_nodsh && skip "remote MDS with nodsh"
19927         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19928                 skip "Need MDS version at least 2.3.56"
19929
19930         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19931         echo aaa > $DIR/$tdir/$tfile
19932
19933 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19934         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19935
19936         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19937         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19938
19939         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19940
19941         # Flush negative dentry cache
19942         touch $DIR/$tdir/$tfile
19943
19944         # We are not checking for any leaked references here, they'll
19945         # become evident next time we do cleanup with module unload.
19946         rm -rf $DIR/$tdir
19947 }
19948 run_test 183 "No crash or request leak in case of strange dispositions ========"
19949
19950 # test suite 184 is for LU-2016, LU-2017
19951 test_184a() {
19952         check_swap_layouts_support
19953
19954         dir0=$DIR/$tdir/$testnum
19955         test_mkdir -p -c1 $dir0
19956         ref1=/etc/passwd
19957         ref2=/etc/group
19958         file1=$dir0/f1
19959         file2=$dir0/f2
19960         $LFS setstripe -c1 $file1
19961         cp $ref1 $file1
19962         $LFS setstripe -c2 $file2
19963         cp $ref2 $file2
19964         gen1=$($LFS getstripe -g $file1)
19965         gen2=$($LFS getstripe -g $file2)
19966
19967         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19968         gen=$($LFS getstripe -g $file1)
19969         [[ $gen1 != $gen ]] ||
19970                 error "Layout generation on $file1 does not change"
19971         gen=$($LFS getstripe -g $file2)
19972         [[ $gen2 != $gen ]] ||
19973                 error "Layout generation on $file2 does not change"
19974
19975         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19976         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19977
19978         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19979 }
19980 run_test 184a "Basic layout swap"
19981
19982 test_184b() {
19983         check_swap_layouts_support
19984
19985         dir0=$DIR/$tdir/$testnum
19986         mkdir -p $dir0 || error "creating dir $dir0"
19987         file1=$dir0/f1
19988         file2=$dir0/f2
19989         file3=$dir0/f3
19990         dir1=$dir0/d1
19991         dir2=$dir0/d2
19992         mkdir $dir1 $dir2
19993         $LFS setstripe -c1 $file1
19994         $LFS setstripe -c2 $file2
19995         $LFS setstripe -c1 $file3
19996         chown $RUNAS_ID $file3
19997         gen1=$($LFS getstripe -g $file1)
19998         gen2=$($LFS getstripe -g $file2)
19999
20000         $LFS swap_layouts $dir1 $dir2 &&
20001                 error "swap of directories layouts should fail"
20002         $LFS swap_layouts $dir1 $file1 &&
20003                 error "swap of directory and file layouts should fail"
20004         $RUNAS $LFS swap_layouts $file1 $file2 &&
20005                 error "swap of file we cannot write should fail"
20006         $LFS swap_layouts $file1 $file3 &&
20007                 error "swap of file with different owner should fail"
20008         /bin/true # to clear error code
20009 }
20010 run_test 184b "Forbidden layout swap (will generate errors)"
20011
20012 test_184c() {
20013         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
20014         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
20015         check_swap_layouts_support
20016         check_swap_layout_no_dom $DIR
20017
20018         local dir0=$DIR/$tdir/$testnum
20019         mkdir -p $dir0 || error "creating dir $dir0"
20020
20021         local ref1=$dir0/ref1
20022         local ref2=$dir0/ref2
20023         local file1=$dir0/file1
20024         local file2=$dir0/file2
20025         # create a file large enough for the concurrent test
20026         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
20027         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
20028         echo "ref file size: ref1($(stat -c %s $ref1))," \
20029              "ref2($(stat -c %s $ref2))"
20030
20031         cp $ref2 $file2
20032         dd if=$ref1 of=$file1 bs=16k &
20033         local DD_PID=$!
20034
20035         # Make sure dd starts to copy file, but wait at most 5 seconds
20036         local loops=0
20037         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
20038
20039         $LFS swap_layouts $file1 $file2
20040         local rc=$?
20041         wait $DD_PID
20042         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
20043         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
20044
20045         # how many bytes copied before swapping layout
20046         local copied=$(stat -c %s $file2)
20047         local remaining=$(stat -c %s $ref1)
20048         remaining=$((remaining - copied))
20049         echo "Copied $copied bytes before swapping layout..."
20050
20051         cmp -n $copied $file1 $ref2 | grep differ &&
20052                 error "Content mismatch [0, $copied) of ref2 and file1"
20053         cmp -n $copied $file2 $ref1 ||
20054                 error "Content mismatch [0, $copied) of ref1 and file2"
20055         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
20056                 error "Content mismatch [$copied, EOF) of ref1 and file1"
20057
20058         # clean up
20059         rm -f $ref1 $ref2 $file1 $file2
20060 }
20061 run_test 184c "Concurrent write and layout swap"
20062
20063 test_184d() {
20064         check_swap_layouts_support
20065         check_swap_layout_no_dom $DIR
20066         [ -z "$(which getfattr 2>/dev/null)" ] &&
20067                 skip_env "no getfattr command"
20068
20069         local file1=$DIR/$tdir/$tfile-1
20070         local file2=$DIR/$tdir/$tfile-2
20071         local file3=$DIR/$tdir/$tfile-3
20072         local lovea1
20073         local lovea2
20074
20075         mkdir -p $DIR/$tdir
20076         touch $file1 || error "create $file1 failed"
20077         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20078                 error "create $file2 failed"
20079         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20080                 error "create $file3 failed"
20081         lovea1=$(get_layout_param $file1)
20082
20083         $LFS swap_layouts $file2 $file3 ||
20084                 error "swap $file2 $file3 layouts failed"
20085         $LFS swap_layouts $file1 $file2 ||
20086                 error "swap $file1 $file2 layouts failed"
20087
20088         lovea2=$(get_layout_param $file2)
20089         echo "$lovea1"
20090         echo "$lovea2"
20091         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20092
20093         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20094         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20095 }
20096 run_test 184d "allow stripeless layouts swap"
20097
20098 test_184e() {
20099         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20100                 skip "Need MDS version at least 2.6.94"
20101         check_swap_layouts_support
20102         check_swap_layout_no_dom $DIR
20103         [ -z "$(which getfattr 2>/dev/null)" ] &&
20104                 skip_env "no getfattr command"
20105
20106         local file1=$DIR/$tdir/$tfile-1
20107         local file2=$DIR/$tdir/$tfile-2
20108         local file3=$DIR/$tdir/$tfile-3
20109         local lovea
20110
20111         mkdir -p $DIR/$tdir
20112         touch $file1 || error "create $file1 failed"
20113         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20114                 error "create $file2 failed"
20115         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20116                 error "create $file3 failed"
20117
20118         $LFS swap_layouts $file1 $file2 ||
20119                 error "swap $file1 $file2 layouts failed"
20120
20121         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20122         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20123
20124         echo 123 > $file1 || error "Should be able to write into $file1"
20125
20126         $LFS swap_layouts $file1 $file3 ||
20127                 error "swap $file1 $file3 layouts failed"
20128
20129         echo 123 > $file1 || error "Should be able to write into $file1"
20130
20131         rm -rf $file1 $file2 $file3
20132 }
20133 run_test 184e "Recreate layout after stripeless layout swaps"
20134
20135 test_184f() {
20136         # Create a file with name longer than sizeof(struct stat) ==
20137         # 144 to see if we can get chars from the file name to appear
20138         # in the returned striping. Note that 'f' == 0x66.
20139         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20140
20141         mkdir -p $DIR/$tdir
20142         mcreate $DIR/$tdir/$file
20143         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20144                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20145         fi
20146 }
20147 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20148
20149 test_185() { # LU-2441
20150         # LU-3553 - no volatile file support in old servers
20151         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20152                 skip "Need MDS version at least 2.3.60"
20153
20154         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20155         touch $DIR/$tdir/spoo
20156         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20157         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20158                 error "cannot create/write a volatile file"
20159         [ "$FILESET" == "" ] &&
20160         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20161                 error "FID is still valid after close"
20162
20163         multiop_bg_pause $DIR/$tdir Vw4096_c
20164         local multi_pid=$!
20165
20166         local OLD_IFS=$IFS
20167         IFS=":"
20168         local fidv=($fid)
20169         IFS=$OLD_IFS
20170         # assume that the next FID for this client is sequential, since stdout
20171         # is unfortunately eaten by multiop_bg_pause
20172         local n=$((${fidv[1]} + 1))
20173         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20174         if [ "$FILESET" == "" ]; then
20175                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20176                         error "FID is missing before close"
20177         fi
20178         kill -USR1 $multi_pid
20179         # 1 second delay, so if mtime change we will see it
20180         sleep 1
20181         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20182         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20183 }
20184 run_test 185 "Volatile file support"
20185
20186 function create_check_volatile() {
20187         local idx=$1
20188         local tgt
20189
20190         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20191         local PID=$!
20192         sleep 1
20193         local FID=$(cat /tmp/${tfile}.fid)
20194         [ "$FID" == "" ] && error "can't get FID for volatile"
20195         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20196         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20197         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20198         kill -USR1 $PID
20199         wait
20200         sleep 1
20201         cancel_lru_locks mdc # flush opencache
20202         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20203         return 0
20204 }
20205
20206 test_185a(){
20207         # LU-12516 - volatile creation via .lustre
20208         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20209                 skip "Need MDS version at least 2.3.55"
20210
20211         create_check_volatile 0
20212         [ $MDSCOUNT -lt 2 ] && return 0
20213
20214         # DNE case
20215         create_check_volatile 1
20216
20217         return 0
20218 }
20219 run_test 185a "Volatile file creation in .lustre/fid/"
20220
20221 test_187a() {
20222         remote_mds_nodsh && skip "remote MDS with nodsh"
20223         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20224                 skip "Need MDS version at least 2.3.0"
20225
20226         local dir0=$DIR/$tdir/$testnum
20227         mkdir -p $dir0 || error "creating dir $dir0"
20228
20229         local file=$dir0/file1
20230         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20231         stack_trap "rm -f $file"
20232         local dv1=$($LFS data_version $file)
20233         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20234         local dv2=$($LFS data_version $file)
20235         [[ $dv1 != $dv2 ]] ||
20236                 error "data version did not change on write $dv1 == $dv2"
20237 }
20238 run_test 187a "Test data version change"
20239
20240 test_187b() {
20241         remote_mds_nodsh && skip "remote MDS with nodsh"
20242         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20243                 skip "Need MDS version at least 2.3.0"
20244
20245         local dir0=$DIR/$tdir/$testnum
20246         mkdir -p $dir0 || error "creating dir $dir0"
20247
20248         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20249         [[ ${DV[0]} != ${DV[1]} ]] ||
20250                 error "data version did not change on write"\
20251                       " ${DV[0]} == ${DV[1]}"
20252
20253         # clean up
20254         rm -f $file1
20255 }
20256 run_test 187b "Test data version change on volatile file"
20257
20258 test_200() {
20259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20260         remote_mgs_nodsh && skip "remote MGS with nodsh"
20261         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20262
20263         local POOL=${POOL:-cea1}
20264         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20265         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20266         # Pool OST targets
20267         local first_ost=0
20268         local last_ost=$(($OSTCOUNT - 1))
20269         local ost_step=2
20270         local ost_list=$(seq $first_ost $ost_step $last_ost)
20271         local ost_range="$first_ost $last_ost $ost_step"
20272         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20273         local file_dir=$POOL_ROOT/file_tst
20274         local subdir=$test_path/subdir
20275         local rc=0
20276
20277         while : ; do
20278                 # former test_200a test_200b
20279                 pool_add $POOL                          || { rc=$? ; break; }
20280                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20281                 # former test_200c test_200d
20282                 mkdir -p $test_path
20283                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20284                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20285                 mkdir -p $subdir
20286                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20287                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20288                                                         || { rc=$? ; break; }
20289                 # former test_200e test_200f
20290                 local files=$((OSTCOUNT*3))
20291                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20292                                                         || { rc=$? ; break; }
20293                 pool_create_files $POOL $file_dir $files "$ost_list" \
20294                                                         || { rc=$? ; break; }
20295                 # former test_200g test_200h
20296                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20297                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20298
20299                 # former test_201a test_201b test_201c
20300                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20301
20302                 local f=$test_path/$tfile
20303                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20304                 pool_remove $POOL $f                    || { rc=$? ; break; }
20305                 break
20306         done
20307
20308         destroy_test_pools
20309
20310         return $rc
20311 }
20312 run_test 200 "OST pools"
20313
20314 # usage: default_attr <count | size | offset>
20315 default_attr() {
20316         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20317 }
20318
20319 # usage: check_default_stripe_attr
20320 check_default_stripe_attr() {
20321         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20322         case $1 in
20323         --stripe-count|-c)
20324                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20325         --stripe-size|-S)
20326                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20327         --stripe-index|-i)
20328                 EXPECTED=-1;;
20329         *)
20330                 error "unknown getstripe attr '$1'"
20331         esac
20332
20333         [ $ACTUAL == $EXPECTED ] ||
20334                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20335 }
20336
20337 test_204a() {
20338         test_mkdir $DIR/$tdir
20339         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20340
20341         check_default_stripe_attr --stripe-count
20342         check_default_stripe_attr --stripe-size
20343         check_default_stripe_attr --stripe-index
20344 }
20345 run_test 204a "Print default stripe attributes"
20346
20347 test_204b() {
20348         test_mkdir $DIR/$tdir
20349         $LFS setstripe --stripe-count 1 $DIR/$tdir
20350
20351         check_default_stripe_attr --stripe-size
20352         check_default_stripe_attr --stripe-index
20353 }
20354 run_test 204b "Print default stripe size and offset"
20355
20356 test_204c() {
20357         test_mkdir $DIR/$tdir
20358         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20359
20360         check_default_stripe_attr --stripe-count
20361         check_default_stripe_attr --stripe-index
20362 }
20363 run_test 204c "Print default stripe count and offset"
20364
20365 test_204d() {
20366         test_mkdir $DIR/$tdir
20367         $LFS setstripe --stripe-index 0 $DIR/$tdir
20368
20369         check_default_stripe_attr --stripe-count
20370         check_default_stripe_attr --stripe-size
20371 }
20372 run_test 204d "Print default stripe count and size"
20373
20374 test_204e() {
20375         test_mkdir $DIR/$tdir
20376         $LFS setstripe -d $DIR/$tdir
20377
20378         # LU-16904 check if root is set as PFL layout
20379         local numcomp=$($LFS getstripe --component-count $MOUNT)
20380
20381         if [[ $numcomp -gt 0 ]]; then
20382                 check_default_stripe_attr --stripe-count
20383         else
20384                 check_default_stripe_attr --stripe-count --raw
20385         fi
20386         check_default_stripe_attr --stripe-size --raw
20387         check_default_stripe_attr --stripe-index --raw
20388 }
20389 run_test 204e "Print raw stripe attributes"
20390
20391 test_204f() {
20392         test_mkdir $DIR/$tdir
20393         $LFS setstripe --stripe-count 1 $DIR/$tdir
20394
20395         check_default_stripe_attr --stripe-size --raw
20396         check_default_stripe_attr --stripe-index --raw
20397 }
20398 run_test 204f "Print raw stripe size and offset"
20399
20400 test_204g() {
20401         test_mkdir $DIR/$tdir
20402         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20403
20404         check_default_stripe_attr --stripe-count --raw
20405         check_default_stripe_attr --stripe-index --raw
20406 }
20407 run_test 204g "Print raw stripe count and offset"
20408
20409 test_204h() {
20410         test_mkdir $DIR/$tdir
20411         $LFS setstripe --stripe-index 0 $DIR/$tdir
20412
20413         check_default_stripe_attr --stripe-count --raw
20414         check_default_stripe_attr --stripe-size --raw
20415 }
20416 run_test 204h "Print raw stripe count and size"
20417
20418 # Figure out which job scheduler is being used, if any,
20419 # or use a fake one
20420 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20421         JOBENV=SLURM_JOB_ID
20422 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20423         JOBENV=LSB_JOBID
20424 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20425         JOBENV=PBS_JOBID
20426 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20427         JOBENV=LOADL_STEP_ID
20428 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20429         JOBENV=JOB_ID
20430 else
20431         $LCTL list_param jobid_name > /dev/null 2>&1
20432         if [ $? -eq 0 ]; then
20433                 JOBENV=nodelocal
20434         else
20435                 JOBENV=FAKE_JOBID
20436         fi
20437 fi
20438 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20439
20440 verify_jobstats() {
20441         local cmd=($1)
20442         shift
20443         local facets="$@"
20444
20445 # we don't really need to clear the stats for this test to work, since each
20446 # command has a unique jobid, but it makes debugging easier if needed.
20447 #       for facet in $facets; do
20448 #               local dev=$(convert_facet2label $facet)
20449 #               # clear old jobstats
20450 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20451 #       done
20452
20453         # use a new JobID for each test, or we might see an old one
20454         [ "$JOBENV" = "FAKE_JOBID" ] &&
20455                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20456
20457         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20458
20459         [ "$JOBENV" = "nodelocal" ] && {
20460                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20461                 $LCTL set_param jobid_name=$FAKE_JOBID
20462                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20463         }
20464
20465         log "Test: ${cmd[*]}"
20466         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20467
20468         if [ $JOBENV = "FAKE_JOBID" ]; then
20469                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20470         else
20471                 ${cmd[*]}
20472         fi
20473
20474         # all files are created on OST0000
20475         for facet in $facets; do
20476                 local stats="*.$(convert_facet2label $facet).job_stats"
20477
20478                 # strip out libtool wrappers for in-tree executables
20479                 if (( $(do_facet $facet lctl get_param $stats |
20480                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20481                         do_facet $facet lctl get_param $stats
20482                         error "No jobstats for $JOBVAL found on $facet::$stats"
20483                 fi
20484         done
20485 }
20486
20487 jobstats_set() {
20488         local new_jobenv=$1
20489
20490         set_persistent_param_and_check client "jobid_var" \
20491                 "$FSNAME.sys.jobid_var" $new_jobenv
20492 }
20493
20494 test_205a() { # Job stats
20495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20496         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20497                 skip "Need MDS version with at least 2.7.1"
20498         remote_mgs_nodsh && skip "remote MGS with nodsh"
20499         remote_mds_nodsh && skip "remote MDS with nodsh"
20500         remote_ost_nodsh && skip "remote OST with nodsh"
20501         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20502                 skip "Server doesn't support jobstats"
20503         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20504
20505         local old_jobenv=$($LCTL get_param -n jobid_var)
20506         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20507         stack_trap "jobstats_set $old_jobenv" EXIT
20508
20509         changelog_register
20510
20511         local old_jobid_name=$($LCTL get_param jobid_name)
20512         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20513
20514         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20515                                 mdt.*.job_cleanup_interval | head -n 1)
20516         local new_interval=5
20517         do_facet $SINGLEMDS \
20518                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20519         stack_trap "do_facet $SINGLEMDS \
20520                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20521         local start=$SECONDS
20522
20523         local cmd
20524         # mkdir
20525         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20526         verify_jobstats "$cmd" "$SINGLEMDS"
20527         # rmdir
20528         cmd="rmdir $DIR/$tdir"
20529         verify_jobstats "$cmd" "$SINGLEMDS"
20530         # mkdir on secondary MDT
20531         if [ $MDSCOUNT -gt 1 ]; then
20532                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20533                 verify_jobstats "$cmd" "mds2"
20534         fi
20535         # mknod
20536         cmd="mknod $DIR/$tfile c 1 3"
20537         verify_jobstats "$cmd" "$SINGLEMDS"
20538         # unlink
20539         cmd="rm -f $DIR/$tfile"
20540         verify_jobstats "$cmd" "$SINGLEMDS"
20541         # create all files on OST0000 so verify_jobstats can find OST stats
20542         # open & close
20543         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20544         verify_jobstats "$cmd" "$SINGLEMDS"
20545         # setattr
20546         cmd="touch $DIR/$tfile"
20547         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20548         # write
20549         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20550         verify_jobstats "$cmd" "ost1"
20551         # read
20552         cancel_lru_locks osc
20553         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20554         verify_jobstats "$cmd" "ost1"
20555         # truncate
20556         cmd="$TRUNCATE $DIR/$tfile 0"
20557         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20558         # rename
20559         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20560         verify_jobstats "$cmd" "$SINGLEMDS"
20561         # jobstats expiry - sleep until old stats should be expired
20562         local left=$((new_interval + 5 - (SECONDS - start)))
20563         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20564                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20565                         "0" $left
20566         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20567         verify_jobstats "$cmd" "$SINGLEMDS"
20568         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20569             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20570
20571         # Ensure that jobid are present in changelog (if supported by MDS)
20572         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20573                 changelog_dump | tail -10
20574                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20575                 [ $jobids -eq 9 ] ||
20576                         error "Wrong changelog jobid count $jobids != 9"
20577
20578                 # LU-5862
20579                 JOBENV="disable"
20580                 jobstats_set $JOBENV
20581                 touch $DIR/$tfile
20582                 changelog_dump | grep $tfile
20583                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20584                 [ $jobids -eq 0 ] ||
20585                         error "Unexpected jobids when jobid_var=$JOBENV"
20586         fi
20587
20588         # test '%j' access to environment variable - if supported
20589         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20590                 JOBENV="JOBCOMPLEX"
20591                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20592
20593                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20594         fi
20595
20596         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20597                 JOBENV="JOBCOMPLEX"
20598                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20599
20600                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20601         fi
20602
20603         # test '%j' access to per-session jobid - if supported
20604         if lctl list_param jobid_this_session > /dev/null 2>&1
20605         then
20606                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20607                 lctl set_param jobid_this_session=$USER
20608
20609                 JOBENV="JOBCOMPLEX"
20610                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20611
20612                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20613         fi
20614 }
20615 run_test 205a "Verify job stats"
20616
20617 # LU-13117, LU-13597, LU-16599
20618 test_205b() {
20619         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20620                 skip "Need MDS version at least 2.13.54.91"
20621
20622         local job_stats="mdt.*.job_stats"
20623         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20624
20625         do_facet mds1 $LCTL set_param $job_stats=clear
20626
20627         # Setting jobid_var to USER might not be supported
20628         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20629         $LCTL set_param jobid_var=USER || true
20630         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20631         $LCTL set_param jobid_name="%j.%e.%u"
20632
20633         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20634         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20635                 { do_facet mds1 $LCTL get_param $job_stats;
20636                   error "Unexpected jobid found"; }
20637         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20638                 { do_facet mds1 $LCTL get_param $job_stats;
20639                   error "wrong job_stats format found"; }
20640
20641         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20642                 echo "MDS does not yet escape jobid" && return 0
20643
20644         mkdir_on_mdt0 $DIR/$tdir
20645         $LCTL set_param jobid_var=TEST205b
20646         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20647         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20648                       awk '/has\\x20sp/ {print $3}')
20649         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20650                   error "jobid not escaped"; }
20651
20652         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20653                 # need to run such a command on mds1:
20654                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20655                 #
20656                 # there might be multiple MDTs on single mds server, so need to
20657                 # specifiy MDT0000. Or the command will fail due to other MDTs
20658                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20659                         error "cannot clear escaped jobid in job_stats";
20660         else
20661                 echo "MDS does not support clearing escaped jobid"
20662         fi
20663 }
20664 run_test 205b "Verify job stats jobid and output format"
20665
20666 # LU-13733
20667 test_205c() {
20668         $LCTL set_param llite.*.stats=0
20669         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20670         $LCTL get_param llite.*.stats
20671         $LCTL get_param llite.*.stats | grep \
20672                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20673                         error "wrong client stats format found"
20674 }
20675 run_test 205c "Verify client stats format"
20676
20677 test_205d() {
20678         local file=$DIR/$tdir/$tfile
20679
20680         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20681                 skip "need lustre >= 2.15.53 for lljobstat"
20682         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20683                 skip "need lustre >= 2.15.53 for lljobstat"
20684         verify_yaml_available || skip_env "YAML verification not installed"
20685
20686         test_mkdir -i 0 $DIR/$tdir
20687         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20688         stack_trap "rm -rf $DIR/$tdir"
20689
20690         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20691                 error "failed to write data to $file"
20692         mv $file $file.2
20693
20694         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20695         echo -n 'verify rename_stats...'
20696         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20697                 verify_yaml || error "rename_stats is not valid YAML"
20698         echo " OK"
20699
20700         echo -n 'verify mdt job_stats...'
20701         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20702                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20703         echo " OK"
20704
20705         echo -n 'verify ost job_stats...'
20706         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20707                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20708         echo " OK"
20709 }
20710 run_test 205d "verify the format of some stats files"
20711
20712 test_205e() {
20713         local ops_comma
20714         local file=$DIR/$tdir/$tfile
20715         local -a cli_params
20716
20717         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20718                 skip "need lustre >= 2.15.53 for lljobstat"
20719         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20720                 skip "need lustre >= 2.15.53 for lljobstat"
20721         verify_yaml_available || skip_env "YAML verification not installed"
20722
20723         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20724         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20725         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20726
20727         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20728         stack_trap "rm -rf $DIR/$tdir"
20729
20730         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20731                 error "failed to create $file on ost1"
20732         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20733                 error "failed to write data to $file"
20734
20735         do_facet mds1 "$LCTL get_param *.*.job_stats"
20736         do_facet ost1 "$LCTL get_param *.*.job_stats"
20737
20738         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20739         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20740                 error "The output of lljobstat is not an valid YAML"
20741
20742         # verify that job dd.0 does exist and has some ops on ost1
20743         # typically this line is like:
20744         # - 205e.dd.0:            {ops: 20, ...}
20745         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20746                     awk '$2=="205e.dd.0:" {print $4}')
20747
20748         (( ${ops_comma%,} >= 10 )) ||
20749                 error "cannot find job 205e.dd.0 with ops >= 10"
20750 }
20751 run_test 205e "verify the output of lljobstat"
20752
20753 test_205f() {
20754         verify_yaml_available || skip_env "YAML verification not installed"
20755
20756         # check both qos_ost_weights and qos_mdt_weights
20757         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20758         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20759                 error "qos_ost_weights is not valid YAML"
20760 }
20761 run_test 205f "verify qos_ost_weights YAML format "
20762
20763 __test_205_jobstats_dump() {
20764         local -a pids
20765         local nbr_instance=$1
20766
20767         while true; do
20768                 if (( ${#pids[@]} >= nbr_instance )); then
20769                         wait ${pids[@]}
20770                         pids=()
20771                 fi
20772
20773                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20774                 pids+=( $! )
20775         done
20776 }
20777
20778 __test_205_cleanup() {
20779         kill $@
20780         # Clear all job entries
20781         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20782 }
20783
20784 test_205g() {
20785         local -a mds1_params
20786         local -a cli_params
20787         local pids
20788         local interval=5
20789
20790         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20791         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20792         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20793
20794         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20795         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20796         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20797
20798         # start jobs loop
20799         export TEST205G_ID=205g
20800         stack_trap "unset TEST205G_ID" EXIT
20801         while true; do
20802                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20803         done & pids="$! "
20804
20805         __test_205_jobstats_dump 4 & pids+="$! "
20806         stack_trap "__test_205_cleanup $pids" EXIT INT
20807
20808         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20809 }
20810 run_test 205g "stress test for job_stats procfile"
20811
20812 test_205h() {
20813         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20814                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20815         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20816
20817         local dir=$DIR/$tdir
20818         local f=$dir/$tfile
20819         local f2=$dir/$tfile-2
20820         local f3=$dir/$tfile-3
20821         local subdir=$DIR/dir
20822         local val
20823
20824         local mdts=$(comma_list $(mdts_nodes))
20825         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20826         local client_saved=$($LCTL get_param -n jobid_var)
20827
20828         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20829         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20830
20831         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20832                 error "failed to set job_xattr parameter to user.job"
20833         $LCTL set_param jobid_var=procname.uid ||
20834                 error "failed to set jobid_var parameter"
20835
20836         test_mkdir $dir
20837
20838         touch $f
20839         val=$(getfattr -n user.job $f | grep user.job)
20840         [[ $val = user.job=\"touch.0\" ]] ||
20841                 error "expected user.job=\"touch.0\", got '$val'"
20842
20843         mkdir $subdir
20844         val=$(getfattr -n user.job $subdir | grep user.job)
20845         [[ $val = user.job=\"mkdir.0\" ]] ||
20846                 error "expected user.job=\"mkdir.0\", got '$val'"
20847
20848         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20849                 error "failed to set job_xattr parameter to NONE"
20850
20851         touch $f2
20852         val=$(getfattr -d $f2)
20853         [[ -z $val ]] ||
20854                 error "expected no user xattr, got '$val'"
20855
20856         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20857                 error "failed to set job_xattr parameter to trusted.job"
20858
20859         touch $f3
20860         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20861         [[ $val = trusted.job=\"touch.0\" ]] ||
20862                 error "expected trusted.job=\"touch.0\", got '$val'"
20863 }
20864 run_test 205h "check jobid xattr is stored correctly"
20865
20866 test_205i() {
20867         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20868                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20869
20870         local mdts=$(comma_list $(mdts_nodes))
20871         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20872
20873         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20874
20875         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20876                 error "failed to set mdt.*.job_xattr to user.1234567"
20877
20878         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20879                 error "failed to reject too long job_xattr name"
20880
20881         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20882                 error "failed to reject job_xattr name in bad format"
20883
20884         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20885                 error "failed to reject job_xattr name with invalid character"
20886
20887         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20888                         xargs $LCTL set_param" &&
20889                 error "failed to reject job_xattr name with non-ascii character"
20890
20891         return 0
20892 }
20893 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20894
20895 # LU-1480, LU-1773 and LU-1657
20896 test_206() {
20897         mkdir -p $DIR/$tdir
20898         $LFS setstripe -c -1 $DIR/$tdir
20899 #define OBD_FAIL_LOV_INIT 0x1403
20900         $LCTL set_param fail_loc=0xa0001403
20901         $LCTL set_param fail_val=1
20902         touch $DIR/$tdir/$tfile || true
20903 }
20904 run_test 206 "fail lov_init_raid0() doesn't lbug"
20905
20906 test_207a() {
20907         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20908         local fsz=`stat -c %s $DIR/$tfile`
20909         cancel_lru_locks mdc
20910
20911         # do not return layout in getattr intent
20912 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20913         $LCTL set_param fail_loc=0x170
20914         local sz=`stat -c %s $DIR/$tfile`
20915
20916         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20917
20918         rm -rf $DIR/$tfile
20919 }
20920 run_test 207a "can refresh layout at glimpse"
20921
20922 test_207b() {
20923         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20924         local cksum=`md5sum $DIR/$tfile`
20925         local fsz=`stat -c %s $DIR/$tfile`
20926         cancel_lru_locks mdc
20927         cancel_lru_locks osc
20928
20929         # do not return layout in getattr intent
20930 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20931         $LCTL set_param fail_loc=0x171
20932
20933         # it will refresh layout after the file is opened but before read issues
20934         echo checksum is "$cksum"
20935         echo "$cksum" |md5sum -c --quiet || error "file differs"
20936
20937         rm -rf $DIR/$tfile
20938 }
20939 run_test 207b "can refresh layout at open"
20940
20941 test_208() {
20942         # FIXME: in this test suite, only RD lease is used. This is okay
20943         # for now as only exclusive open is supported. After generic lease
20944         # is done, this test suite should be revised. - Jinshan
20945
20946         remote_mds_nodsh && skip "remote MDS with nodsh"
20947         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20948                 skip "Need MDS version at least 2.4.52"
20949
20950         echo "==== test 1: verify get lease work"
20951         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20952
20953         echo "==== test 2: verify lease can be broken by upcoming open"
20954         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20955         local PID=$!
20956         sleep 2
20957
20958         $MULTIOP $DIR/$tfile oO_RDWR:c
20959         kill -USR1 $PID && wait $PID || error "break lease error"
20960
20961         echo "==== test 3: verify lease can't be granted if an open already exists"
20962         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20963         local PID=$!
20964         sleep 2
20965
20966         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20967         kill -USR1 $PID && wait $PID || error "open file error"
20968
20969         echo "==== test 4: lease can sustain over recovery"
20970         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20971         PID=$!
20972         sleep 2
20973
20974         fail mds1
20975
20976         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20977
20978         echo "==== test 5: lease broken can't be regained by replay"
20979         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20980         PID=$!
20981         sleep 2
20982
20983         # open file to break lease and then recovery
20984         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20985         fail mds1
20986
20987         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20988
20989         rm -f $DIR/$tfile
20990 }
20991 run_test 208 "Exclusive open"
20992
20993 test_209() {
20994         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20995                 skip_env "must have disp_stripe"
20996
20997         touch $DIR/$tfile
20998         sync; sleep 5; sync;
20999
21000         echo 3 > /proc/sys/vm/drop_caches
21001         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21002                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21003         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21004
21005         # open/close 500 times
21006         for i in $(seq 500); do
21007                 cat $DIR/$tfile
21008         done
21009
21010         echo 3 > /proc/sys/vm/drop_caches
21011         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
21012                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
21013         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
21014
21015         echo "before: $req_before, after: $req_after"
21016         [ $((req_after - req_before)) -ge 300 ] &&
21017                 error "open/close requests are not freed"
21018         return 0
21019 }
21020 run_test 209 "read-only open/close requests should be freed promptly"
21021
21022 test_210() {
21023         local pid
21024
21025         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
21026         pid=$!
21027         sleep 1
21028
21029         $LFS getstripe $DIR/$tfile
21030         kill -USR1 $pid
21031         wait $pid || error "multiop failed"
21032
21033         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
21034         pid=$!
21035         sleep 1
21036
21037         $LFS getstripe $DIR/$tfile
21038         kill -USR1 $pid
21039         wait $pid || error "multiop failed"
21040 }
21041 run_test 210 "lfs getstripe does not break leases"
21042
21043 function test_211() {
21044         local PID
21045         local id
21046         local rc
21047
21048         stack_trap "rm -f $DIR/$tfile" EXIT
21049         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
21050                 error "can't create file"
21051         $LFS mirror extend -N $DIR/$tfile ||
21052                 error "can't create a replica"
21053         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
21054         $LFS getstripe $DIR/$tfile
21055         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
21056         (( $stale != 1 )) && error "expected 1 stale, found $stale"
21057
21058         $MULTIOP $DIR/$tfile OeW_E+eUc &
21059         PID=$!
21060         sleep 0.3
21061
21062         id=$($LFS getstripe $DIR/$tfile |
21063                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
21064         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
21065                 error "removed last in-sync replica?"
21066
21067         kill -USR1 $PID
21068         wait $PID
21069         (( $? == 0 )) || error "failed split broke the lease"
21070 }
21071 run_test 211 "failed mirror split doesn't break write lease"
21072
21073 test_212() {
21074         size=`date +%s`
21075         size=$((size % 8192 + 1))
21076         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21077         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21078         rm -f $DIR/f212 $DIR/f212.xyz
21079 }
21080 run_test 212 "Sendfile test ============================================"
21081
21082 test_213() {
21083         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21084         cancel_lru_locks osc
21085         lctl set_param fail_loc=0x8000040f
21086         # generate a read lock
21087         cat $DIR/$tfile > /dev/null
21088         # write to the file, it will try to cancel the above read lock.
21089         cat /etc/hosts >> $DIR/$tfile
21090 }
21091 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21092
21093 test_214() { # for bug 20133
21094         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21095         for (( i=0; i < 340; i++ )) ; do
21096                 touch $DIR/$tdir/d214c/a$i
21097         done
21098
21099         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21100         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21101         ls $DIR/d214c || error "ls $DIR/d214c failed"
21102         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21103         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21104 }
21105 run_test 214 "hash-indexed directory test - bug 20133"
21106
21107 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21108 create_lnet_proc_files() {
21109         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21110 }
21111
21112 # counterpart of create_lnet_proc_files
21113 remove_lnet_proc_files() {
21114         rm -f $TMP/lnet_$1.sys
21115 }
21116
21117 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21118 # 3rd arg as regexp for body
21119 check_lnet_proc_stats() {
21120         local l=$(cat "$TMP/lnet_$1" |wc -l)
21121         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21122
21123         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21124 }
21125
21126 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21127 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21128 # optional and can be regexp for 2nd line (lnet.routes case)
21129 check_lnet_proc_entry() {
21130         local blp=2          # blp stands for 'position of 1st line of body'
21131         [ -z "$5" ] || blp=3 # lnet.routes case
21132
21133         local l=$(cat "$TMP/lnet_$1" |wc -l)
21134         # subtracting one from $blp because the body can be empty
21135         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21136
21137         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21138                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21139
21140         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21141                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21142
21143         # bail out if any unexpected line happened
21144         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21145         [ "$?" != 0 ] || error "$2 misformatted"
21146 }
21147
21148 test_215() { # for bugs 18102, 21079, 21517
21149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21150
21151         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21152         local P='[1-9][0-9]*'           # positive numeric
21153         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21154         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21155         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21156         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21157         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21158         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21159
21160         local L1 # regexp for 1st line
21161         local L2 # regexp for 2nd line (optional)
21162         local BR # regexp for the rest (body)
21163
21164         # lnet.stats should look as 11 space-separated non-negative numerics
21165         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21166         create_lnet_proc_files "stats"
21167         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21168         remove_lnet_proc_files "stats"
21169
21170         # lnet.routes should look like this:
21171         # Routing disabled/enabled
21172         # net hops priority state router
21173         # where net is a string like tcp0, hops > 0, priority >= 0,
21174         # state is up/down,
21175         # router is a string like 192.168.1.1@tcp2
21176         L1="^Routing (disabled|enabled)$"
21177         L2="^net +hops +priority +state +router$"
21178         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21179         create_lnet_proc_files "routes"
21180         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21181         remove_lnet_proc_files "routes"
21182
21183         # lnet.routers should look like this:
21184         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21185         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21186         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21187         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21188         L1="^ref +rtr_ref +alive +router$"
21189         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21190         create_lnet_proc_files "routers"
21191         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21192         remove_lnet_proc_files "routers"
21193
21194         # lnet.peers should look like this:
21195         # nid refs state last max rtr min tx min queue
21196         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21197         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21198         # numeric (0 or >0 or <0), queue >= 0.
21199         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21200         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21201         create_lnet_proc_files "peers"
21202         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21203         remove_lnet_proc_files "peers"
21204
21205         # lnet.buffers  should look like this:
21206         # pages count credits min
21207         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21208         L1="^pages +count +credits +min$"
21209         BR="^ +$N +$N +$I +$I$"
21210         create_lnet_proc_files "buffers"
21211         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21212         remove_lnet_proc_files "buffers"
21213
21214         # lnet.nis should look like this:
21215         # nid status alive refs peer rtr max tx min
21216         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21217         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21218         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21219         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21220         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21221         create_lnet_proc_files "nis"
21222         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21223         remove_lnet_proc_files "nis"
21224
21225         # can we successfully write to lnet.stats?
21226         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21227 }
21228 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21229
21230 test_216() { # bug 20317
21231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21232         remote_ost_nodsh && skip "remote OST with nodsh"
21233
21234         local node
21235         local facets=$(get_facets OST)
21236         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21237
21238         save_lustre_params client "osc.*.contention_seconds" > $p
21239         save_lustre_params $facets \
21240                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21241         save_lustre_params $facets \
21242                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21243         save_lustre_params $facets \
21244                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21245         clear_stats osc.*.osc_stats
21246
21247         # agressive lockless i/o settings
21248         do_nodes $(comma_list $(osts_nodes)) \
21249                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21250                         ldlm.namespaces.filter-*.contended_locks=0 \
21251                         ldlm.namespaces.filter-*.contention_seconds=60"
21252         lctl set_param -n osc.*.contention_seconds=60
21253
21254         $DIRECTIO write $DIR/$tfile 0 10 4096
21255         $CHECKSTAT -s 40960 $DIR/$tfile
21256
21257         # disable lockless i/o
21258         do_nodes $(comma_list $(osts_nodes)) \
21259                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21260                         ldlm.namespaces.filter-*.contended_locks=32 \
21261                         ldlm.namespaces.filter-*.contention_seconds=0"
21262         lctl set_param -n osc.*.contention_seconds=0
21263         clear_stats osc.*.osc_stats
21264
21265         dd if=/dev/zero of=$DIR/$tfile count=0
21266         $CHECKSTAT -s 0 $DIR/$tfile
21267
21268         restore_lustre_params <$p
21269         rm -f $p
21270         rm $DIR/$tfile
21271 }
21272 run_test 216 "check lockless direct write updates file size and kms correctly"
21273
21274 test_217() { # bug 22430
21275         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21276
21277         local node
21278
21279         for node in $(nodes_list); do
21280                 local nid=$(host_nids_address $node $NETTYPE)
21281                 local node_ip=$(do_node $node getent ahostsv4 $node |
21282                                 awk '{ print $1; exit; }')
21283
21284                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21285                 # if hostname matches any NID, use hostname for better testing
21286                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21287                         echo "lctl ping node $node@$NETTYPE"
21288                         lctl ping $node@$NETTYPE ||
21289                                 error "ping $node@$NETTYPE failed rc=$?"
21290                 else # otherwise, at least test 'lctl ping' is working
21291                         echo "lctl ping nid $(h2nettype $nid)"
21292                         lctl ping $(h2nettype $nid) ||
21293                                 error "ping $(h2nettype $nid) failed rc=$?"
21294                         echo "skipping $node (no hyphen detected)"
21295                 fi
21296         done
21297
21298         return 0
21299 }
21300 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21301
21302 test_218() {
21303         # do directio so as not to populate the page cache
21304         log "creating a 10 Mb file"
21305         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21306                 error "multiop failed while creating a file"
21307         log "starting reads"
21308         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21309         log "truncating the file"
21310         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21311                 error "multiop failed while truncating the file"
21312         log "killing dd"
21313         kill %+ || true # reads might have finished
21314         echo "wait until dd is finished"
21315         wait
21316         log "removing the temporary file"
21317         rm -rf $DIR/$tfile || error "tmp file removal failed"
21318 }
21319 run_test 218 "parallel read and truncate should not deadlock"
21320
21321 test_219() {
21322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21323
21324         # write one partial page
21325         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21326         # set no grant so vvp_io_commit_write will do sync write
21327         $LCTL set_param fail_loc=0x411
21328         # write a full page at the end of file
21329         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21330
21331         $LCTL set_param fail_loc=0
21332         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21333         $LCTL set_param fail_loc=0x411
21334         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21335
21336         # LU-4201
21337         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21338         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21339 }
21340 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21341
21342 test_220() { #LU-325
21343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21344         remote_ost_nodsh && skip "remote OST with nodsh"
21345         remote_mds_nodsh && skip "remote MDS with nodsh"
21346         remote_mgs_nodsh && skip "remote MGS with nodsh"
21347
21348         local OSTIDX=0
21349
21350         # create on MDT0000 so the last_id and next_id are correct
21351         mkdir_on_mdt0 $DIR/$tdir
21352         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21353         OST=${OST%_UUID}
21354
21355         # on the mdt's osc
21356         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21357         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21358                         osp.$mdtosc_proc1.prealloc_last_id)
21359         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21360                         osp.$mdtosc_proc1.prealloc_next_id)
21361
21362         $LFS df -i
21363
21364         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21365         #define OBD_FAIL_OST_ENOINO              0x229
21366         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21367         create_pool $FSNAME.$TESTNAME || return 1
21368         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21369
21370         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21371
21372         MDSOBJS=$((last_id - next_id))
21373         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21374
21375         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21376         echo "OST still has $count kbytes free"
21377
21378         echo "create $MDSOBJS files @next_id..."
21379         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21380
21381         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21382                         osp.$mdtosc_proc1.prealloc_last_id)
21383         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21384                         osp.$mdtosc_proc1.prealloc_next_id)
21385
21386         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21387         $LFS df -i
21388
21389         echo "cleanup..."
21390
21391         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21392         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21393
21394         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21395                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21396         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21397                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21398         echo "unlink $MDSOBJS files @$next_id..."
21399         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21400 }
21401 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21402
21403 test_221() {
21404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21405
21406         dd if=`which date` of=$MOUNT/date oflag=sync
21407         chmod +x $MOUNT/date
21408
21409         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21410         $LCTL set_param fail_loc=0x80001401
21411
21412         $MOUNT/date > /dev/null
21413         rm -f $MOUNT/date
21414 }
21415 run_test 221 "make sure fault and truncate race to not cause OOM"
21416
21417 test_222a () {
21418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21419
21420         rm -rf $DIR/$tdir
21421         test_mkdir $DIR/$tdir
21422         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21423         createmany -o $DIR/$tdir/$tfile 10
21424         cancel_lru_locks mdc
21425         cancel_lru_locks osc
21426         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21427         $LCTL set_param fail_loc=0x31a
21428         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21429         $LCTL set_param fail_loc=0
21430         rm -r $DIR/$tdir
21431 }
21432 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21433
21434 test_222b () {
21435         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21436
21437         rm -rf $DIR/$tdir
21438         test_mkdir $DIR/$tdir
21439         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21440         createmany -o $DIR/$tdir/$tfile 10
21441         cancel_lru_locks mdc
21442         cancel_lru_locks osc
21443         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21444         $LCTL set_param fail_loc=0x31a
21445         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21446         $LCTL set_param fail_loc=0
21447 }
21448 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21449
21450 test_223 () {
21451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21452
21453         rm -rf $DIR/$tdir
21454         test_mkdir $DIR/$tdir
21455         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21456         createmany -o $DIR/$tdir/$tfile 10
21457         cancel_lru_locks mdc
21458         cancel_lru_locks osc
21459         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21460         $LCTL set_param fail_loc=0x31b
21461         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21462         $LCTL set_param fail_loc=0
21463         rm -r $DIR/$tdir
21464 }
21465 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21466
21467 test_224a() { # LU-1039, MRP-303
21468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21469         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21470         $LCTL set_param fail_loc=0x508
21471         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21472         $LCTL set_param fail_loc=0
21473         df $DIR
21474 }
21475 run_test 224a "Don't panic on bulk IO failure"
21476
21477 test_224bd_sub() { # LU-1039, MRP-303
21478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21479         local timeout=$1
21480
21481         shift
21482         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21483
21484         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21485
21486         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21487         cancel_lru_locks osc
21488         set_checksums 0
21489         stack_trap "set_checksums $ORIG_CSUM" EXIT
21490         local at_max_saved=0
21491
21492         # adaptive timeouts may prevent seeing the issue
21493         if at_is_enabled; then
21494                 at_max_saved=$(at_max_get mds)
21495                 at_max_set 0 mds client
21496                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21497         fi
21498
21499         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21500         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21501         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21502
21503         do_facet ost1 $LCTL set_param fail_loc=0
21504         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21505         df $DIR
21506 }
21507
21508 test_224b() {
21509         test_224bd_sub 3 error "dd failed"
21510 }
21511 run_test 224b "Don't panic on bulk IO failure"
21512
21513 test_224c() { # LU-6441
21514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21515         remote_mds_nodsh && skip "remote MDS with nodsh"
21516
21517         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21518         save_writethrough $p
21519         set_cache writethrough on
21520
21521         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21522         local at_max=$($LCTL get_param -n at_max)
21523         local timeout=$($LCTL get_param -n timeout)
21524         local test_at="at_max"
21525         local param_at="$FSNAME.sys.at_max"
21526         local test_timeout="timeout"
21527         local param_timeout="$FSNAME.sys.timeout"
21528
21529         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21530
21531         set_persistent_param_and_check client "$test_at" "$param_at" 0
21532         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21533
21534         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21535         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21536         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21537         stack_trap "rm -f $DIR/$tfile"
21538         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21539         sync
21540         do_facet ost1 "$LCTL set_param fail_loc=0"
21541
21542         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21543         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21544                 $timeout
21545
21546         $LCTL set_param -n $pages_per_rpc
21547         restore_lustre_params < $p
21548         rm -f $p
21549 }
21550 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21551
21552 test_224d() { # LU-11169
21553         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21554 }
21555 run_test 224d "Don't corrupt data on bulk IO timeout"
21556
21557 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21558 test_225a () {
21559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21560         if [ -z ${MDSSURVEY} ]; then
21561                 skip_env "mds-survey not found"
21562         fi
21563         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21564                 skip "Need MDS version at least 2.2.51"
21565
21566         local mds=$(facet_host $SINGLEMDS)
21567         local target=$(do_nodes $mds 'lctl dl' |
21568                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21569
21570         local cmd1="file_count=1000 thrhi=4"
21571         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21572         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21573         local cmd="$cmd1 $cmd2 $cmd3"
21574
21575         rm -f ${TMP}/mds_survey*
21576         echo + $cmd
21577         eval $cmd || error "mds-survey with zero-stripe failed"
21578         cat ${TMP}/mds_survey*
21579         rm -f ${TMP}/mds_survey*
21580 }
21581 run_test 225a "Metadata survey sanity with zero-stripe"
21582
21583 test_225b () {
21584         if [ -z ${MDSSURVEY} ]; then
21585                 skip_env "mds-survey not found"
21586         fi
21587         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21588                 skip "Need MDS version at least 2.2.51"
21589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21590         remote_mds_nodsh && skip "remote MDS with nodsh"
21591         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21592                 skip_env "Need to mount OST to test"
21593         fi
21594
21595         local mds=$(facet_host $SINGLEMDS)
21596         local target=$(do_nodes $mds 'lctl dl' |
21597                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21598
21599         local cmd1="file_count=1000 thrhi=4"
21600         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21601         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21602         local cmd="$cmd1 $cmd2 $cmd3"
21603
21604         rm -f ${TMP}/mds_survey*
21605         echo + $cmd
21606         eval $cmd || error "mds-survey with stripe_count failed"
21607         cat ${TMP}/mds_survey*
21608         rm -f ${TMP}/mds_survey*
21609 }
21610 run_test 225b "Metadata survey sanity with stripe_count = 1"
21611
21612 mcreate_path2fid () {
21613         local mode=$1
21614         local major=$2
21615         local minor=$3
21616         local name=$4
21617         local desc=$5
21618         local path=$DIR/$tdir/$name
21619         local fid
21620         local rc
21621         local fid_path
21622
21623         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21624                 error "cannot create $desc"
21625
21626         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21627         rc=$?
21628         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21629
21630         fid_path=$($LFS fid2path $MOUNT $fid)
21631         rc=$?
21632         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21633
21634         [ "$path" == "$fid_path" ] ||
21635                 error "fid2path returned $fid_path, expected $path"
21636
21637         echo "pass with $path and $fid"
21638 }
21639
21640 test_226a () {
21641         rm -rf $DIR/$tdir
21642         mkdir -p $DIR/$tdir
21643
21644         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21645         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21646         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21647         mcreate_path2fid 0040666 0 0 dir "directory"
21648         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21649         mcreate_path2fid 0100666 0 0 file "regular file"
21650         mcreate_path2fid 0120666 0 0 link "symbolic link"
21651         mcreate_path2fid 0140666 0 0 sock "socket"
21652 }
21653 run_test 226a "call path2fid and fid2path on files of all type"
21654
21655 test_226b () {
21656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21657
21658         local MDTIDX=1
21659
21660         rm -rf $DIR/$tdir
21661         mkdir -p $DIR/$tdir
21662         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21663                 error "create remote directory failed"
21664         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21665         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21666                                 "character special file (null)"
21667         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21668                                 "character special file (no device)"
21669         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21670         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21671                                 "block special file (loop)"
21672         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21673         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21674         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21675 }
21676 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21677
21678 test_226c () {
21679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21680         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21681                 skip "Need MDS version at least 2.13.55"
21682
21683         local submnt=/mnt/submnt
21684         local srcfile=/etc/passwd
21685         local dstfile=$submnt/passwd
21686         local path
21687         local fid
21688
21689         rm -rf $DIR/$tdir
21690         rm -rf $submnt
21691         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21692                 error "create remote directory failed"
21693         mkdir -p $submnt || error "create $submnt failed"
21694         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21695                 error "mount $submnt failed"
21696         stack_trap "umount $submnt" EXIT
21697
21698         cp $srcfile $dstfile
21699         fid=$($LFS path2fid $dstfile)
21700         path=$($LFS fid2path $submnt "$fid")
21701         [ "$path" = "$dstfile" ] ||
21702                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21703 }
21704 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21705
21706 test_226d () {
21707         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21708                 skip "Need client at least version 2.15.57"
21709
21710         # Define First test dataset
21711         local testdirs_01=$DIR/$tdir
21712         local testdata_01=$testdirs_01/${tdir}_01
21713         local testresult_01=${tdir}_01
21714         # Define Second test dataset
21715         local testdirs_02=$DIR/$tdir/$tdir
21716         local testdata_02=$testdirs_02/${tdir}_02
21717         local testresult_02=${tdir}_02
21718         # Define third test dataset (top level)
21719         local testdata_03=$DIR/${tdir}_03
21720         local testresult_03=${tdir}_03
21721
21722         # Create first test dataset
21723         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21724         touch $testdata_01 || error "cannot create file $testdata_01"
21725
21726         # Create second test dataset
21727         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21728         touch $testdata_02 || error "cannot create file $testdata_02"
21729
21730         # Create third test dataset
21731         touch $testdata_03 || error "cannot create file $testdata_03"
21732
21733         local fid01=$($LFS getstripe -F "$testdata_01") ||
21734                 error "getstripe failed on $testdata_01"
21735         local fid02=$($LFS getstripe -F "$testdata_02") ||
21736                 error "getstripe failed on $testdata_01"
21737         local fid03=$($LFS getstripe -F "$testdata_03") ||
21738                 error "getstripe failed on $testdata_03"
21739
21740         # Verify only -n option
21741         local out1=$($LFS fid2path -n $DIR $fid01) ||
21742                 error "fid2path failed on $fid01"
21743         local out2=$($LFS fid2path -n $DIR $fid02) ||
21744                 error "fid2path failed on $fid02"
21745         local out3=$($LFS fid2path -n $DIR $fid03) ||
21746                 error "fid2path failed on $fid03"
21747
21748         [[ "$out1" == "$testresult_01" ]] ||
21749                 error "fid2path failed: Expected $testresult_01 got $out1"
21750         [[ "$out2" == "$testresult_02" ]] ||
21751                 error "fid2path failed: Expected $testresult_02 got $out2"
21752         [[ "$out3" == "$testresult_03" ]] ||
21753                 error "fid2path failed: Expected $testresult_03 got $out3"
21754
21755         # Verify with option -fn together
21756         out1=$($LFS fid2path -fn $DIR $fid01) ||
21757                 error "fid2path -fn failed on $fid01"
21758         out2=$($LFS fid2path -fn $DIR $fid02) ||
21759                 error "fid2path -fn failed on $fid02"
21760         out3=$($LFS fid2path -fn $DIR $fid03) ||
21761                 error "fid2path -fn failed on $fid03"
21762
21763         local tmpout=$(echo $out1 | cut -d" " -f2)
21764         [[ "$tmpout" == "$testresult_01" ]] ||
21765                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21766
21767         tmpout=$(echo $out2 | cut -d" " -f2)
21768         [[ "$tmpout" == "$testresult_02" ]] ||
21769                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21770
21771         tmpout=$(echo $out3 | cut -d" " -f2)
21772         [[ "$tmpout" == "$testresult_03" ]] ||
21773                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21774 }
21775 run_test 226d "verify fid2path with -n and -fn option"
21776
21777 test_226e () {
21778         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21779                 skip "Need client at least version 2.15.56"
21780
21781         # Define filename with 'newline' and a space
21782         local testfile="Test"$'\n'"file 01"
21783         # Define link name with multiple 'newline' and a space
21784         local linkfile="Link"$'\n'"file "$'\n'"01"
21785         # Remove prior hard link
21786         rm -f $DIR/"$linkfile"
21787
21788         # Create file
21789         touch $DIR/"$testfile"
21790         # Create link
21791         ln $DIR/"$testfile" $DIR/"$linkfile"
21792
21793         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21794                 error "getstripe failed on $DIR/$testfile"
21795
21796         # Call with -0 option
21797         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21798                 echo "FILE:" | grep -c "FILE:")
21799
21800         # With -0 option the output should be exactly 2 lines.
21801         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21802 }
21803 run_test 226e "Verify path2fid -0 option with newline and space"
21804
21805 # LU-1299 Executing or running ldd on a truncated executable does not
21806 # cause an out-of-memory condition.
21807 test_227() {
21808         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21809         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21810
21811         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21812         chmod +x $MOUNT/date
21813
21814         $MOUNT/date > /dev/null
21815         ldd $MOUNT/date > /dev/null
21816         rm -f $MOUNT/date
21817 }
21818 run_test 227 "running truncated executable does not cause OOM"
21819
21820 # LU-1512 try to reuse idle OI blocks
21821 test_228a() {
21822         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21823         remote_mds_nodsh && skip "remote MDS with nodsh"
21824         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21825
21826         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21827         local myDIR=$DIR/$tdir
21828
21829         mkdir -p $myDIR
21830         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21831         $LCTL set_param fail_loc=0x80001002
21832         createmany -o $myDIR/t- 10000
21833         $LCTL set_param fail_loc=0
21834         # The guard is current the largest FID holder
21835         touch $myDIR/guard
21836         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21837                     tr -d '[')
21838         local IDX=$(($SEQ % 64))
21839
21840         do_facet $SINGLEMDS sync
21841         # Make sure journal flushed.
21842         sleep 6
21843         local blk1=$(do_facet $SINGLEMDS \
21844                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21845                      grep Blockcount | awk '{print $4}')
21846
21847         # Remove old files, some OI blocks will become idle.
21848         unlinkmany $myDIR/t- 10000
21849         # Create new files, idle OI blocks should be reused.
21850         createmany -o $myDIR/t- 2000
21851         do_facet $SINGLEMDS sync
21852         # Make sure journal flushed.
21853         sleep 6
21854         local blk2=$(do_facet $SINGLEMDS \
21855                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21856                      grep Blockcount | awk '{print $4}')
21857
21858         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21859 }
21860 run_test 228a "try to reuse idle OI blocks"
21861
21862 test_228b() {
21863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21864         remote_mds_nodsh && skip "remote MDS with nodsh"
21865         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21866
21867         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21868         local myDIR=$DIR/$tdir
21869
21870         mkdir -p $myDIR
21871         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21872         $LCTL set_param fail_loc=0x80001002
21873         createmany -o $myDIR/t- 10000
21874         $LCTL set_param fail_loc=0
21875         # The guard is current the largest FID holder
21876         touch $myDIR/guard
21877         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21878                     tr -d '[')
21879         local IDX=$(($SEQ % 64))
21880
21881         do_facet $SINGLEMDS sync
21882         # Make sure journal flushed.
21883         sleep 6
21884         local blk1=$(do_facet $SINGLEMDS \
21885                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21886                      grep Blockcount | awk '{print $4}')
21887
21888         # Remove old files, some OI blocks will become idle.
21889         unlinkmany $myDIR/t- 10000
21890
21891         # stop the MDT
21892         stop $SINGLEMDS || error "Fail to stop MDT."
21893         # remount the MDT
21894         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21895                 error "Fail to start MDT."
21896
21897         client_up || error "Fail to df."
21898         # Create new files, idle OI blocks should be reused.
21899         createmany -o $myDIR/t- 2000
21900         do_facet $SINGLEMDS sync
21901         # Make sure journal flushed.
21902         sleep 6
21903         local blk2=$(do_facet $SINGLEMDS \
21904                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21905                      grep Blockcount | awk '{print $4}')
21906
21907         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21908 }
21909 run_test 228b "idle OI blocks can be reused after MDT restart"
21910
21911 #LU-1881
21912 test_228c() {
21913         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21914         remote_mds_nodsh && skip "remote MDS with nodsh"
21915         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21916
21917         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21918         local myDIR=$DIR/$tdir
21919
21920         mkdir -p $myDIR
21921         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21922         $LCTL set_param fail_loc=0x80001002
21923         # 20000 files can guarantee there are index nodes in the OI file
21924         createmany -o $myDIR/t- 20000
21925         $LCTL set_param fail_loc=0
21926         # The guard is current the largest FID holder
21927         touch $myDIR/guard
21928         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21929                     tr -d '[')
21930         local IDX=$(($SEQ % 64))
21931
21932         do_facet $SINGLEMDS sync
21933         # Make sure journal flushed.
21934         sleep 6
21935         local blk1=$(do_facet $SINGLEMDS \
21936                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21937                      grep Blockcount | awk '{print $4}')
21938
21939         # Remove old files, some OI blocks will become idle.
21940         unlinkmany $myDIR/t- 20000
21941         rm -f $myDIR/guard
21942         # The OI file should become empty now
21943
21944         # Create new files, idle OI blocks should be reused.
21945         createmany -o $myDIR/t- 2000
21946         do_facet $SINGLEMDS sync
21947         # Make sure journal flushed.
21948         sleep 6
21949         local blk2=$(do_facet $SINGLEMDS \
21950                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21951                      grep Blockcount | awk '{print $4}')
21952
21953         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21954 }
21955 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21956
21957 test_229() { # LU-2482, LU-3448
21958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21959         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21960         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21961                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21962
21963         rm -f $DIR/$tfile
21964
21965         # Create a file with a released layout and stripe count 2.
21966         $MULTIOP $DIR/$tfile H2c ||
21967                 error "failed to create file with released layout"
21968
21969         $LFS getstripe -v $DIR/$tfile
21970
21971         local pattern=$($LFS getstripe -L $DIR/$tfile)
21972         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21973
21974         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21975                 error "getstripe"
21976         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21977         stat $DIR/$tfile || error "failed to stat released file"
21978
21979         chown $RUNAS_ID $DIR/$tfile ||
21980                 error "chown $RUNAS_ID $DIR/$tfile failed"
21981
21982         chgrp $RUNAS_ID $DIR/$tfile ||
21983                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21984
21985         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21986         rm $DIR/$tfile || error "failed to remove released file"
21987 }
21988 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21989
21990 test_230a() {
21991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21992         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21993         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21994                 skip "Need MDS version at least 2.11.52"
21995
21996         local MDTIDX=1
21997
21998         test_mkdir $DIR/$tdir
21999         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
22000         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
22001         [ $mdt_idx -ne 0 ] &&
22002                 error "create local directory on wrong MDT $mdt_idx"
22003
22004         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
22005                         error "create remote directory failed"
22006         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
22007         [ $mdt_idx -ne $MDTIDX ] &&
22008                 error "create remote directory on wrong MDT $mdt_idx"
22009
22010         createmany -o $DIR/$tdir/test_230/t- 10 ||
22011                 error "create files on remote directory failed"
22012         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
22013         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
22014         rm -r $DIR/$tdir || error "unlink remote directory failed"
22015 }
22016 run_test 230a "Create remote directory and files under the remote directory"
22017
22018 test_230b() {
22019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22021         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22022                 skip "Need MDS version at least 2.11.52"
22023
22024         local MDTIDX=1
22025         local mdt_index
22026         local i
22027         local file
22028         local pid
22029         local stripe_count
22030         local migrate_dir=$DIR/$tdir/migrate_dir
22031         local other_dir=$DIR/$tdir/other_dir
22032
22033         test_mkdir $DIR/$tdir
22034         test_mkdir -i0 -c1 $migrate_dir
22035         test_mkdir -i0 -c1 $other_dir
22036         for ((i=0; i<10; i++)); do
22037                 mkdir -p $migrate_dir/dir_${i}
22038                 createmany -o $migrate_dir/dir_${i}/f 10 ||
22039                         error "create files under remote dir failed $i"
22040         done
22041
22042         cp /etc/passwd $migrate_dir/$tfile
22043         cp /etc/passwd $other_dir/$tfile
22044         chattr +SAD $migrate_dir
22045         chattr +SAD $migrate_dir/$tfile
22046
22047         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22048         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22049         local old_dir_mode=$(stat -c%f $migrate_dir)
22050         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
22051
22052         mkdir -p $migrate_dir/dir_default_stripe2
22053         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
22054         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
22055
22056         mkdir -p $other_dir
22057         ln $migrate_dir/$tfile $other_dir/luna
22058         ln $migrate_dir/$tfile $migrate_dir/sofia
22059         ln $other_dir/$tfile $migrate_dir/david
22060         ln -s $migrate_dir/$tfile $other_dir/zachary
22061         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
22062         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
22063
22064         local len
22065         local lnktgt
22066
22067         # inline symlink
22068         for len in 58 59 60; do
22069                 lnktgt=$(str_repeat 'l' $len)
22070                 touch $migrate_dir/$lnktgt
22071                 ln -s $lnktgt $migrate_dir/${len}char_ln
22072         done
22073
22074         # PATH_MAX
22075         for len in 4094 4095; do
22076                 lnktgt=$(str_repeat 'l' $len)
22077                 ln -s $lnktgt $migrate_dir/${len}char_ln
22078         done
22079
22080         # NAME_MAX
22081         for len in 254 255; do
22082                 touch $migrate_dir/$(str_repeat 'l' $len)
22083         done
22084
22085         $LFS migrate -m $MDTIDX $migrate_dir ||
22086                 error "fails on migrating remote dir to MDT1"
22087
22088         echo "migratate to MDT1, then checking.."
22089         for ((i = 0; i < 10; i++)); do
22090                 for file in $(find $migrate_dir/dir_${i}); do
22091                         mdt_index=$($LFS getstripe -m $file)
22092                         # broken symlink getstripe will fail
22093                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22094                                 error "$file is not on MDT${MDTIDX}"
22095                 done
22096         done
22097
22098         # the multiple link file should still in MDT0
22099         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22100         [ $mdt_index == 0 ] ||
22101                 error "$file is not on MDT${MDTIDX}"
22102
22103         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22104         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22105                 error " expect $old_dir_flag get $new_dir_flag"
22106
22107         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22108         [ "$old_file_flag" = "$new_file_flag" ] ||
22109                 error " expect $old_file_flag get $new_file_flag"
22110
22111         local new_dir_mode=$(stat -c%f $migrate_dir)
22112         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22113                 error "expect mode $old_dir_mode get $new_dir_mode"
22114
22115         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22116         [ "$old_file_mode" = "$new_file_mode" ] ||
22117                 error "expect mode $old_file_mode get $new_file_mode"
22118
22119         diff /etc/passwd $migrate_dir/$tfile ||
22120                 error "$tfile different after migration"
22121
22122         diff /etc/passwd $other_dir/luna ||
22123                 error "luna different after migration"
22124
22125         diff /etc/passwd $migrate_dir/sofia ||
22126                 error "sofia different after migration"
22127
22128         diff /etc/passwd $migrate_dir/david ||
22129                 error "david different after migration"
22130
22131         diff /etc/passwd $other_dir/zachary ||
22132                 error "zachary different after migration"
22133
22134         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22135                 error "${tfile}_ln different after migration"
22136
22137         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22138                 error "${tfile}_ln_other different after migration"
22139
22140         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22141         [ $stripe_count = 2 ] ||
22142                 error "dir strpe_count $d != 2 after migration."
22143
22144         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22145         [ $stripe_count = 2 ] ||
22146                 error "file strpe_count $d != 2 after migration."
22147
22148         #migrate back to MDT0
22149         MDTIDX=0
22150
22151         $LFS migrate -m $MDTIDX $migrate_dir ||
22152                 error "fails on migrating remote dir to MDT0"
22153
22154         echo "migrate back to MDT0, checking.."
22155         for file in $(find $migrate_dir); do
22156                 mdt_index=$($LFS getstripe -m $file)
22157                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22158                         error "$file is not on MDT${MDTIDX}"
22159         done
22160
22161         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22162         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22163                 error " expect $old_dir_flag get $new_dir_flag"
22164
22165         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22166         [ "$old_file_flag" = "$new_file_flag" ] ||
22167                 error " expect $old_file_flag get $new_file_flag"
22168
22169         local new_dir_mode=$(stat -c%f $migrate_dir)
22170         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22171                 error "expect mode $old_dir_mode get $new_dir_mode"
22172
22173         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22174         [ "$old_file_mode" = "$new_file_mode" ] ||
22175                 error "expect mode $old_file_mode get $new_file_mode"
22176
22177         diff /etc/passwd ${migrate_dir}/$tfile ||
22178                 error "$tfile different after migration"
22179
22180         diff /etc/passwd ${other_dir}/luna ||
22181                 error "luna different after migration"
22182
22183         diff /etc/passwd ${migrate_dir}/sofia ||
22184                 error "sofia different after migration"
22185
22186         diff /etc/passwd ${other_dir}/zachary ||
22187                 error "zachary different after migration"
22188
22189         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22190                 error "${tfile}_ln different after migration"
22191
22192         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22193                 error "${tfile}_ln_other different after migration"
22194
22195         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22196         [ $stripe_count = 2 ] ||
22197                 error "dir strpe_count $d != 2 after migration."
22198
22199         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22200         [ $stripe_count = 2 ] ||
22201                 error "file strpe_count $d != 2 after migration."
22202
22203         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22204 }
22205 run_test 230b "migrate directory"
22206
22207 test_230c() {
22208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22209         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22210         remote_mds_nodsh && skip "remote MDS with nodsh"
22211         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22212                 skip "Need MDS version at least 2.11.52"
22213
22214         local MDTIDX=1
22215         local total=3
22216         local mdt_index
22217         local file
22218         local migrate_dir=$DIR/$tdir/migrate_dir
22219
22220         #If migrating directory fails in the middle, all entries of
22221         #the directory is still accessiable.
22222         test_mkdir $DIR/$tdir
22223         test_mkdir -i0 -c1 $migrate_dir
22224         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22225         stat $migrate_dir
22226         createmany -o $migrate_dir/f $total ||
22227                 error "create files under ${migrate_dir} failed"
22228
22229         # fail after migrating top dir, and this will fail only once, so the
22230         # first sub file migration will fail (currently f3), others succeed.
22231         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22232         do_facet mds1 lctl set_param fail_loc=0x1801
22233         local t=$(ls $migrate_dir | wc -l)
22234         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22235                 error "migrate should fail"
22236         local u=$(ls $migrate_dir | wc -l)
22237         [ "$u" == "$t" ] || error "$u != $t during migration"
22238
22239         # add new dir/file should succeed
22240         mkdir $migrate_dir/dir ||
22241                 error "mkdir failed under migrating directory"
22242         touch $migrate_dir/file ||
22243                 error "create file failed under migrating directory"
22244
22245         # add file with existing name should fail
22246         for file in $migrate_dir/f*; do
22247                 stat $file > /dev/null || error "stat $file failed"
22248                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22249                         error "open(O_CREAT|O_EXCL) $file should fail"
22250                 $MULTIOP $file m && error "create $file should fail"
22251                 touch $DIR/$tdir/remote_dir/$tfile ||
22252                         error "touch $tfile failed"
22253                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22254                         error "link $file should fail"
22255                 mdt_index=$($LFS getstripe -m $file)
22256                 if [ $mdt_index == 0 ]; then
22257                         # file failed to migrate is not allowed to rename to
22258                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22259                                 error "rename to $file should fail"
22260                 else
22261                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22262                                 error "rename to $file failed"
22263                 fi
22264                 echo hello >> $file || error "write $file failed"
22265         done
22266
22267         # resume migration with different options should fail
22268         $LFS migrate -m 0 $migrate_dir &&
22269                 error "migrate -m 0 $migrate_dir should fail"
22270
22271         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22272                 error "migrate -c 2 $migrate_dir should fail"
22273
22274         # resume migration should succeed
22275         $LFS migrate -m $MDTIDX $migrate_dir ||
22276                 error "migrate $migrate_dir failed"
22277
22278         echo "Finish migration, then checking.."
22279         for file in $(find $migrate_dir); do
22280                 mdt_index=$($LFS getstripe -m $file)
22281                 [ $mdt_index == $MDTIDX ] ||
22282                         error "$file is not on MDT${MDTIDX}"
22283         done
22284
22285         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22286 }
22287 run_test 230c "check directory accessiblity if migration failed"
22288
22289 test_230d() {
22290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22291         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22292         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22293                 skip "Need MDS version at least 2.11.52"
22294         # LU-11235
22295         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22296
22297         local migrate_dir=$DIR/$tdir/migrate_dir
22298         local old_index
22299         local new_index
22300         local old_count
22301         local new_count
22302         local new_hash
22303         local mdt_index
22304         local i
22305         local j
22306
22307         old_index=$((RANDOM % MDSCOUNT))
22308         old_count=$((MDSCOUNT - old_index))
22309         new_index=$((RANDOM % MDSCOUNT))
22310         new_count=$((MDSCOUNT - new_index))
22311         new_hash=1 # for all_char
22312
22313         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22314         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22315
22316         test_mkdir $DIR/$tdir
22317         test_mkdir -i $old_index -c $old_count $migrate_dir
22318
22319         for ((i=0; i<100; i++)); do
22320                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22321                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22322                         error "create files under remote dir failed $i"
22323         done
22324
22325         echo -n "Migrate from MDT$old_index "
22326         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22327         echo -n "to MDT$new_index"
22328         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22329         echo
22330
22331         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22332         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22333                 error "migrate remote dir error"
22334
22335         echo "Finish migration, then checking.."
22336         for file in $(find $migrate_dir -maxdepth 1); do
22337                 mdt_index=$($LFS getstripe -m $file)
22338                 if [ $mdt_index -lt $new_index ] ||
22339                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22340                         error "$file is on MDT$mdt_index"
22341                 fi
22342         done
22343
22344         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22345 }
22346 run_test 230d "check migrate big directory"
22347
22348 test_230e() {
22349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22350         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22351         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22352                 skip "Need MDS version at least 2.11.52"
22353
22354         local i
22355         local j
22356         local a_fid
22357         local b_fid
22358
22359         mkdir_on_mdt0 $DIR/$tdir
22360         mkdir $DIR/$tdir/migrate_dir
22361         mkdir $DIR/$tdir/other_dir
22362         touch $DIR/$tdir/migrate_dir/a
22363         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22364         ls $DIR/$tdir/other_dir
22365
22366         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22367                 error "migrate dir fails"
22368
22369         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22370         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22371
22372         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22373         [ $mdt_index == 0 ] || error "a is not on MDT0"
22374
22375         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22376                 error "migrate dir fails"
22377
22378         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22379         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22380
22381         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22382         [ $mdt_index == 1 ] || error "a is not on MDT1"
22383
22384         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22385         [ $mdt_index == 1 ] || error "b is not on MDT1"
22386
22387         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22388         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22389
22390         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22391
22392         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22393 }
22394 run_test 230e "migrate mulitple local link files"
22395
22396 test_230f() {
22397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22398         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22399         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22400                 skip "Need MDS version at least 2.11.52"
22401
22402         local a_fid
22403         local ln_fid
22404
22405         mkdir -p $DIR/$tdir
22406         mkdir $DIR/$tdir/migrate_dir
22407         $LFS mkdir -i1 $DIR/$tdir/other_dir
22408         touch $DIR/$tdir/migrate_dir/a
22409         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22410         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22411         ls $DIR/$tdir/other_dir
22412
22413         # a should be migrated to MDT1, since no other links on MDT0
22414         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22415                 error "#1 migrate dir fails"
22416         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22417         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22418         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22419         [ $mdt_index == 1 ] || error "a is not on MDT1"
22420
22421         # a should stay on MDT1, because it is a mulitple link file
22422         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22423                 error "#2 migrate dir fails"
22424         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22425         [ $mdt_index == 1 ] || error "a is not on MDT1"
22426
22427         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22428                 error "#3 migrate dir fails"
22429
22430         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22431         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22432         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22433
22434         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22435         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22436
22437         # a should be migrated to MDT0, since no other links on MDT1
22438         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22439                 error "#4 migrate dir fails"
22440         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22441         [ $mdt_index == 0 ] || error "a is not on MDT0"
22442
22443         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22444 }
22445 run_test 230f "migrate mulitple remote link files"
22446
22447 test_230g() {
22448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22449         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22450         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22451                 skip "Need MDS version at least 2.11.52"
22452
22453         mkdir -p $DIR/$tdir/migrate_dir
22454
22455         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22456                 error "migrating dir to non-exist MDT succeeds"
22457         true
22458 }
22459 run_test 230g "migrate dir to non-exist MDT"
22460
22461 test_230h() {
22462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22463         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22464         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22465                 skip "Need MDS version at least 2.11.52"
22466
22467         local mdt_index
22468
22469         mkdir -p $DIR/$tdir/migrate_dir
22470
22471         $LFS migrate -m1 $DIR &&
22472                 error "migrating mountpoint1 should fail"
22473
22474         $LFS migrate -m1 $DIR/$tdir/.. &&
22475                 error "migrating mountpoint2 should fail"
22476
22477         # same as mv
22478         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22479                 error "migrating $tdir/migrate_dir/.. should fail"
22480
22481         true
22482 }
22483 run_test 230h "migrate .. and root"
22484
22485 test_230i() {
22486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22487         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22488         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22489                 skip "Need MDS version at least 2.11.52"
22490
22491         mkdir -p $DIR/$tdir/migrate_dir
22492
22493         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22494                 error "migration fails with a tailing slash"
22495
22496         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22497                 error "migration fails with two tailing slashes"
22498 }
22499 run_test 230i "lfs migrate -m tolerates trailing slashes"
22500
22501 test_230j() {
22502         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22503         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22504                 skip "Need MDS version at least 2.11.52"
22505
22506         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22507         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22508                 error "create $tfile failed"
22509         cat /etc/passwd > $DIR/$tdir/$tfile
22510
22511         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22512
22513         cmp /etc/passwd $DIR/$tdir/$tfile ||
22514                 error "DoM file mismatch after migration"
22515 }
22516 run_test 230j "DoM file data not changed after dir migration"
22517
22518 test_230k() {
22519         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22520         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22521                 skip "Need MDS version at least 2.11.56"
22522
22523         local total=20
22524         local files_on_starting_mdt=0
22525
22526         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22527         $LFS getdirstripe $DIR/$tdir
22528         for i in $(seq $total); do
22529                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22530                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22531                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22532         done
22533
22534         echo "$files_on_starting_mdt files on MDT0"
22535
22536         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22537         $LFS getdirstripe $DIR/$tdir
22538
22539         files_on_starting_mdt=0
22540         for i in $(seq $total); do
22541                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22542                         error "file $tfile.$i mismatch after migration"
22543                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22544                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22545         done
22546
22547         echo "$files_on_starting_mdt files on MDT1 after migration"
22548         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22549
22550         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22551         $LFS getdirstripe $DIR/$tdir
22552
22553         files_on_starting_mdt=0
22554         for i in $(seq $total); do
22555                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22556                         error "file $tfile.$i mismatch after 2nd migration"
22557                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22558                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22559         done
22560
22561         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22562         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22563
22564         true
22565 }
22566 run_test 230k "file data not changed after dir migration"
22567
22568 test_230l() {
22569         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22570         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22571                 skip "Need MDS version at least 2.11.56"
22572
22573         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22574         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22575                 error "create files under remote dir failed $i"
22576         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22577 }
22578 run_test 230l "readdir between MDTs won't crash"
22579
22580 test_230m() {
22581         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22582         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22583                 skip "Need MDS version at least 2.11.56"
22584
22585         local MDTIDX=1
22586         local mig_dir=$DIR/$tdir/migrate_dir
22587         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22588         local shortstr="b"
22589         local val
22590
22591         echo "Creating files and dirs with xattrs"
22592         test_mkdir $DIR/$tdir
22593         test_mkdir -i0 -c1 $mig_dir
22594         mkdir $mig_dir/dir
22595         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22596                 error "cannot set xattr attr1 on dir"
22597         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22598                 error "cannot set xattr attr2 on dir"
22599         touch $mig_dir/dir/f0
22600         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22601                 error "cannot set xattr attr1 on file"
22602         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22603                 error "cannot set xattr attr2 on file"
22604         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22605         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22606         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22607         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22608         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22609         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22610         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22611         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22612         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22613
22614         echo "Migrating to MDT1"
22615         $LFS migrate -m $MDTIDX $mig_dir ||
22616                 error "fails on migrating dir to MDT1"
22617
22618         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22619         echo "Checking xattrs"
22620         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22621         [ "$val" = $longstr ] ||
22622                 error "expecting xattr1 $longstr on dir, found $val"
22623         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22624         [ "$val" = $shortstr ] ||
22625                 error "expecting xattr2 $shortstr on dir, found $val"
22626         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22627         [ "$val" = $longstr ] ||
22628                 error "expecting xattr1 $longstr on file, found $val"
22629         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22630         [ "$val" = $shortstr ] ||
22631                 error "expecting xattr2 $shortstr on file, found $val"
22632 }
22633 run_test 230m "xattrs not changed after dir migration"
22634
22635 test_230n() {
22636         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22637         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22638                 skip "Need MDS version at least 2.13.53"
22639
22640         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22641         cat /etc/hosts > $DIR/$tdir/$tfile
22642         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22643         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22644
22645         cmp /etc/hosts $DIR/$tdir/$tfile ||
22646                 error "File data mismatch after migration"
22647 }
22648 run_test 230n "Dir migration with mirrored file"
22649
22650 test_230o() {
22651         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22652         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22653                 skip "Need MDS version at least 2.13.52"
22654
22655         local mdts=$(comma_list $(mdts_nodes))
22656         local timeout=100
22657         local restripe_status
22658         local delta
22659         local i
22660
22661         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22662
22663         # in case "crush" hash type is not set
22664         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22665
22666         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22667                            mdt.*MDT0000.enable_dir_restripe)
22668         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22669         stack_trap "do_nodes $mdts $LCTL set_param \
22670                     mdt.*.enable_dir_restripe=$restripe_status"
22671
22672         mkdir $DIR/$tdir
22673         createmany -m $DIR/$tdir/f 100 ||
22674                 error "create files under remote dir failed $i"
22675         createmany -d $DIR/$tdir/d 100 ||
22676                 error "create dirs under remote dir failed $i"
22677
22678         for i in $(seq 2 $MDSCOUNT); do
22679                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22680                 $LFS setdirstripe -c $i $DIR/$tdir ||
22681                         error "split -c $i $tdir failed"
22682                 wait_update $HOSTNAME \
22683                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22684                         error "dir split not finished"
22685                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22686                         awk '/migrate/ {sum += $2} END { print sum }')
22687                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22688                 # delta is around total_files/stripe_count
22689                 (( $delta < 200 / (i - 1) + 4 )) ||
22690                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22691         done
22692 }
22693 run_test 230o "dir split"
22694
22695 test_230p() {
22696         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22697         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22698                 skip "Need MDS version at least 2.13.52"
22699
22700         local mdts=$(comma_list $(mdts_nodes))
22701         local timeout=100
22702         local restripe_status
22703         local delta
22704         local c
22705
22706         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22707
22708         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22709
22710         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22711                            mdt.*MDT0000.enable_dir_restripe)
22712         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22713         stack_trap "do_nodes $mdts $LCTL set_param \
22714                     mdt.*.enable_dir_restripe=$restripe_status"
22715
22716         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22717         createmany -m $DIR/$tdir/f 100 ||
22718                 error "create files under remote dir failed"
22719         createmany -d $DIR/$tdir/d 100 ||
22720                 error "create dirs under remote dir failed"
22721
22722         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22723                 local mdt_hash="crush"
22724
22725                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22726                 $LFS setdirstripe -c $c $DIR/$tdir ||
22727                         error "split -c $c $tdir failed"
22728                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22729                         mdt_hash="$mdt_hash,fixed"
22730                 elif [ $c -eq 1 ]; then
22731                         mdt_hash="none"
22732                 fi
22733                 wait_update $HOSTNAME \
22734                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22735                         error "dir merge not finished"
22736                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22737                         awk '/migrate/ {sum += $2} END { print sum }')
22738                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22739                 # delta is around total_files/stripe_count
22740                 (( delta < 200 / c + 4 )) ||
22741                         error "$delta files migrated >= $((200 / c + 4))"
22742         done
22743 }
22744 run_test 230p "dir merge"
22745
22746 test_230q() {
22747         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22748         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22749                 skip "Need MDS version at least 2.13.52"
22750
22751         local mdts=$(comma_list $(mdts_nodes))
22752         local saved_threshold=$(do_facet mds1 \
22753                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22754         local saved_delta=$(do_facet mds1 \
22755                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22756         local threshold=100
22757         local delta=2
22758         local total=0
22759         local stripe_count=0
22760         local stripe_index
22761         local nr_files
22762         local create
22763
22764         # test with fewer files on ZFS
22765         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22766
22767         stack_trap "do_nodes $mdts $LCTL set_param \
22768                     mdt.*.dir_split_count=$saved_threshold"
22769         stack_trap "do_nodes $mdts $LCTL set_param \
22770                     mdt.*.dir_split_delta=$saved_delta"
22771         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22772         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22773         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22774         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22775         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22776         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22777
22778         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22779         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22780
22781         create=$((threshold * 3 / 2))
22782         while [ $stripe_count -lt $MDSCOUNT ]; do
22783                 createmany -m $DIR/$tdir/f $total $create ||
22784                         error "create sub files failed"
22785                 stat $DIR/$tdir > /dev/null
22786                 total=$((total + create))
22787                 stripe_count=$((stripe_count + delta))
22788                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22789
22790                 wait_update $HOSTNAME \
22791                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22792                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22793
22794                 wait_update $HOSTNAME \
22795                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22796                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22797
22798                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22799                 echo "$nr_files/$total files on MDT$stripe_index after split"
22800                 # allow 10% margin of imbalance with crush hash
22801                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22802                         error "$nr_files files on MDT$stripe_index after split"
22803
22804                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22805                 [ $nr_files -eq $total ] ||
22806                         error "total sub files $nr_files != $total"
22807         done
22808
22809         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22810
22811         echo "fixed layout directory won't auto split"
22812         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22813         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22814                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22815         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22816                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22817 }
22818 run_test 230q "dir auto split"
22819
22820 test_230r() {
22821         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22822         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22823         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22824                 skip "Need MDS version at least 2.13.54"
22825
22826         # maximum amount of local locks:
22827         # parent striped dir - 2 locks
22828         # new stripe in parent to migrate to - 1 lock
22829         # source and target - 2 locks
22830         # Total 5 locks for regular file
22831         mkdir -p $DIR/$tdir
22832         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22833         touch $DIR/$tdir/dir1/eee
22834
22835         # create 4 hardlink for 4 more locks
22836         # Total: 9 locks > RS_MAX_LOCKS (8)
22837         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22838         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22839         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22840         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22841         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22842         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22843         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22844         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22845
22846         cancel_lru_locks mdc
22847
22848         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22849                 error "migrate dir fails"
22850
22851         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22852 }
22853 run_test 230r "migrate with too many local locks"
22854
22855 test_230s() {
22856         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22857                 skip "Need MDS version at least 2.14.52"
22858
22859         local mdts=$(comma_list $(mdts_nodes))
22860         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22861                                 mdt.*MDT0000.enable_dir_restripe)
22862
22863         stack_trap "do_nodes $mdts $LCTL set_param \
22864                     mdt.*.enable_dir_restripe=$restripe_status"
22865
22866         local st
22867         for st in 0 1; do
22868                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22869                 test_mkdir $DIR/$tdir
22870                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22871                         error "$LFS mkdir should return EEXIST if target exists"
22872                 rmdir $DIR/$tdir
22873         done
22874 }
22875 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22876
22877 test_230t()
22878 {
22879         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22880         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22881                 skip "Need MDS version at least 2.14.50"
22882
22883         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22884         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22885         $LFS project -p 1 -s $DIR/$tdir ||
22886                 error "set $tdir project id failed"
22887         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22888                 error "set subdir project id failed"
22889         local pbefore="$($LFS project -d $DIR/$tdir)"
22890         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22891         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22892
22893         local pafter="$($LFS project -d $DIR/$tdir)"
22894         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22895         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22896         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22897
22898         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22899                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22900
22901         # check rename works, even if source parent projid differs (LU-17016)
22902         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22903         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22904
22905         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22906         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22907                 error "subdir failed rename for different source parent projid"
22908         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22909
22910         [[ "$fid_before" == "$fid_after" ]] ||
22911                 error "fid before '$fid_before' != after '$fid_after'"
22912 }
22913 run_test 230t "migrate directory with project ID set"
22914
22915 test_230u()
22916 {
22917         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22918         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22919                 skip "Need MDS version at least 2.14.53"
22920
22921         local count
22922
22923         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22924         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22925         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22926         for i in $(seq 0 $((MDSCOUNT - 1))); do
22927                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22928                 echo "$count dirs migrated to MDT$i"
22929         done
22930         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22931         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22932 }
22933 run_test 230u "migrate directory by QOS"
22934
22935 test_230v()
22936 {
22937         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22938         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22939                 skip "Need MDS version at least 2.14.53"
22940
22941         local count
22942
22943         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22944         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22945         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22946         for i in $(seq 0 $((MDSCOUNT - 1))); do
22947                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22948                 echo "$count subdirs migrated to MDT$i"
22949                 (( i == 3 )) && (( count > 0 )) &&
22950                         error "subdir shouldn't be migrated to MDT3"
22951         done
22952         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22953         (( count == 3 )) || error "dirs migrated to $count MDTs"
22954 }
22955 run_test 230v "subdir migrated to the MDT where its parent is located"
22956
22957 test_230w() {
22958         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22959         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22960                 skip "Need MDS version at least 2.15.0"
22961
22962         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22963         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22964         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22965
22966         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22967                 error "migrate failed"
22968
22969         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22970                 error "$tdir stripe count mismatch"
22971
22972         for i in $(seq 0 9); do
22973                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22974                         error "d$i is striped"
22975         done
22976 }
22977 run_test 230w "non-recursive mode dir migration"
22978
22979 test_230x() {
22980         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22981         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22982                 skip "Need MDS version at least 2.15.0"
22983
22984         mkdir -p $DIR/$tdir || error "mkdir failed"
22985         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22986
22987         local mdt_name=$(mdtname_from_index 0)
22988         local low=$(do_facet mds2 $LCTL get_param -n \
22989                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22990         local high=$(do_facet mds2 $LCTL get_param -n \
22991                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22992         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22993         local maxage=$(do_facet mds2 $LCTL get_param -n \
22994                 osp.*$mdt_name-osp-MDT0001.maxage)
22995
22996         stack_trap "do_facet mds2 $LCTL set_param -n \
22997                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22998                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22999         stack_trap "do_facet mds2 $LCTL set_param -n \
23000                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
23001
23002         do_facet mds2 $LCTL set_param -n \
23003                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
23004         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
23005         sleep 4
23006         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
23007                 error "migrate $tdir should fail"
23008
23009         do_facet mds2 $LCTL set_param -n \
23010                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
23011         do_facet mds2 $LCTL set_param -n \
23012                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
23013         sleep 4
23014         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
23015                 error "migrate failed"
23016         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
23017                 error "$tdir stripe count mismatch"
23018 }
23019 run_test 230x "dir migration check space"
23020
23021 test_230y() {
23022         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23023         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23024                 skip "Need MDS version at least 2.15.55.45"
23025
23026         local pid
23027
23028         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23029         $LFS getdirstripe $DIR/$tdir
23030         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23031         $LFS migrate -m 1 -c 2 $DIR/$tdir &
23032         pid=$!
23033         sleep 1
23034
23035         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23036         do_facet mds2 lctl set_param fail_loc=0x1802
23037
23038         wait $pid
23039         do_facet mds2 lctl set_param fail_loc=0
23040         $LFS getdirstripe $DIR/$tdir
23041         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
23042         rmdir $DIR/$tdir || error "rmdir $tdir failed"
23043 }
23044 run_test 230y "unlink dir with bad hash type"
23045
23046 test_230z() {
23047         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
23048         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
23049                 skip "Need MDS version at least 2.15.55.45"
23050
23051         local pid
23052
23053         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
23054         $LFS getdirstripe $DIR/$tdir
23055         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
23056         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
23057         pid=$!
23058         sleep 1
23059
23060         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
23061         do_facet mds2 lctl set_param fail_loc=0x1802
23062
23063         wait $pid
23064         do_facet mds2 lctl set_param fail_loc=0
23065         $LFS getdirstripe $DIR/$tdir
23066
23067         # resume migration
23068         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
23069                 error "resume migration failed"
23070         $LFS getdirstripe $DIR/$tdir
23071         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
23072                 error "migration is not finished"
23073 }
23074 run_test 230z "resume dir migration with bad hash type"
23075
23076 test_231a()
23077 {
23078         # For simplicity this test assumes that max_pages_per_rpc
23079         # is the same across all OSCs
23080         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23081         local bulk_size=$((max_pages * PAGE_SIZE))
23082         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23083                                        head -n 1)
23084
23085         mkdir -p $DIR/$tdir
23086         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23087                 error "failed to set stripe with -S ${brw_size}M option"
23088         stack_trap "rm -rf $DIR/$tdir"
23089
23090         # clear the OSC stats
23091         $LCTL set_param osc.*.stats=0 &>/dev/null
23092         stop_writeback
23093
23094         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23095         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23096                 oflag=direct &>/dev/null || error "dd failed"
23097
23098         sync; sleep 1; sync # just to be safe
23099         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23100         if [ x$nrpcs != "x1" ]; then
23101                 $LCTL get_param osc.*.stats
23102                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23103         fi
23104
23105         start_writeback
23106         # Drop the OSC cache, otherwise we will read from it
23107         cancel_lru_locks osc
23108
23109         # clear the OSC stats
23110         $LCTL set_param osc.*.stats=0 &>/dev/null
23111
23112         # Client reads $bulk_size.
23113         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23114                 iflag=direct &>/dev/null || error "dd failed"
23115
23116         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23117         if [ x$nrpcs != "x1" ]; then
23118                 $LCTL get_param osc.*.stats
23119                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23120         fi
23121 }
23122 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23123
23124 test_231b() {
23125         mkdir -p $DIR/$tdir
23126         stack_trap "rm -rf $DIR/$tdir"
23127         local i
23128         for i in {0..1023}; do
23129                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23130                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23131                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23132         done
23133         sync
23134 }
23135 run_test 231b "must not assert on fully utilized OST request buffer"
23136
23137 test_232a() {
23138         mkdir -p $DIR/$tdir
23139         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23140
23141         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23142         do_facet ost1 $LCTL set_param fail_loc=0x31c
23143
23144         # ignore dd failure
23145         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23146         stack_trap "rm -f $DIR/$tdir/$tfile"
23147
23148         do_facet ost1 $LCTL set_param fail_loc=0
23149         umount_client $MOUNT || error "umount failed"
23150         mount_client $MOUNT || error "mount failed"
23151         stop ost1 || error "cannot stop ost1"
23152         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23153 }
23154 run_test 232a "failed lock should not block umount"
23155
23156 test_232b() {
23157         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23158                 skip "Need MDS version at least 2.10.58"
23159
23160         mkdir -p $DIR/$tdir
23161         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23162         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23163         stack_trap "rm -f $DIR/$tdir/$tfile"
23164         sync
23165         cancel_lru_locks osc
23166
23167         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23168         do_facet ost1 $LCTL set_param fail_loc=0x31c
23169
23170         # ignore failure
23171         $LFS data_version $DIR/$tdir/$tfile || true
23172
23173         do_facet ost1 $LCTL set_param fail_loc=0
23174         umount_client $MOUNT || error "umount failed"
23175         mount_client $MOUNT || error "mount failed"
23176         stop ost1 || error "cannot stop ost1"
23177         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23178 }
23179 run_test 232b "failed data version lock should not block umount"
23180
23181 test_233a() {
23182         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23183                 skip "Need MDS version at least 2.3.64"
23184         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23185
23186         local fid=$($LFS path2fid $MOUNT)
23187
23188         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23189                 error "cannot access $MOUNT using its FID '$fid'"
23190 }
23191 run_test 233a "checking that OBF of the FS root succeeds"
23192
23193 test_233b() {
23194         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23195                 skip "Need MDS version at least 2.5.90"
23196         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23197
23198         local fid=$($LFS path2fid $MOUNT/.lustre)
23199
23200         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23201                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23202
23203         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23204         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23205                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23206 }
23207 run_test 233b "checking that OBF of the FS .lustre succeeds"
23208
23209 test_234() {
23210         local p="$TMP/sanityN-$TESTNAME.parameters"
23211         save_lustre_params client "llite.*.xattr_cache" > $p
23212         lctl set_param llite.*.xattr_cache 1 ||
23213                 skip_env "xattr cache is not supported"
23214
23215         mkdir -p $DIR/$tdir || error "mkdir failed"
23216         touch $DIR/$tdir/$tfile || error "touch failed"
23217         # OBD_FAIL_LLITE_XATTR_ENOMEM
23218         $LCTL set_param fail_loc=0x1405
23219         getfattr -n user.attr $DIR/$tdir/$tfile &&
23220                 error "getfattr should have failed with ENOMEM"
23221         $LCTL set_param fail_loc=0x0
23222         rm -rf $DIR/$tdir
23223
23224         restore_lustre_params < $p
23225         rm -f $p
23226 }
23227 run_test 234 "xattr cache should not crash on ENOMEM"
23228
23229 test_235() {
23230         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23231                 skip "Need MDS version at least 2.4.52"
23232
23233         flock_deadlock $DIR/$tfile
23234         local RC=$?
23235         case $RC in
23236                 0)
23237                 ;;
23238                 124) error "process hangs on a deadlock"
23239                 ;;
23240                 *) error "error executing flock_deadlock $DIR/$tfile"
23241                 ;;
23242         esac
23243 }
23244 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23245
23246 #LU-2935
23247 test_236() {
23248         check_swap_layouts_support
23249
23250         local ref1=/etc/passwd
23251         local ref2=/etc/group
23252         local file1=$DIR/$tdir/f1
23253         local file2=$DIR/$tdir/f2
23254
23255         test_mkdir -c1 $DIR/$tdir
23256         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23257         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23258         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23259         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23260         local fd=$(free_fd)
23261         local cmd="exec $fd<>$file2"
23262         eval $cmd
23263         rm $file2
23264         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23265                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23266         cmd="exec $fd>&-"
23267         eval $cmd
23268         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23269
23270         #cleanup
23271         rm -rf $DIR/$tdir
23272 }
23273 run_test 236 "Layout swap on open unlinked file"
23274
23275 # LU-4659 linkea consistency
23276 test_238() {
23277         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23278                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23279                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23280                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23281
23282         touch $DIR/$tfile
23283         ln $DIR/$tfile $DIR/$tfile.lnk
23284         touch $DIR/$tfile.new
23285         mv $DIR/$tfile.new $DIR/$tfile
23286         local fid1=$($LFS path2fid $DIR/$tfile)
23287         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23288         local path1=$($LFS fid2path $FSNAME "$fid1")
23289         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23290         local path2=$($LFS fid2path $FSNAME "$fid2")
23291         [ $tfile.lnk == $path2 ] ||
23292                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23293         rm -f $DIR/$tfile*
23294 }
23295 run_test 238 "Verify linkea consistency"
23296
23297 test_239A() { # was test_239
23298         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23299                 skip "Need MDS version at least 2.5.60"
23300
23301         local list=$(comma_list $(mdts_nodes))
23302
23303         mkdir -p $DIR/$tdir
23304         createmany -o $DIR/$tdir/f- 5000
23305         unlinkmany $DIR/$tdir/f- 5000
23306         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23307                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23308         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23309                         osp.*MDT*.sync_in_flight" | calc_sum)
23310         [ "$changes" -eq 0 ] || error "$changes not synced"
23311 }
23312 run_test 239A "osp_sync test"
23313
23314 test_239a() { #LU-5297
23315         remote_mds_nodsh && skip "remote MDS with nodsh"
23316
23317         touch $DIR/$tfile
23318         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23319         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23320         chgrp $RUNAS_GID $DIR/$tfile
23321         wait_delete_completed
23322 }
23323 run_test 239a "process invalid osp sync record correctly"
23324
23325 test_239b() { #LU-5297
23326         remote_mds_nodsh && skip "remote MDS with nodsh"
23327
23328         touch $DIR/$tfile1
23329         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23330         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23331         chgrp $RUNAS_GID $DIR/$tfile1
23332         wait_delete_completed
23333         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23334         touch $DIR/$tfile2
23335         chgrp $RUNAS_GID $DIR/$tfile2
23336         wait_delete_completed
23337 }
23338 run_test 239b "process osp sync record with ENOMEM error correctly"
23339
23340 test_240() {
23341         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23342         remote_mds_nodsh && skip "remote MDS with nodsh"
23343
23344         mkdir -p $DIR/$tdir
23345
23346         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23347                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23348         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23349                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23350
23351         umount_client $MOUNT || error "umount failed"
23352         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23353         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23354         mount_client $MOUNT || error "failed to mount client"
23355
23356         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23357         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23358 }
23359 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23360
23361 test_241_bio() {
23362         local count=$1
23363         local bsize=$2
23364
23365         for LOOP in $(seq $count); do
23366                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23367                 cancel_lru_locks $OSC || true
23368         done
23369 }
23370
23371 test_241_dio() {
23372         local count=$1
23373         local bsize=$2
23374
23375         for LOOP in $(seq $1); do
23376                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23377                         2>/dev/null
23378         done
23379 }
23380
23381 test_241a() { # was test_241
23382         local bsize=$PAGE_SIZE
23383
23384         (( bsize < 40960 )) && bsize=40960
23385         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23386         ls -la $DIR/$tfile
23387         cancel_lru_locks $OSC
23388         test_241_bio 1000 $bsize &
23389         PID=$!
23390         test_241_dio 1000 $bsize
23391         wait $PID
23392 }
23393 run_test 241a "bio vs dio"
23394
23395 test_241b() {
23396         local bsize=$PAGE_SIZE
23397
23398         (( bsize < 40960 )) && bsize=40960
23399         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23400         ls -la $DIR/$tfile
23401         test_241_dio 1000 $bsize &
23402         PID=$!
23403         test_241_dio 1000 $bsize
23404         wait $PID
23405 }
23406 run_test 241b "dio vs dio"
23407
23408 test_242() {
23409         remote_mds_nodsh && skip "remote MDS with nodsh"
23410
23411         mkdir_on_mdt0 $DIR/$tdir
23412         touch $DIR/$tdir/$tfile
23413
23414         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23415         do_facet mds1 lctl set_param fail_loc=0x105
23416         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23417
23418         do_facet mds1 lctl set_param fail_loc=0
23419         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23420 }
23421 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23422
23423 test_243()
23424 {
23425         test_mkdir $DIR/$tdir
23426         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23427 }
23428 run_test 243 "various group lock tests"
23429
23430 test_244a()
23431 {
23432         test_mkdir $DIR/$tdir
23433         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23434         sendfile_grouplock $DIR/$tdir/$tfile || \
23435                 error "sendfile+grouplock failed"
23436         rm -rf $DIR/$tdir
23437 }
23438 run_test 244a "sendfile with group lock tests"
23439
23440 test_244b()
23441 {
23442         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23443
23444         local threads=50
23445         local size=$((1024*1024))
23446
23447         test_mkdir $DIR/$tdir
23448         for i in $(seq 1 $threads); do
23449                 local file=$DIR/$tdir/file_$((i / 10))
23450                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23451                 local pids[$i]=$!
23452         done
23453         for i in $(seq 1 $threads); do
23454                 wait ${pids[$i]}
23455         done
23456 }
23457 run_test 244b "multi-threaded write with group lock"
23458
23459 test_245a() {
23460         local flagname="multi_mod_rpcs"
23461         local connect_data_name="max_mod_rpcs"
23462         local out
23463
23464         # check if multiple modify RPCs flag is set
23465         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23466                 grep "connect_flags:")
23467         echo "$out"
23468
23469         echo "$out" | grep -qw $flagname
23470         if [ $? -ne 0 ]; then
23471                 echo "connect flag $flagname is not set"
23472                 return
23473         fi
23474
23475         # check if multiple modify RPCs data is set
23476         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23477         echo "$out"
23478
23479         echo "$out" | grep -qw $connect_data_name ||
23480                 error "import should have connect data $connect_data_name"
23481 }
23482 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23483
23484 test_245b() {
23485         local flagname="multi_mod_rpcs"
23486         local connect_data_name="max_mod_rpcs"
23487         local out
23488
23489         remote_mds_nodsh && skip "remote MDS with nodsh"
23490         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23491
23492         # check if multiple modify RPCs flag is set
23493         out=$(do_facet mds1 \
23494               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23495               grep "connect_flags:")
23496         echo "$out"
23497
23498         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23499
23500         # check if multiple modify RPCs data is set
23501         out=$(do_facet mds1 \
23502               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23503
23504         [[ "$out" =~ $connect_data_name ]] ||
23505                 {
23506                         echo "$out"
23507                         error "missing connect data $connect_data_name"
23508                 }
23509 }
23510 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23511
23512 cleanup_247() {
23513         local submount=$1
23514
23515         trap 0
23516         umount_client $submount
23517         rmdir $submount
23518 }
23519
23520 test_247a() {
23521         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23522                 grep -q subtree ||
23523                 skip_env "Fileset feature is not supported"
23524
23525         local submount=${MOUNT}_$tdir
23526
23527         mkdir $MOUNT/$tdir
23528         mkdir -p $submount || error "mkdir $submount failed"
23529         FILESET="$FILESET/$tdir" mount_client $submount ||
23530                 error "mount $submount failed"
23531         trap "cleanup_247 $submount" EXIT
23532         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23533         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23534                 error "read $MOUNT/$tdir/$tfile failed"
23535         cleanup_247 $submount
23536 }
23537 run_test 247a "mount subdir as fileset"
23538
23539 test_247b() {
23540         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23541                 skip_env "Fileset feature is not supported"
23542
23543         local submount=${MOUNT}_$tdir
23544
23545         rm -rf $MOUNT/$tdir
23546         mkdir -p $submount || error "mkdir $submount failed"
23547         SKIP_FILESET=1
23548         FILESET="$FILESET/$tdir" mount_client $submount &&
23549                 error "mount $submount should fail"
23550         rmdir $submount
23551 }
23552 run_test 247b "mount subdir that dose not exist"
23553
23554 test_247c() {
23555         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23556                 skip_env "Fileset feature is not supported"
23557
23558         local submount=${MOUNT}_$tdir
23559
23560         mkdir -p $MOUNT/$tdir/dir1
23561         mkdir -p $submount || error "mkdir $submount failed"
23562         trap "cleanup_247 $submount" EXIT
23563         FILESET="$FILESET/$tdir" mount_client $submount ||
23564                 error "mount $submount failed"
23565         local fid=$($LFS path2fid $MOUNT/)
23566         $LFS fid2path $submount $fid && error "fid2path should fail"
23567         cleanup_247 $submount
23568 }
23569 run_test 247c "running fid2path outside subdirectory root"
23570
23571 test_247d() {
23572         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23573                 skip "Fileset feature is not supported"
23574
23575         local submount=${MOUNT}_$tdir
23576
23577         mkdir -p $MOUNT/$tdir/dir1
23578         mkdir -p $submount || error "mkdir $submount failed"
23579         FILESET="$FILESET/$tdir" mount_client $submount ||
23580                 error "mount $submount failed"
23581         trap "cleanup_247 $submount" EXIT
23582
23583         local td=$submount/dir1
23584         local fid=$($LFS path2fid $td)
23585         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23586
23587         # check that we get the same pathname back
23588         local rootpath
23589         local found
23590         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23591                 echo "$rootpath $fid"
23592                 found=$($LFS fid2path $rootpath "$fid")
23593                 [ -n "$found" ] || error "fid2path should succeed"
23594                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23595         done
23596         # check wrong root path format
23597         rootpath=$submount"_wrong"
23598         found=$($LFS fid2path $rootpath "$fid")
23599         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23600
23601         cleanup_247 $submount
23602 }
23603 run_test 247d "running fid2path inside subdirectory root"
23604
23605 # LU-8037
23606 test_247e() {
23607         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23608                 grep -q subtree ||
23609                 skip "Fileset feature is not supported"
23610
23611         local submount=${MOUNT}_$tdir
23612
23613         mkdir $MOUNT/$tdir
23614         mkdir -p $submount || error "mkdir $submount failed"
23615         FILESET="$FILESET/.." mount_client $submount &&
23616                 error "mount $submount should fail"
23617         rmdir $submount
23618 }
23619 run_test 247e "mount .. as fileset"
23620
23621 test_247f() {
23622         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23623         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23624                 skip "Need at least version 2.14.50.162"
23625         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23626                 skip "Fileset feature is not supported"
23627
23628         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23629         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23630                 error "mkdir remote failed"
23631         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23632                 error "mkdir remote/subdir failed"
23633         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23634                 error "mkdir striped failed"
23635         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23636
23637         local submount=${MOUNT}_$tdir
23638
23639         mkdir -p $submount || error "mkdir $submount failed"
23640         stack_trap "rmdir $submount"
23641
23642         local dir
23643         local fileset=$FILESET
23644         local mdts=$(comma_list $(mdts_nodes))
23645
23646         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23647         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23648                 $tdir/striped/subdir $tdir/striped/.; do
23649                 FILESET="$fileset/$dir" mount_client $submount ||
23650                         error "mount $dir failed"
23651                 umount_client $submount
23652         done
23653 }
23654 run_test 247f "mount striped or remote directory as fileset"
23655
23656 test_subdir_mount_lock()
23657 {
23658         local testdir=$1
23659         local submount=${MOUNT}_$(basename $testdir)
23660
23661         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23662
23663         mkdir -p $submount || error "mkdir $submount failed"
23664         stack_trap "rmdir $submount"
23665
23666         FILESET="$fileset/$testdir" mount_client $submount ||
23667                 error "mount $FILESET failed"
23668         stack_trap "umount $submount"
23669
23670         local mdts=$(comma_list $(mdts_nodes))
23671
23672         local nrpcs
23673
23674         stat $submount > /dev/null || error "stat $submount failed"
23675         cancel_lru_locks $MDC
23676         stat $submount > /dev/null || error "stat $submount failed"
23677         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23678         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23679         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23680         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23681                 awk '/getattr/ {sum += $2} END {print sum}')
23682
23683         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23684 }
23685
23686 test_247g() {
23687         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23688
23689         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23690                 error "mkdir $tdir failed"
23691         test_subdir_mount_lock $tdir
23692 }
23693 run_test 247g "striped directory submount revalidate ROOT from cache"
23694
23695 test_247h() {
23696         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23697         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23698                 skip "Need MDS version at least 2.15.51"
23699
23700         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23701         test_subdir_mount_lock $tdir
23702         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23703         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23704                 error "mkdir $tdir.1 failed"
23705         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23706 }
23707 run_test 247h "remote directory submount revalidate ROOT from cache"
23708
23709 test_248a() {
23710         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23711         [ -z "$fast_read_sav" ] && skip "no fast read support"
23712
23713         # create a large file for fast read verification
23714         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23715
23716         # make sure the file is created correctly
23717         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23718                 { rm -f $DIR/$tfile; skip "file creation error"; }
23719
23720         echo "Test 1: verify that fast read is 4 times faster on cache read"
23721
23722         # small read with fast read enabled
23723         $LCTL set_param -n llite.*.fast_read=1
23724         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23725                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23726                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23727         # small read with fast read disabled
23728         $LCTL set_param -n llite.*.fast_read=0
23729         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23730                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23731                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23732
23733         # verify that fast read is 4 times faster for cache read
23734         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23735                 error_not_in_vm "fast read was not 4 times faster: " \
23736                            "$t_fast vs $t_slow"
23737
23738         echo "Test 2: verify the performance between big and small read"
23739         $LCTL set_param -n llite.*.fast_read=1
23740
23741         # 1k non-cache read
23742         cancel_lru_locks osc
23743         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23744                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23745                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23746
23747         # 1M non-cache read
23748         cancel_lru_locks osc
23749         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23750                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23751                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23752
23753         # verify that big IO is not 4 times faster than small IO
23754         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23755                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23756
23757         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23758         rm -f $DIR/$tfile
23759 }
23760 run_test 248a "fast read verification"
23761
23762 test_248b() {
23763         # Default short_io_bytes=16384, try both smaller and larger sizes.
23764         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23765         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23766         echo "bs=53248 count=113 normal buffered write"
23767         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23768                 error "dd of initial data file failed"
23769         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23770
23771         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23772         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23773                 error "dd with sync normal writes failed"
23774         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23775
23776         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23777         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23778                 error "dd with sync small writes failed"
23779         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23780
23781         cancel_lru_locks osc
23782
23783         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23784         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23785         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23786         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23787                 iflag=direct || error "dd with O_DIRECT small read failed"
23788         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23789         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23790                 error "compare $TMP/$tfile.1 failed"
23791
23792         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23793         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23794
23795         # just to see what the maximum tunable value is, and test parsing
23796         echo "test invalid parameter 2MB"
23797         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23798                 error "too-large short_io_bytes allowed"
23799         echo "test maximum parameter 512KB"
23800         # if we can set a larger short_io_bytes, run test regardless of version
23801         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23802                 # older clients may not allow setting it this large, that's OK
23803                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23804                         skip "Need at least client version 2.13.50"
23805                 error "medium short_io_bytes failed"
23806         fi
23807         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23808         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23809
23810         echo "test large parameter 64KB"
23811         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23812         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23813
23814         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23815         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23816                 error "dd with sync large writes failed"
23817         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23818
23819         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23820         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23821         num=$((113 * 4096 / PAGE_SIZE))
23822         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23823         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23824                 error "dd with O_DIRECT large writes failed"
23825         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23826                 error "compare $DIR/$tfile.3 failed"
23827
23828         cancel_lru_locks osc
23829
23830         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23831         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23832                 error "dd with O_DIRECT large read failed"
23833         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23834                 error "compare $TMP/$tfile.2 failed"
23835
23836         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23837         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23838                 error "dd with O_DIRECT large read failed"
23839         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23840                 error "compare $TMP/$tfile.3 failed"
23841 }
23842 run_test 248b "test short_io read and write for both small and large sizes"
23843
23844 test_249() { # LU-7890
23845         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23846                 skip "Need at least version 2.8.54"
23847
23848         rm -f $DIR/$tfile
23849         $LFS setstripe -c 1 $DIR/$tfile
23850         # Offset 2T == 4k * 512M
23851         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23852                 error "dd to 2T offset failed"
23853 }
23854 run_test 249 "Write above 2T file size"
23855
23856 test_250() {
23857         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23858          && skip "no 16TB file size limit on ZFS"
23859
23860         $LFS setstripe -c 1 $DIR/$tfile
23861         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23862         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23863         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23864         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23865                 conv=notrunc,fsync && error "append succeeded"
23866         return 0
23867 }
23868 run_test 250 "Write above 16T limit"
23869
23870 test_251a() {
23871         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23872
23873         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23874         #Skip once - writing the first stripe will succeed
23875         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23876         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23877                 error "short write happened"
23878
23879         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23880         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23881                 error "short read happened"
23882
23883         rm -f $DIR/$tfile
23884 }
23885 run_test 251a "Handling short read and write correctly"
23886
23887 test_251b() {
23888         dd if=/dev/zero of=$DIR/$tfile bs=1k count=4 ||
23889                 error "write $tfile failed"
23890
23891         sleep 2 && echo 12345 >> $DIR/$tfile &
23892
23893         #define OBD_FAIL_LLITE_READ_PAUSE 0x1431
23894         $LCTL set_param fail_loc=0x1431 fail_val=5
23895         # seek to 4096, 2 seconds later, file size expand to 4102, and after
23896         # 5 seconds, read 10 bytes, the short read should
23897         # report:
23898         #                start ->+ read_len -> offset_after_read read_count
23899         #     short read: 4096 ->+ 10 -> 4096 0
23900         # not:
23901         #     short read: 4096 ->+ 10 -> 4102 0
23902         local off=$($MULTIOP $DIR/$tfile oO_RDONLY:z4096r10c 2>&1 | \
23903                         awk '/short read/ { print $7 }')
23904         (( off == 4096 )) ||
23905                 error "short read should set offset at 4096, not $off"
23906 }
23907 run_test 251b "short read restore offset correctly"
23908
23909 test_252() {
23910         remote_mds_nodsh && skip "remote MDS with nodsh"
23911         remote_ost_nodsh && skip "remote OST with nodsh"
23912         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23913                 skip_env "ldiskfs only test"
23914         fi
23915
23916         local tgt
23917         local dev
23918         local out
23919         local uuid
23920         local num
23921         local gen
23922
23923         # check lr_reader on OST0000
23924         tgt=ost1
23925         dev=$(facet_device $tgt)
23926         out=$(do_facet $tgt $LR_READER $dev)
23927         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23928         echo "$out"
23929         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23930         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23931                 error "Invalid uuid returned by $LR_READER on target $tgt"
23932         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23933
23934         # check lr_reader -c on MDT0000
23935         tgt=mds1
23936         dev=$(facet_device $tgt)
23937         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23938                 skip "$LR_READER does not support additional options"
23939         fi
23940         out=$(do_facet $tgt $LR_READER -c $dev)
23941         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23942         echo "$out"
23943         num=$(echo "$out" | grep -c "mdtlov")
23944         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23945                 error "Invalid number of mdtlov clients returned by $LR_READER"
23946         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23947
23948         # check lr_reader -cr on MDT0000
23949         out=$(do_facet $tgt $LR_READER -cr $dev)
23950         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23951         echo "$out"
23952         echo "$out" | grep -q "^reply_data:$" ||
23953                 error "$LR_READER should have returned 'reply_data' section"
23954         num=$(echo "$out" | grep -c "client_generation")
23955         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23956 }
23957 run_test 252 "check lr_reader tool"
23958
23959 test_253() {
23960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23961         remote_mds_nodsh && skip "remote MDS with nodsh"
23962         remote_mgs_nodsh && skip "remote MGS with nodsh"
23963         check_set_fallocate_or_skip
23964
23965         local ostidx=0
23966         local rc=0
23967         local ost_name=$(ostname_from_index $ostidx)
23968
23969         # on the mdt's osc
23970         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23971         do_facet $SINGLEMDS $LCTL get_param -n \
23972                 osp.$mdtosc_proc1.reserved_mb_high ||
23973                 skip  "remote MDS does not support reserved_mb_high"
23974
23975         rm -rf $DIR/$tdir
23976         wait_mds_ost_sync
23977         wait_delete_completed
23978         mkdir $DIR/$tdir
23979         stack_trap "rm -rf $DIR/$tdir"
23980
23981         pool_add $TESTNAME || error "Pool creation failed"
23982         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23983
23984         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23985                 error "Setstripe failed"
23986
23987         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23988
23989         local wms=$(ost_watermarks_get $ostidx)
23990
23991         ost_watermarks_set $ostidx 60 50
23992         stack_trap "ost_watermarks_set $ostidx $wms"
23993
23994         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
23995         local size=$((free_kb * 1024))
23996
23997         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
23998                 error "fallocate failed"
23999         sleep_maxage
24000
24001         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24002                         osp.$mdtosc_proc1.prealloc_status)
24003         echo "prealloc_status $oa_status"
24004
24005         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
24006                 error "File creation should fail"
24007
24008         #object allocation was stopped, but we still able to append files
24009         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
24010                 oflag=append || error "Append failed"
24011
24012         rm -f $DIR/$tdir/$tfile.0
24013         rm -f $DIR/$tdir/fill_ost$ostidx
24014
24015         wait_delete_completed
24016         sleep_maxage
24017
24018         for i in $(seq 10 12); do
24019                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
24020                         2>/dev/null || error "File creation failed after rm"
24021         done
24022
24023         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
24024                         osp.$mdtosc_proc1.prealloc_status)
24025         echo "prealloc_status $oa_status"
24026
24027         if (( oa_status != 0 )); then
24028                 error "Object allocation still disable after rm"
24029         fi
24030 }
24031 run_test 253 "Check object allocation limit"
24032
24033 test_254() {
24034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24035         remote_mds_nodsh && skip "remote MDS with nodsh"
24036
24037         local mdt=$(facet_svc $SINGLEMDS)
24038
24039         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
24040                 skip "MDS does not support changelog_size"
24041
24042         local cl_user
24043
24044         changelog_register || error "changelog_register failed"
24045
24046         changelog_clear 0 || error "changelog_clear failed"
24047
24048         local size1=$(do_facet $SINGLEMDS \
24049                       $LCTL get_param -n mdd.$mdt.changelog_size)
24050         echo "Changelog size $size1"
24051
24052         rm -rf $DIR/$tdir
24053         $LFS mkdir -i 0 $DIR/$tdir
24054         # change something
24055         mkdir -p $DIR/$tdir/pics/2008/zachy
24056         touch $DIR/$tdir/pics/2008/zachy/timestamp
24057         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
24058         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
24059         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
24060         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
24061         rm $DIR/$tdir/pics/desktop.jpg
24062
24063         local size2=$(do_facet $SINGLEMDS \
24064                       $LCTL get_param -n mdd.$mdt.changelog_size)
24065         echo "Changelog size after work $size2"
24066
24067         (( $size2 > $size1 )) ||
24068                 error "new Changelog size=$size2 less than old size=$size1"
24069 }
24070 run_test 254 "Check changelog size"
24071
24072 ladvise_no_type()
24073 {
24074         local type=$1
24075         local file=$2
24076
24077         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
24078                 awk -F: '{print $2}' | grep $type > /dev/null
24079         if [ $? -ne 0 ]; then
24080                 return 0
24081         fi
24082         return 1
24083 }
24084
24085 ladvise_no_ioctl()
24086 {
24087         local file=$1
24088
24089         lfs ladvise -a willread $file > /dev/null 2>&1
24090         if [ $? -eq 0 ]; then
24091                 return 1
24092         fi
24093
24094         lfs ladvise -a willread $file 2>&1 |
24095                 grep "Inappropriate ioctl for device" > /dev/null
24096         if [ $? -eq 0 ]; then
24097                 return 0
24098         fi
24099         return 1
24100 }
24101
24102 percent() {
24103         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24104 }
24105
24106 # run a random read IO workload
24107 # usage: random_read_iops <filename> <filesize> <iosize>
24108 random_read_iops() {
24109         local file=$1
24110         local fsize=$2
24111         local iosize=${3:-4096}
24112
24113         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24114                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24115 }
24116
24117 drop_file_oss_cache() {
24118         local file="$1"
24119         local nodes="$2"
24120
24121         $LFS ladvise -a dontneed $file 2>/dev/null ||
24122                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24123 }
24124
24125 ladvise_willread_performance()
24126 {
24127         local repeat=10
24128         local average_origin=0
24129         local average_cache=0
24130         local average_ladvise=0
24131
24132         for ((i = 1; i <= $repeat; i++)); do
24133                 echo "Iter $i/$repeat: reading without willread hint"
24134                 cancel_lru_locks osc
24135                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24136                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24137                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24138                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24139
24140                 cancel_lru_locks osc
24141                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24142                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24143                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24144
24145                 cancel_lru_locks osc
24146                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24147                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24148                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24149                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24150                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24151         done
24152         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24153         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24154         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24155
24156         speedup_cache=$(percent $average_cache $average_origin)
24157         speedup_ladvise=$(percent $average_ladvise $average_origin)
24158
24159         echo "Average uncached read: $average_origin"
24160         echo "Average speedup with OSS cached read:" \
24161                 "$average_cache = +$speedup_cache%"
24162         echo "Average speedup with ladvise willread:" \
24163                 "$average_ladvise = +$speedup_ladvise%"
24164
24165         local lowest_speedup=20
24166         if (( ${speedup_cache%.*} < $lowest_speedup )); then
24167                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24168                      "got $speedup_cache%. Skipping ladvise willread check."
24169                 return 0
24170         fi
24171
24172         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24173         # it is still good to run until then to exercise 'ladvise willread'
24174         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24175                 [ "$ost1_FSTYPE" = "zfs" ] &&
24176                 echo "osd-zfs does not support dontneed or drop_caches" &&
24177                 return 0
24178
24179         lowest_speedup=$(bc <<<"scale=2; $speedup_cache / 2")
24180         (( ${speedup_ladvise%.*} > ${lowest_speedup%.*} )) ||
24181                 error_not_in_vm "Speedup with willread is less than " \
24182                         "$lowest_speedup%, got $speedup_ladvise%"
24183 }
24184
24185 test_255a() {
24186         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24187                 skip "lustre < 2.8.54 does not support ladvise "
24188         remote_ost_nodsh && skip "remote OST with nodsh"
24189
24190         stack_trap "rm -f $DIR/$tfile"
24191         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24192
24193         ladvise_no_type willread $DIR/$tfile &&
24194                 skip "willread ladvise is not supported"
24195
24196         ladvise_no_ioctl $DIR/$tfile &&
24197                 skip "ladvise ioctl is not supported"
24198
24199         local size_mb=100
24200         local size=$((size_mb * 1048576))
24201         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24202                 error "dd to $DIR/$tfile failed"
24203
24204         lfs ladvise -a willread $DIR/$tfile ||
24205                 error "Ladvise failed with no range argument"
24206
24207         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24208                 error "Ladvise failed with no -l or -e argument"
24209
24210         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24211                 error "Ladvise failed with only -e argument"
24212
24213         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24214                 error "Ladvise failed with only -l argument"
24215
24216         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24217                 error "End offset should not be smaller than start offset"
24218
24219         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24220                 error "End offset should not be equal to start offset"
24221
24222         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24223                 error "Ladvise failed with overflowing -s argument"
24224
24225         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24226                 error "Ladvise failed with overflowing -e argument"
24227
24228         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24229                 error "Ladvise failed with overflowing -l argument"
24230
24231         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24232                 error "Ladvise succeeded with conflicting -l and -e arguments"
24233
24234         echo "Synchronous ladvise should wait"
24235         local delay=8
24236 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24237         do_nodes $(comma_list $(osts_nodes)) \
24238                 $LCTL set_param fail_val=$delay fail_loc=0x237
24239         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24240                 $LCTL set_param fail_loc=0"
24241
24242         local start_ts=$SECONDS
24243         lfs ladvise -a willread $DIR/$tfile ||
24244                 error "Ladvise failed with no range argument"
24245         local end_ts=$SECONDS
24246         local inteval_ts=$((end_ts - start_ts))
24247
24248         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24249                 error "Synchronous advice didn't wait reply"
24250         fi
24251
24252         echo "Asynchronous ladvise shouldn't wait"
24253         local start_ts=$SECONDS
24254         lfs ladvise -a willread -b $DIR/$tfile ||
24255                 error "Ladvise failed with no range argument"
24256         local end_ts=$SECONDS
24257         local inteval_ts=$((end_ts - start_ts))
24258
24259         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24260                 error "Asynchronous advice blocked"
24261         fi
24262
24263         ladvise_willread_performance
24264 }
24265 run_test 255a "check 'lfs ladvise -a willread'"
24266
24267 facet_meminfo() {
24268         local facet=$1
24269         local info=$2
24270
24271         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24272 }
24273
24274 test_255b() {
24275         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24276                 skip "lustre < 2.8.54 does not support ladvise "
24277         remote_ost_nodsh && skip "remote OST with nodsh"
24278
24279         stack_trap "rm -f $DIR/$tfile"
24280         lfs setstripe -c 1 -i 0 $DIR/$tfile
24281
24282         ladvise_no_type dontneed $DIR/$tfile &&
24283                 skip "dontneed ladvise is not supported"
24284
24285         ladvise_no_ioctl $DIR/$tfile &&
24286                 skip "ladvise ioctl is not supported"
24287
24288         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24289                 [ "$ost1_FSTYPE" = "zfs" ] &&
24290                 skip "zfs-osd does not support 'ladvise dontneed'"
24291
24292         local size_mb=100
24293         local size=$((size_mb * 1048576))
24294         # In order to prevent disturbance of other processes, only check 3/4
24295         # of the memory usage
24296         local kibibytes=$((size_mb * 1024 * 3 / 4))
24297
24298         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24299                 error "dd to $DIR/$tfile failed"
24300
24301         #force write to complete before dropping OST cache & checking memory
24302         sync
24303
24304         local total=$(facet_meminfo ost1 MemTotal)
24305         echo "Total memory: $total KiB"
24306
24307         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24308         local before_read=$(facet_meminfo ost1 Cached)
24309         echo "Cache used before read: $before_read KiB"
24310
24311         lfs ladvise -a willread $DIR/$tfile ||
24312                 error "Ladvise willread failed"
24313         local after_read=$(facet_meminfo ost1 Cached)
24314         echo "Cache used after read: $after_read KiB"
24315
24316         lfs ladvise -a dontneed $DIR/$tfile ||
24317                 error "Ladvise dontneed again failed"
24318         local no_read=$(facet_meminfo ost1 Cached)
24319         echo "Cache used after dontneed ladvise: $no_read KiB"
24320
24321         if [ $total -lt $((before_read + kibibytes)) ]; then
24322                 echo "Memory is too small, abort checking"
24323                 return 0
24324         fi
24325
24326         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24327                 error "Ladvise willread should use more memory" \
24328                         "than $kibibytes KiB"
24329         fi
24330
24331         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24332                 error "Ladvise dontneed should release more memory" \
24333                         "than $kibibytes KiB"
24334         fi
24335 }
24336 run_test 255b "check 'lfs ladvise -a dontneed'"
24337
24338 test_255c() {
24339         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24340                 skip "lustre < 2.10.50 does not support lockahead"
24341
24342         local ost1_imp=$(get_osc_import_name client ost1)
24343         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24344                          cut -d'.' -f2)
24345         local count
24346         local new_count
24347         local difference
24348         local i
24349         local rc
24350
24351         test_mkdir -p $DIR/$tdir
24352         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24353
24354         #test 10 returns only success/failure
24355         i=10
24356         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24357         rc=$?
24358         if [ $rc -eq 255 ]; then
24359                 error "Ladvise test${i} failed, ${rc}"
24360         fi
24361
24362         #test 11 counts lock enqueue requests, all others count new locks
24363         i=11
24364         count=$(do_facet ost1 \
24365                 $LCTL get_param -n ost.OSS.ost.stats)
24366         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24367
24368         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24369         rc=$?
24370         if [ $rc -eq 255 ]; then
24371                 error "Ladvise test${i} failed, ${rc}"
24372         fi
24373
24374         new_count=$(do_facet ost1 \
24375                 $LCTL get_param -n ost.OSS.ost.stats)
24376         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24377                    awk '{ print $2 }')
24378
24379         difference="$((new_count - count))"
24380         if [ $difference -ne $rc ]; then
24381                 error "Ladvise test${i}, bad enqueue count, returned " \
24382                       "${rc}, actual ${difference}"
24383         fi
24384
24385         for i in $(seq 12 21); do
24386                 # If we do not do this, we run the risk of having too many
24387                 # locks and starting lock cancellation while we are checking
24388                 # lock counts.
24389                 cancel_lru_locks osc
24390
24391                 count=$($LCTL get_param -n \
24392                        ldlm.namespaces.$imp_name.lock_unused_count)
24393
24394                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24395                 rc=$?
24396                 if [ $rc -eq 255 ]; then
24397                         error "Ladvise test ${i} failed, ${rc}"
24398                 fi
24399
24400                 new_count=$($LCTL get_param -n \
24401                        ldlm.namespaces.$imp_name.lock_unused_count)
24402                 difference="$((new_count - count))"
24403
24404                 # Test 15 output is divided by 100 to map down to valid return
24405                 if [ $i -eq 15 ]; then
24406                         rc="$((rc * 100))"
24407                 fi
24408
24409                 if [ $difference -ne $rc ]; then
24410                         error "Ladvise test ${i}, bad lock count, returned " \
24411                               "${rc}, actual ${difference}"
24412                 fi
24413         done
24414
24415         #test 22 returns only success/failure
24416         i=22
24417         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24418         rc=$?
24419         if [ $rc -eq 255 ]; then
24420                 error "Ladvise test${i} failed, ${rc}"
24421         fi
24422 }
24423 run_test 255c "suite of ladvise lockahead tests"
24424
24425 test_256() {
24426         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24427         remote_mds_nodsh && skip "remote MDS with nodsh"
24428         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24429         changelog_users $SINGLEMDS | grep "^cl" &&
24430                 skip "active changelog user"
24431
24432         local cl_user
24433         local cat_sl
24434         local mdt_dev
24435
24436         mdt_dev=$(facet_device $SINGLEMDS)
24437         echo $mdt_dev
24438
24439         changelog_register || error "changelog_register failed"
24440
24441         rm -rf $DIR/$tdir
24442         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24443
24444         changelog_clear 0 || error "changelog_clear failed"
24445
24446         # change something
24447         touch $DIR/$tdir/{1..10}
24448
24449         # stop the MDT
24450         stop $SINGLEMDS || error "Fail to stop MDT"
24451
24452         # remount the MDT
24453         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24454                 error "Fail to start MDT"
24455
24456         #after mount new plainllog is used
24457         touch $DIR/$tdir/{11..19}
24458         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24459         stack_trap "rm -f $tmpfile"
24460         cat_sl=$(do_facet $SINGLEMDS "sync; \
24461                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24462                  llog_reader $tmpfile | grep -c type=1064553b")
24463         do_facet $SINGLEMDS llog_reader $tmpfile
24464
24465         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24466
24467         changelog_clear 0 || error "changelog_clear failed"
24468
24469         cat_sl=$(do_facet $SINGLEMDS "sync; \
24470                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24471                  llog_reader $tmpfile | grep -c type=1064553b")
24472
24473         if (( cat_sl == 2 )); then
24474                 error "Empty plain llog was not deleted from changelog catalog"
24475         elif (( cat_sl != 1 )); then
24476                 error "Active plain llog shouldn't be deleted from catalog"
24477         fi
24478 }
24479 run_test 256 "Check llog delete for empty and not full state"
24480
24481 test_257() {
24482         remote_mds_nodsh && skip "remote MDS with nodsh"
24483         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24484                 skip "Need MDS version at least 2.8.55"
24485
24486         test_mkdir $DIR/$tdir
24487
24488         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24489                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24490         stat $DIR/$tdir
24491
24492 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24493         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24494         local facet=mds$((mdtidx + 1))
24495         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24496         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24497
24498         stop $facet || error "stop MDS failed"
24499         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24500                 error "start MDS fail"
24501         wait_recovery_complete $facet
24502 }
24503 run_test 257 "xattr locks are not lost"
24504
24505 # Verify we take the i_mutex when security requires it
24506 test_258a() {
24507 #define OBD_FAIL_IMUTEX_SEC 0x141c
24508         $LCTL set_param fail_loc=0x141c
24509         touch $DIR/$tfile
24510         chmod u+s $DIR/$tfile
24511         chmod a+rwx $DIR/$tfile
24512         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24513         RC=$?
24514         if [ $RC -ne 0 ]; then
24515                 error "error, failed to take i_mutex, rc=$?"
24516         fi
24517         rm -f $DIR/$tfile
24518 }
24519 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24520
24521 # Verify we do NOT take the i_mutex in the normal case
24522 test_258b() {
24523 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24524         $LCTL set_param fail_loc=0x141d
24525         touch $DIR/$tfile
24526         chmod a+rwx $DIR
24527         chmod a+rw $DIR/$tfile
24528         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24529         RC=$?
24530         if [ $RC -ne 0 ]; then
24531                 error "error, took i_mutex unnecessarily, rc=$?"
24532         fi
24533         rm -f $DIR/$tfile
24534
24535 }
24536 run_test 258b "verify i_mutex security behavior"
24537
24538 test_259() {
24539         local file=$DIR/$tfile
24540         local before
24541         local after
24542
24543         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24544
24545         stack_trap "rm -f $file" EXIT
24546
24547         wait_delete_completed
24548         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24549         echo "before: $before"
24550
24551         $LFS setstripe -i 0 -c 1 $file
24552         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24553         sync_all_data
24554         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24555         echo "after write: $after"
24556
24557 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24558         do_facet ost1 $LCTL set_param fail_loc=0x2301
24559         $TRUNCATE $file 0
24560         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24561         echo "after truncate: $after"
24562
24563         stop ost1
24564         do_facet ost1 $LCTL set_param fail_loc=0
24565         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24566         sleep 2
24567         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24568         echo "after restart: $after"
24569         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24570                 error "missing truncate?"
24571
24572         return 0
24573 }
24574 run_test 259 "crash at delayed truncate"
24575
24576 test_260() {
24577 #define OBD_FAIL_MDC_CLOSE               0x806
24578         $LCTL set_param fail_loc=0x80000806
24579         touch $DIR/$tfile
24580
24581 }
24582 run_test 260 "Check mdc_close fail"
24583
24584 ### Data-on-MDT sanity tests ###
24585 test_270a() {
24586         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24587                 skip "Need MDS version at least 2.10.55 for DoM"
24588
24589         # create DoM file
24590         local dom=$DIR/$tdir/dom_file
24591         local tmp=$DIR/$tdir/tmp_file
24592
24593         mkdir_on_mdt0 $DIR/$tdir
24594
24595         # basic checks for DoM component creation
24596         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24597                 error "Can set MDT layout to non-first entry"
24598
24599         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24600                 error "Can define multiple entries as MDT layout"
24601
24602         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24603
24604         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24605         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24606         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24607
24608         local mdtidx=$($LFS getstripe -m $dom)
24609         local mdtname=MDT$(printf %04x $mdtidx)
24610         local facet=mds$((mdtidx + 1))
24611         local space_check=1
24612
24613         # Skip free space checks with ZFS
24614         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24615
24616         # write
24617         sync
24618         local size_tmp=$((65536 * 3))
24619         local mdtfree1=$(do_facet $facet \
24620                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24621
24622         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24623         # check also direct IO along write
24624         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24625         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24626         sync
24627         cmp $tmp $dom || error "file data is different"
24628         [ $(stat -c%s $dom) == $size_tmp ] ||
24629                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24630         if [ $space_check == 1 ]; then
24631                 local mdtfree2=$(do_facet $facet \
24632                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24633
24634                 # increase in usage from by $size_tmp
24635                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24636                         error "MDT free space wrong after write: " \
24637                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24638         fi
24639
24640         # truncate
24641         local size_dom=10000
24642
24643         $TRUNCATE $dom $size_dom
24644         [ $(stat -c%s $dom) == $size_dom ] ||
24645                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24646         if [ $space_check == 1 ]; then
24647                 mdtfree1=$(do_facet $facet \
24648                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24649                 # decrease in usage from $size_tmp to new $size_dom
24650                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24651                   $(((size_tmp - size_dom) / 1024)) ] ||
24652                         error "MDT free space is wrong after truncate: " \
24653                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24654         fi
24655
24656         # append
24657         cat $tmp >> $dom
24658         sync
24659         size_dom=$((size_dom + size_tmp))
24660         [ $(stat -c%s $dom) == $size_dom ] ||
24661                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24662         if [ $space_check == 1 ]; then
24663                 mdtfree2=$(do_facet $facet \
24664                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24665                 # increase in usage by $size_tmp from previous
24666                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24667                         error "MDT free space is wrong after append: " \
24668                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24669         fi
24670
24671         # delete
24672         rm $dom
24673         if [ $space_check == 1 ]; then
24674                 mdtfree1=$(do_facet $facet \
24675                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24676                 # decrease in usage by $size_dom from previous
24677                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24678                         error "MDT free space is wrong after removal: " \
24679                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24680         fi
24681
24682         # combined striping
24683         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24684                 error "Can't create DoM + OST striping"
24685
24686         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24687         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24688         # check also direct IO along write
24689         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24690         sync
24691         cmp $tmp $dom || error "file data is different"
24692         [ $(stat -c%s $dom) == $size_tmp ] ||
24693                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24694         rm $dom $tmp
24695
24696         return 0
24697 }
24698 run_test 270a "DoM: basic functionality tests"
24699
24700 test_270b() {
24701         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24702                 skip "Need MDS version at least 2.10.55"
24703
24704         local dom=$DIR/$tdir/dom_file
24705         local max_size=1048576
24706
24707         mkdir -p $DIR/$tdir
24708         $LFS setstripe -E $max_size -L mdt $dom
24709
24710         # truncate over the limit
24711         $TRUNCATE $dom $(($max_size + 1)) &&
24712                 error "successful truncate over the maximum size"
24713         # write over the limit
24714         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24715                 error "successful write over the maximum size"
24716         # append over the limit
24717         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24718         echo "12345" >> $dom && error "successful append over the maximum size"
24719         rm $dom
24720
24721         return 0
24722 }
24723 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24724
24725 test_270c() {
24726         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24727                 skip "Need MDS version at least 2.10.55"
24728
24729         mkdir -p $DIR/$tdir
24730         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24731
24732         # check files inherit DoM EA
24733         touch $DIR/$tdir/first
24734         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24735                 error "bad pattern"
24736         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24737                 error "bad stripe count"
24738         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24739                 error "bad stripe size"
24740
24741         # check directory inherits DoM EA and uses it as default
24742         mkdir $DIR/$tdir/subdir
24743         touch $DIR/$tdir/subdir/second
24744         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24745                 error "bad pattern in sub-directory"
24746         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24747                 error "bad stripe count in sub-directory"
24748         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24749                 error "bad stripe size in sub-directory"
24750         return 0
24751 }
24752 run_test 270c "DoM: DoM EA inheritance tests"
24753
24754 test_270d() {
24755         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24756                 skip "Need MDS version at least 2.10.55"
24757
24758         mkdir -p $DIR/$tdir
24759         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24760
24761         # inherit default DoM striping
24762         mkdir $DIR/$tdir/subdir
24763         touch $DIR/$tdir/subdir/f1
24764
24765         # change default directory striping
24766         $LFS setstripe -c 1 $DIR/$tdir/subdir
24767         touch $DIR/$tdir/subdir/f2
24768         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24769                 error "wrong default striping in file 2"
24770         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24771                 error "bad pattern in file 2"
24772         return 0
24773 }
24774 run_test 270d "DoM: change striping from DoM to RAID0"
24775
24776 test_270e() {
24777         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24778                 skip "Need MDS version at least 2.10.55"
24779
24780         mkdir -p $DIR/$tdir/dom
24781         mkdir -p $DIR/$tdir/norm
24782         DOMFILES=20
24783         NORMFILES=10
24784         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24785         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24786
24787         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24788         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24789
24790         # find DoM files by layout
24791         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24792         [ $NUM -eq  $DOMFILES ] ||
24793                 error "lfs find -L: found $NUM, expected $DOMFILES"
24794         echo "Test 1: lfs find 20 DOM files by layout: OK"
24795
24796         # there should be 1 dir with default DOM striping
24797         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24798         [ $NUM -eq  1 ] ||
24799                 error "lfs find -L: found $NUM, expected 1 dir"
24800         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24801
24802         # find DoM files by stripe size
24803         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24804         [ $NUM -eq  $DOMFILES ] ||
24805                 error "lfs find -S: found $NUM, expected $DOMFILES"
24806         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24807
24808         # find files by stripe offset except DoM files
24809         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24810         [ $NUM -eq  $NORMFILES ] ||
24811                 error "lfs find -i: found $NUM, expected $NORMFILES"
24812         echo "Test 5: lfs find no DOM files by stripe index: OK"
24813         return 0
24814 }
24815 run_test 270e "DoM: lfs find with DoM files test"
24816
24817 test_270f() {
24818         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24819                 skip "Need MDS version at least 2.10.55"
24820
24821         local mdtname=${FSNAME}-MDT0000-mdtlov
24822         local dom=$DIR/$tdir/dom_file
24823         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24824                                                 lod.$mdtname.dom_stripesize)
24825         local dom_limit=131072
24826
24827         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24828         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24829                                                 lod.$mdtname.dom_stripesize)
24830         [ ${dom_limit} -eq ${dom_current} ] ||
24831                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24832
24833         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24834         $LFS setstripe -d $DIR/$tdir
24835         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24836                 error "Can't set directory default striping"
24837
24838         # exceed maximum stripe size
24839         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24840                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24841         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24842                 error "Able to create DoM component size more than LOD limit"
24843
24844         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24845         dom_current=$(do_facet mds1 $LCTL get_param -n \
24846                                                 lod.$mdtname.dom_stripesize)
24847         [ 0 -eq ${dom_current} ] ||
24848                 error "Can't set zero DoM stripe limit"
24849         rm $dom
24850
24851         # attempt to create DoM file on server with disabled DoM should
24852         # remove DoM entry from layout and be succeed
24853         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24854                 error "Can't create DoM file (DoM is disabled)"
24855         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24856                 error "File has DoM component while DoM is disabled"
24857         rm $dom
24858
24859         # attempt to create DoM file with only DoM stripe should return error
24860         $LFS setstripe -E $dom_limit -L mdt $dom &&
24861                 error "Able to create DoM-only file while DoM is disabled"
24862
24863         # too low values to be aligned with smallest stripe size 64K
24864         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24865         dom_current=$(do_facet mds1 $LCTL get_param -n \
24866                                                 lod.$mdtname.dom_stripesize)
24867         [ 30000 -eq ${dom_current} ] &&
24868                 error "Can set too small DoM stripe limit"
24869
24870         # 64K is a minimal stripe size in Lustre, expect limit of that size
24871         [ 65536 -eq ${dom_current} ] ||
24872                 error "Limit is not set to 64K but ${dom_current}"
24873
24874         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24875         dom_current=$(do_facet mds1 $LCTL get_param -n \
24876                                                 lod.$mdtname.dom_stripesize)
24877         echo $dom_current
24878         [ 2147483648 -eq ${dom_current} ] &&
24879                 error "Can set too large DoM stripe limit"
24880
24881         do_facet mds1 $LCTL set_param -n \
24882                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24883         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24884                 error "Can't create DoM component size after limit change"
24885         do_facet mds1 $LCTL set_param -n \
24886                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24887         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24888                 error "Can't create DoM file after limit decrease"
24889         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24890                 error "Can create big DoM component after limit decrease"
24891         touch ${dom}_def ||
24892                 error "Can't create file with old default layout"
24893
24894         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24895         return 0
24896 }
24897 run_test 270f "DoM: maximum DoM stripe size checks"
24898
24899 test_270g() {
24900         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24901                 skip "Need MDS version at least 2.13.52"
24902         local dom=$DIR/$tdir/$tfile
24903
24904         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24905         local lodname=${FSNAME}-MDT0000-mdtlov
24906
24907         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24908         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24909         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24910         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24911
24912         local dom_limit=1024
24913         local dom_threshold="50%"
24914
24915         $LFS setstripe -d $DIR/$tdir
24916         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24917                 error "Can't set directory default striping"
24918
24919         do_facet mds1 $LCTL set_param -n \
24920                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24921         # set 0 threshold and create DOM file to change tunable stripesize
24922         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24923         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24924                 error "Failed to create $dom file"
24925         # now tunable dom_cur_stripesize should reach maximum
24926         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24927                                         lod.${lodname}.dom_stripesize_cur_kb)
24928         [[ $dom_current == $dom_limit ]] ||
24929                 error "Current DOM stripesize is not maximum"
24930         rm $dom
24931
24932         # set threshold for further tests
24933         do_facet mds1 $LCTL set_param -n \
24934                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24935         echo "DOM threshold is $dom_threshold free space"
24936         local dom_def
24937         local dom_set
24938         # Spoof bfree to exceed threshold
24939         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24940         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24941         for spfree in 40 20 0 15 30 55; do
24942                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24943                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24944                         error "Failed to create $dom file"
24945                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24946                                         lod.${lodname}.dom_stripesize_cur_kb)
24947                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24948                 [[ $dom_def != $dom_current ]] ||
24949                         error "Default stripe size was not changed"
24950                 if (( spfree > 0 )) ; then
24951                         dom_set=$($LFS getstripe -S $dom)
24952                         (( dom_set == dom_def * 1024 )) ||
24953                                 error "DOM component size is still old"
24954                 else
24955                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24956                                 error "DoM component is set with no free space"
24957                 fi
24958                 rm $dom
24959                 dom_current=$dom_def
24960         done
24961 }
24962 run_test 270g "DoM: default DoM stripe size depends on free space"
24963
24964 test_270h() {
24965         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24966                 skip "Need MDS version at least 2.13.53"
24967
24968         local mdtname=${FSNAME}-MDT0000-mdtlov
24969         local dom=$DIR/$tdir/$tfile
24970         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24971
24972         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24973         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24974
24975         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24976         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24977                 error "can't create OST file"
24978         # mirrored file with DOM entry in the second mirror
24979         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24980                 error "can't create mirror with DoM component"
24981
24982         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24983
24984         # DOM component in the middle and has other enries in the same mirror,
24985         # should succeed but lost DoM component
24986         $LFS setstripe --copy=${dom}_1 $dom ||
24987                 error "Can't create file from OST|DOM mirror layout"
24988         # check new file has no DoM layout after all
24989         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24990                 error "File has DoM component while DoM is disabled"
24991 }
24992 run_test 270h "DoM: DoM stripe removal when disabled on server"
24993
24994 test_270i() {
24995         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24996                 skip "Need MDS version at least 2.14.54"
24997
24998         mkdir $DIR/$tdir
24999         # DoM with plain layout
25000         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
25001                 error "default plain layout with DoM must fail"
25002         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
25003                 error "setstripe plain file layout with DoM must fail"
25004         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
25005                 error "default DoM layout with bad striping must fail"
25006         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
25007                 error "setstripe to DoM layout with bad striping must fail"
25008         return 0
25009 }
25010 run_test 270i "DoM: setting invalid DoM striping should fail"
25011
25012 test_270j() {
25013         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
25014                 skip "Need MDS version at least 2.15.55.203"
25015
25016         local dom=$DIR/$tdir/$tfile
25017         local odv
25018         local ndv
25019
25020         mkdir -p $DIR/$tdir
25021
25022         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25023
25024         odv=$($LFS data_version $dom)
25025         chmod 666 $dom
25026         mv $dom ${dom}_moved
25027         link ${dom}_moved $dom
25028         setfattr -n user.attrx -v "some_attr" $dom
25029         ndv=$($LFS data_version $dom)
25030         (( $ndv == $odv )) ||
25031                 error "data version was changed by metadata operations"
25032
25033         dd if=/dev/urandom of=$dom bs=1M count=1 ||
25034                 error "failed to write data into $dom"
25035         cancel_lru_locks mdc
25036         ndv=$($LFS data_version $dom)
25037         (( $ndv != $odv )) ||
25038                 error "data version wasn't changed on write"
25039
25040         odv=$ndv
25041         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
25042         ndv=$($LFS data_version $dom)
25043         (( $ndv != $odv )) ||
25044                 error "data version wasn't changed on truncate down"
25045
25046         odv=$ndv
25047         $TRUNCATE $dom 25000
25048         ndv=$($LFS data_version $dom)
25049         (( $ndv != $odv )) ||
25050                 error "data version wasn't changed on truncate up"
25051
25052         # check also fallocate for ldiskfs
25053         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
25054                 odv=$ndv
25055                 fallocate -l 1048576 $dom
25056                 ndv=$($LFS data_version $dom)
25057                 (( $ndv != $odv )) ||
25058                         error "data version wasn't changed on fallocate"
25059
25060                 odv=$ndv
25061                 fallocate -p --offset 4096 -l 4096 $dom
25062                 ndv=$($LFS data_version $dom)
25063                 (( $ndv != $odv )) ||
25064                         error "data version wasn't changed on fallocate punch"
25065         fi
25066 }
25067 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
25068
25069 test_271a() {
25070         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25071                 skip "Need MDS version at least 2.10.55"
25072
25073         local dom=$DIR/$tdir/dom
25074
25075         mkdir -p $DIR/$tdir
25076
25077         $LFS setstripe -E 1024K -L mdt $dom
25078
25079         lctl set_param -n mdc.*.stats=clear
25080         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25081         cat $dom > /dev/null
25082         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
25083         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
25084         ls $dom
25085         rm -f $dom
25086 }
25087 run_test 271a "DoM: data is cached for read after write"
25088
25089 test_271b() {
25090         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25091                 skip "Need MDS version at least 2.10.55"
25092
25093         local dom=$DIR/$tdir/dom
25094
25095         mkdir -p $DIR/$tdir
25096
25097         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25098
25099         lctl set_param -n mdc.*.stats=clear
25100         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25101         cancel_lru_locks mdc
25102         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25103         # second stat to check size is cached on client
25104         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25105         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25106         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25107         rm -f $dom
25108 }
25109 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25110
25111 test_271ba() {
25112         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25113                 skip "Need MDS version at least 2.10.55"
25114
25115         local dom=$DIR/$tdir/dom
25116
25117         mkdir -p $DIR/$tdir
25118
25119         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25120
25121         lctl set_param -n mdc.*.stats=clear
25122         lctl set_param -n osc.*.stats=clear
25123         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25124         cancel_lru_locks mdc
25125         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25126         # second stat to check size is cached on client
25127         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25128         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25129         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25130         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25131         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25132         rm -f $dom
25133 }
25134 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25135
25136
25137 get_mdc_stats() {
25138         local mdtidx=$1
25139         local param=$2
25140         local mdt=MDT$(printf %04x $mdtidx)
25141
25142         if [ -z $param ]; then
25143                 lctl get_param -n mdc.*$mdt*.stats
25144         else
25145                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25146         fi
25147 }
25148
25149 test_271c() {
25150         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25151                 skip "Need MDS version at least 2.10.55"
25152
25153         local dom=$DIR/$tdir/dom
25154
25155         mkdir -p $DIR/$tdir
25156
25157         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25158
25159         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25160         local facet=mds$((mdtidx + 1))
25161
25162         cancel_lru_locks mdc
25163         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25164         createmany -o $dom 1000
25165         lctl set_param -n mdc.*.stats=clear
25166         smalliomany -w $dom 1000 200
25167         get_mdc_stats $mdtidx
25168         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25169         # Each file has 1 open, 1 IO enqueues, total 2000
25170         # but now we have also +1 getxattr for security.capability, total 3000
25171         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25172         unlinkmany $dom 1000
25173
25174         cancel_lru_locks mdc
25175         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25176         createmany -o $dom 1000
25177         lctl set_param -n mdc.*.stats=clear
25178         smalliomany -w $dom 1000 200
25179         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25180         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25181         # for OPEN and IO lock.
25182         [ $((enq - enq_2)) -ge 1000 ] ||
25183                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25184         unlinkmany $dom 1000
25185         return 0
25186 }
25187 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25188
25189 cleanup_271def_tests() {
25190         trap 0
25191         rm -f $1
25192 }
25193
25194 test_271d() {
25195         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25196                 skip "Need MDS version at least 2.10.57"
25197
25198         local dom=$DIR/$tdir/dom
25199         local tmp=$TMP/$tfile
25200         trap "cleanup_271def_tests $tmp" EXIT
25201
25202         mkdir -p $DIR/$tdir
25203
25204         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25205
25206         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25207
25208         cancel_lru_locks mdc
25209         dd if=/dev/urandom of=$tmp bs=1000 count=1
25210         dd if=$tmp of=$dom bs=1000 count=1
25211         cancel_lru_locks mdc
25212
25213         cat /etc/hosts >> $tmp
25214         lctl set_param -n mdc.*.stats=clear
25215
25216         # append data to the same file it should update local page
25217         echo "Append to the same page"
25218         cat /etc/hosts >> $dom
25219         local num=$(get_mdc_stats $mdtidx ost_read)
25220         local ra=$(get_mdc_stats $mdtidx req_active)
25221         local rw=$(get_mdc_stats $mdtidx req_waittime)
25222
25223         [ -z $num ] || error "$num READ RPC occured"
25224         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25225         echo "... DONE"
25226
25227         # compare content
25228         cmp $tmp $dom || error "file miscompare"
25229
25230         cancel_lru_locks mdc
25231         lctl set_param -n mdc.*.stats=clear
25232
25233         echo "Open and read file"
25234         cat $dom > /dev/null
25235         local num=$(get_mdc_stats $mdtidx ost_read)
25236         local ra=$(get_mdc_stats $mdtidx req_active)
25237         local rw=$(get_mdc_stats $mdtidx req_waittime)
25238
25239         [ -z $num ] || error "$num READ RPC occured"
25240         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25241         echo "... DONE"
25242
25243         # compare content
25244         cmp $tmp $dom || error "file miscompare"
25245
25246         return 0
25247 }
25248 run_test 271d "DoM: read on open (1K file in reply buffer)"
25249
25250 test_271f() {
25251         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25252                 skip "Need MDS version at least 2.10.57"
25253
25254         local dom=$DIR/$tdir/dom
25255         local tmp=$TMP/$tfile
25256         trap "cleanup_271def_tests $tmp" EXIT
25257
25258         mkdir -p $DIR/$tdir
25259
25260         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25261
25262         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25263
25264         cancel_lru_locks mdc
25265         dd if=/dev/urandom of=$tmp bs=265000 count=1
25266         dd if=$tmp of=$dom bs=265000 count=1
25267         cancel_lru_locks mdc
25268         cat /etc/hosts >> $tmp
25269         lctl set_param -n mdc.*.stats=clear
25270
25271         echo "Append to the same page"
25272         cat /etc/hosts >> $dom
25273         local num=$(get_mdc_stats $mdtidx ost_read)
25274         local ra=$(get_mdc_stats $mdtidx req_active)
25275         local rw=$(get_mdc_stats $mdtidx req_waittime)
25276
25277         [ -z $num ] || error "$num READ RPC occured"
25278         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25279         echo "... DONE"
25280
25281         # compare content
25282         cmp $tmp $dom || error "file miscompare"
25283
25284         cancel_lru_locks mdc
25285         lctl set_param -n mdc.*.stats=clear
25286
25287         echo "Open and read file"
25288         cat $dom > /dev/null
25289         local num=$(get_mdc_stats $mdtidx ost_read)
25290         local ra=$(get_mdc_stats $mdtidx req_active)
25291         local rw=$(get_mdc_stats $mdtidx req_waittime)
25292
25293         [ -z $num ] && num=0
25294         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25295         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25296         echo "... DONE"
25297
25298         # compare content
25299         cmp $tmp $dom || error "file miscompare"
25300
25301         return 0
25302 }
25303 run_test 271f "DoM: read on open (200K file and read tail)"
25304
25305 test_271g() {
25306         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25307                 skip "Skipping due to old client or server version"
25308
25309         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25310         # to get layout
25311         $CHECKSTAT -t file $DIR1/$tfile
25312
25313         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25314         MULTIOP_PID=$!
25315         sleep 1
25316         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25317         $LCTL set_param fail_loc=0x80000314
25318         rm $DIR1/$tfile || error "Unlink fails"
25319         RC=$?
25320         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25321         [ $RC -eq 0 ] || error "Failed write to stale object"
25322 }
25323 run_test 271g "Discard DoM data vs client flush race"
25324
25325 test_272a() {
25326         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25327                 skip "Need MDS version at least 2.11.50"
25328
25329         local dom=$DIR/$tdir/dom
25330         mkdir -p $DIR/$tdir
25331
25332         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25333         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25334                 error "failed to write data into $dom"
25335         local old_md5=$(md5sum $dom)
25336
25337         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25338                 error "failed to migrate to the same DoM component"
25339
25340         local new_md5=$(md5sum $dom)
25341
25342         [ "$old_md5" == "$new_md5" ] ||
25343                 error "md5sum differ: $old_md5, $new_md5"
25344
25345         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25346                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25347 }
25348 run_test 272a "DoM migration: new layout with the same DOM component"
25349
25350 test_272b() {
25351         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25352                 skip "Need MDS version at least 2.11.50"
25353
25354         local dom=$DIR/$tdir/dom
25355         mkdir -p $DIR/$tdir
25356         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25357         stack_trap "rm -rf $DIR/$tdir"
25358
25359         local mdtidx=$($LFS getstripe -m $dom)
25360         local mdtname=MDT$(printf %04x $mdtidx)
25361         local facet=mds$((mdtidx + 1))
25362
25363         local mdtfree1=$(do_facet $facet \
25364                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25365         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25366                 error "failed to write data into $dom"
25367         local old_md5=$(md5sum $dom)
25368         cancel_lru_locks mdc
25369         local mdtfree1=$(do_facet $facet \
25370                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25371
25372         $LFS migrate -c2 $dom ||
25373                 error "failed to migrate to the new composite layout"
25374         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25375                 error "MDT stripe was not removed"
25376         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25377                 error "$dir1 shouldn't have DATAVER EA"
25378
25379         cancel_lru_locks mdc
25380         local new_md5=$(md5sum $dom)
25381         [ "$old_md5" == "$new_md5" ] ||
25382                 error "$old_md5 != $new_md5"
25383
25384         # Skip free space checks with ZFS
25385         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25386                 local mdtfree2=$(do_facet $facet \
25387                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25388                 [ $mdtfree2 -gt $mdtfree1 ] ||
25389                         error "MDT space is not freed after migration"
25390         fi
25391         return 0
25392 }
25393 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25394
25395 test_272c() {
25396         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25397                 skip "Need MDS version at least 2.11.50"
25398
25399         local dom=$DIR/$tdir/$tfile
25400         mkdir -p $DIR/$tdir
25401         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25402         stack_trap "rm -rf $DIR/$tdir"
25403
25404         local mdtidx=$($LFS getstripe -m $dom)
25405         local mdtname=MDT$(printf %04x $mdtidx)
25406         local facet=mds$((mdtidx + 1))
25407
25408         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25409                 error "failed to write data into $dom"
25410         local old_md5=$(md5sum $dom)
25411         cancel_lru_locks mdc
25412         local mdtfree1=$(do_facet $facet \
25413                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25414
25415         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25416                 error "failed to migrate to the new composite layout"
25417         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25418                 error "MDT stripe was not removed"
25419
25420         cancel_lru_locks mdc
25421         local new_md5=$(md5sum $dom)
25422         [ "$old_md5" == "$new_md5" ] ||
25423                 error "$old_md5 != $new_md5"
25424
25425         # Skip free space checks with ZFS
25426         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25427                 local mdtfree2=$(do_facet $facet \
25428                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25429                 [ $mdtfree2 -gt $mdtfree1 ] ||
25430                         error "MDS space is not freed after migration"
25431         fi
25432         return 0
25433 }
25434 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25435
25436 test_272d() {
25437         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25438                 skip "Need MDS version at least 2.12.55"
25439
25440         local dom=$DIR/$tdir/$tfile
25441         mkdir -p $DIR/$tdir
25442         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25443
25444         local mdtidx=$($LFS getstripe -m $dom)
25445         local mdtname=MDT$(printf %04x $mdtidx)
25446         local facet=mds$((mdtidx + 1))
25447
25448         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25449                 error "failed to write data into $dom"
25450         local old_md5=$(md5sum $dom)
25451         cancel_lru_locks mdc
25452         local mdtfree1=$(do_facet $facet \
25453                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25454
25455         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25456                 error "failed mirroring to the new composite layout"
25457         $LFS mirror resync $dom ||
25458                 error "failed mirror resync"
25459         $LFS mirror split --mirror-id 1 -d $dom ||
25460                 error "failed mirror split"
25461
25462         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25463                 error "MDT stripe was not removed"
25464
25465         cancel_lru_locks mdc
25466         local new_md5=$(md5sum $dom)
25467         [ "$old_md5" == "$new_md5" ] ||
25468                 error "$old_md5 != $new_md5"
25469
25470         # Skip free space checks with ZFS
25471         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25472                 local mdtfree2=$(do_facet $facet \
25473                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25474                 [ $mdtfree2 -gt $mdtfree1 ] ||
25475                         error "MDS space is not freed after DOM mirror deletion"
25476         fi
25477         return 0
25478 }
25479 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25480
25481 test_272e() {
25482         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25483                 skip "Need MDS version at least 2.12.55"
25484
25485         local dom=$DIR/$tdir/$tfile
25486         mkdir -p $DIR/$tdir
25487         $LFS setstripe -c 2 $dom
25488
25489         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25490                 error "failed to write data into $dom"
25491         local old_md5=$(md5sum $dom)
25492         cancel_lru_locks
25493
25494         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25495                 error "failed mirroring to the DOM layout"
25496         $LFS mirror resync $dom ||
25497                 error "failed mirror resync"
25498         $LFS mirror split --mirror-id 1 -d $dom ||
25499                 error "failed mirror split"
25500
25501         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25502                 error "MDT stripe wasn't set"
25503
25504         cancel_lru_locks
25505         local new_md5=$(md5sum $dom)
25506         [ "$old_md5" == "$new_md5" ] ||
25507                 error "$old_md5 != $new_md5"
25508
25509         return 0
25510 }
25511 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25512
25513 test_272f() {
25514         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25515                 skip "Need MDS version at least 2.12.55"
25516
25517         local dom=$DIR/$tdir/$tfile
25518         mkdir -p $DIR/$tdir
25519         $LFS setstripe -c 2 $dom
25520
25521         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25522                 error "failed to write data into $dom"
25523         local old_md5=$(md5sum $dom)
25524         cancel_lru_locks
25525
25526         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25527                 error "failed migrating to the DOM file"
25528
25529         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25530                 error "MDT stripe wasn't set"
25531
25532         cancel_lru_locks
25533         local new_md5=$(md5sum $dom)
25534         [ "$old_md5" != "$new_md5" ] &&
25535                 error "$old_md5 != $new_md5"
25536
25537         return 0
25538 }
25539 run_test 272f "DoM migration: OST-striped file to DOM file"
25540
25541 test_273a() {
25542         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25543                 skip "Need MDS version at least 2.11.50"
25544
25545         # Layout swap cannot be done if either file has DOM component,
25546         # this will never be supported, migration should be used instead
25547
25548         local dom=$DIR/$tdir/$tfile
25549         mkdir -p $DIR/$tdir
25550
25551         $LFS setstripe -c2 ${dom}_plain
25552         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25553         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25554                 error "can swap layout with DoM component"
25555         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25556                 error "can swap layout with DoM component"
25557
25558         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25559         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25560                 error "can swap layout with DoM component"
25561         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25562                 error "can swap layout with DoM component"
25563         return 0
25564 }
25565 run_test 273a "DoM: layout swapping should fail with DOM"
25566
25567 test_273b() {
25568         mkdir -p $DIR/$tdir
25569         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25570
25571 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25572         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25573
25574         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25575 }
25576 run_test 273b "DoM: race writeback and object destroy"
25577
25578 test_273c() {
25579         mkdir -p $DIR/$tdir
25580         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25581
25582         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25583         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25584
25585         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25586 }
25587 run_test 273c "race writeback and object destroy"
25588
25589 test_275() {
25590         remote_ost_nodsh && skip "remote OST with nodsh"
25591         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25592                 skip "Need OST version >= 2.10.57"
25593
25594         local file=$DIR/$tfile
25595         local oss
25596
25597         oss=$(comma_list $(osts_nodes))
25598
25599         dd if=/dev/urandom of=$file bs=1M count=2 ||
25600                 error "failed to create a file"
25601         stack_trap "rm -f $file"
25602         cancel_lru_locks osc
25603
25604         #lock 1
25605         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25606                 error "failed to read a file"
25607
25608 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25609         $LCTL set_param fail_loc=0x8000031f
25610
25611         cancel_lru_locks osc &
25612         sleep 1
25613
25614 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25615         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25616         #IO takes another lock, but matches the PENDING one
25617         #and places it to the IO RPC
25618         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25619                 error "failed to read a file with PENDING lock"
25620 }
25621 run_test 275 "Read on a canceled duplicate lock"
25622
25623 test_276() {
25624         remote_ost_nodsh && skip "remote OST with nodsh"
25625         local pid
25626
25627         do_facet ost1 "(while true; do \
25628                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25629                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25630         pid=$!
25631
25632         for LOOP in $(seq 20); do
25633                 stop ost1
25634                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25635         done
25636         kill -9 $pid
25637         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25638                 rm $TMP/sanity_276_pid"
25639 }
25640 run_test 276 "Race between mount and obd_statfs"
25641
25642 test_277() {
25643         $LCTL set_param ldlm.namespaces.*.lru_size=0
25644         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25645         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25646                           awk '/^used_mb/ { print $2 }')
25647         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25648         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25649                 oflag=direct conv=notrunc
25650         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25651                     awk '/^used_mb/ { print $2 }')
25652         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25653 }
25654 run_test 277 "Direct IO shall drop page cache"
25655
25656 test_278() {
25657         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25658         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25659         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25660                 skip "needs the same host for mdt1 mdt2" && return
25661
25662         local pid1
25663         local pid2
25664
25665 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25666         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25667         stop mds2 &
25668         pid2=$!
25669
25670         stop mds1
25671
25672         echo "Starting MDTs"
25673         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25674         wait $pid2
25675 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25676 #will return NULL
25677         do_facet mds2 $LCTL set_param fail_loc=0
25678
25679         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25680         wait_recovery_complete mds2
25681 }
25682 run_test 278 "Race starting MDS between MDTs stop/start"
25683
25684 test_280() {
25685         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25686                 skip "Need MGS version at least 2.13.52"
25687         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25688         combined_mgs_mds || skip "needs combined MGS/MDT"
25689
25690         umount_client $MOUNT
25691 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25692         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25693
25694         mount_client $MOUNT &
25695         sleep 1
25696         stop mgs || error "stop mgs failed"
25697         #for a race mgs would crash
25698         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25699         # make sure we unmount client before remounting
25700         wait
25701         umount_client $MOUNT
25702         mount_client $MOUNT || error "mount client failed"
25703 }
25704 run_test 280 "Race between MGS umount and client llog processing"
25705
25706 cleanup_test_300() {
25707         trap 0
25708         umask $SAVE_UMASK
25709 }
25710
25711 test_striped_dir() {
25712         local mdt_index=$1
25713         local stripe_count=$2
25714         local overstriping=$3
25715         local stripe_index
25716         local getstripe_count
25717
25718         mkdir -p $DIR/$tdir
25719
25720         SAVE_UMASK=$(umask)
25721         trap cleanup_test_300 RETURN EXIT
25722
25723         if [ -z $overstriping ]; then
25724                 $LFS setdirstripe -i $mdt_index -c $stripe_count -H all_char \
25725                                         -o 755 $DIR/$tdir/striped_dir ||
25726                         error "set striped dir error"
25727         else
25728                 $LFS setdirstripe -i $mdt_index -C $stripe_count -H all_char \
25729                                         -o 755 $DIR/$tdir/striped_dir ||
25730                         error "set striped dir error"
25731         fi
25732
25733         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25734         [ "$mode" = "755" ] || error "expect 755 got $mode"
25735
25736         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25737                 error "getdirstripe failed"
25738         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25739         if [ "$getstripe_count" != "$stripe_count" ]; then
25740                 error "1:stripe_count is $getstripe_count, expect $stripe_count"
25741         fi
25742         getstripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25743         if [ "$getstripe_count" != "$stripe_count" ]; then
25744                 error "2:stripe_count is $getstripe_count, expect $stripe_count"
25745         fi
25746
25747         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25748         if [ "$stripe_index" != "$mdt_index" ]; then
25749                 error "stripe_index is $stripe_index, expect $mdt_index"
25750         fi
25751
25752         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25753                 error "nlink error after create striped dir"
25754
25755         mkdir $DIR/$tdir/striped_dir/a
25756         mkdir $DIR/$tdir/striped_dir/b
25757
25758         stat $DIR/$tdir/striped_dir/a ||
25759                 error "create dir under striped dir failed"
25760         stat $DIR/$tdir/striped_dir/b ||
25761                 error "create dir under striped dir failed"
25762
25763         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25764                 error "nlink error after mkdir"
25765
25766         rmdir $DIR/$tdir/striped_dir/a
25767         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25768                 error "nlink error after rmdir"
25769
25770         rmdir $DIR/$tdir/striped_dir/b
25771         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25772                 error "nlink error after rmdir"
25773
25774         chattr +i $DIR/$tdir/striped_dir
25775         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25776                 error "immutable flags not working under striped dir!"
25777         chattr -i $DIR/$tdir/striped_dir
25778
25779         rmdir $DIR/$tdir/striped_dir ||
25780                 error "rmdir striped dir error"
25781
25782         cleanup_test_300
25783
25784         true
25785 }
25786
25787 test_300a() {
25788         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25789                 skip "skipped for lustre < 2.7.0"
25790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25792
25793         test_striped_dir 0 2 || error "failed on striped dir on MDT0"
25794         test_striped_dir 1 2 || error "failed on striped dir on MDT0"
25795 }
25796 run_test 300a "basic striped dir sanity test"
25797
25798 test_300b() {
25799         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25800                 skip "skipped for lustre < 2.7.0"
25801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25802         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25803
25804         local i
25805         local mtime1
25806         local mtime2
25807         local mtime3
25808
25809         test_mkdir $DIR/$tdir || error "mkdir fail"
25810         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25811                 error "set striped dir error"
25812         for i in {0..9}; do
25813                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25814                 sleep 1
25815                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25816                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25817                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25818                 sleep 1
25819                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25820                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25821                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25822         done
25823         true
25824 }
25825 run_test 300b "check ctime/mtime for striped dir"
25826
25827 test_300c() {
25828         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25829                 skip "skipped for lustre < 2.7.0"
25830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25831         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25832
25833         local file_count
25834
25835         mkdir_on_mdt0 $DIR/$tdir
25836         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25837                 error "set striped dir error"
25838
25839         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25840                 error "chown striped dir failed"
25841
25842         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25843                 error "create 5k files failed"
25844
25845         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25846
25847         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25848
25849         rm -rf $DIR/$tdir
25850 }
25851 run_test 300c "chown && check ls under striped directory"
25852
25853 test_300d() {
25854         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25855                 skip "skipped for lustre < 2.7.0"
25856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25857         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25858
25859         local stripe_count
25860         local file
25861
25862         mkdir -p $DIR/$tdir
25863         $LFS setstripe -c 2 $DIR/$tdir
25864
25865         #local striped directory
25866         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25867                 error "set striped dir error"
25868         #look at the directories for debug purposes
25869         ls -l $DIR/$tdir
25870         $LFS getdirstripe $DIR/$tdir
25871         ls -l $DIR/$tdir/striped_dir
25872         $LFS getdirstripe $DIR/$tdir/striped_dir
25873         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25874                 error "create 10 files failed"
25875
25876         #remote striped directory
25877         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25878                 error "set striped dir error"
25879         #look at the directories for debug purposes
25880         ls -l $DIR/$tdir
25881         $LFS getdirstripe $DIR/$tdir
25882         ls -l $DIR/$tdir/remote_striped_dir
25883         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25884         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25885                 error "create 10 files failed"
25886
25887         for file in $(find $DIR/$tdir); do
25888                 stripe_count=$($LFS getstripe -c $file)
25889                 [ $stripe_count -eq 2 ] ||
25890                         error "wrong stripe $stripe_count for $file"
25891         done
25892
25893         rm -rf $DIR/$tdir
25894 }
25895 run_test 300d "check default stripe under striped directory"
25896
25897 test_300e() {
25898         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25899                 skip "Need MDS version at least 2.7.55"
25900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25902
25903         local stripe_count
25904         local file
25905
25906         mkdir -p $DIR/$tdir
25907
25908         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25909                 error "set striped dir error"
25910
25911         touch $DIR/$tdir/striped_dir/a
25912         touch $DIR/$tdir/striped_dir/b
25913         touch $DIR/$tdir/striped_dir/c
25914
25915         mkdir $DIR/$tdir/striped_dir/dir_a
25916         mkdir $DIR/$tdir/striped_dir/dir_b
25917         mkdir $DIR/$tdir/striped_dir/dir_c
25918
25919         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25920                 error "set striped adir under striped dir error"
25921
25922         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25923                 error "set striped bdir under striped dir error"
25924
25925         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25926                 error "set striped cdir under striped dir error"
25927
25928         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25929                 error "rename dir under striped dir fails"
25930
25931         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25932                 error "rename dir under different stripes fails"
25933
25934         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25935                 error "rename file under striped dir should succeed"
25936
25937         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25938                 error "rename dir under striped dir should succeed"
25939
25940         rm -rf $DIR/$tdir
25941 }
25942 run_test 300e "check rename under striped directory"
25943
25944 test_300f() {
25945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25946         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25947         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25948                 skip "Need MDS version at least 2.7.55"
25949
25950         local stripe_count
25951         local file
25952
25953         rm -rf $DIR/$tdir
25954         mkdir -p $DIR/$tdir
25955
25956         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25957                 error "set striped dir error"
25958
25959         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25960                 error "set striped dir error"
25961
25962         touch $DIR/$tdir/striped_dir/a
25963         mkdir $DIR/$tdir/striped_dir/dir_a
25964         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25965                 error "create striped dir under striped dir fails"
25966
25967         touch $DIR/$tdir/striped_dir1/b
25968         mkdir $DIR/$tdir/striped_dir1/dir_b
25969         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25970                 error "create striped dir under striped dir fails"
25971
25972         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25973                 error "rename dir under different striped dir should fail"
25974
25975         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25976                 error "rename striped dir under diff striped dir should fail"
25977
25978         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25979                 error "rename file under diff striped dirs fails"
25980
25981         rm -rf $DIR/$tdir
25982 }
25983 run_test 300f "check rename cross striped directory"
25984
25985 test_300_check_default_striped_dir()
25986 {
25987         local dirname=$1
25988         local default_count=$2
25989         local default_index=$3
25990         local stripe_count
25991         local stripe_index
25992         local dir_stripe_index
25993         local dir
25994
25995         echo "checking $dirname $default_count $default_index"
25996         $LFS setdirstripe -D -c $default_count -i $default_index \
25997                                 -H all_char $DIR/$tdir/$dirname ||
25998                 error "set default stripe on striped dir error"
25999         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
26000         [ $stripe_count -eq $default_count ] ||
26001                 error "expect $default_count get $stripe_count for $dirname"
26002
26003         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
26004         [ $stripe_index -eq $default_index ] ||
26005                 error "expect $default_index get $stripe_index for $dirname"
26006
26007         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
26008                                                 error "create dirs failed"
26009
26010         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
26011         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
26012         for dir in $(find $DIR/$tdir/$dirname/*); do
26013                 stripe_count=$($LFS getdirstripe -c $dir)
26014                 (( $stripe_count == $default_count )) ||
26015                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
26016                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
26017                 error "stripe count $default_count != $stripe_count for $dir"
26018
26019                 stripe_index=$($LFS getdirstripe -i $dir)
26020                 [ $default_index -eq -1 ] ||
26021                         [ $stripe_index -eq $default_index ] ||
26022                         error "$stripe_index != $default_index for $dir"
26023
26024                 #check default stripe
26025                 stripe_count=$($LFS getdirstripe -D -c $dir)
26026                 [ $stripe_count -eq $default_count ] ||
26027                 error "default count $default_count != $stripe_count for $dir"
26028
26029                 stripe_index=$($LFS getdirstripe -D -i $dir)
26030                 [ $stripe_index -eq $default_index ] ||
26031                 error "default index $default_index != $stripe_index for $dir"
26032         done
26033         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
26034 }
26035
26036 test_300g() {
26037         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26038         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26039                 skip "Need MDS version at least 2.7.55"
26040
26041         local dir
26042         local stripe_count
26043         local stripe_index
26044
26045         mkdir_on_mdt0 $DIR/$tdir
26046         mkdir $DIR/$tdir/normal_dir
26047
26048         #Checking when client cache stripe index
26049         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
26050         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
26051                 error "create striped_dir failed"
26052
26053         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
26054                 error "create dir0 fails"
26055         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
26056         [ $stripe_index -eq 0 ] ||
26057                 error "dir0 expect index 0 got $stripe_index"
26058
26059         mkdir $DIR/$tdir/striped_dir/dir1 ||
26060                 error "create dir1 fails"
26061         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
26062         [ $stripe_index -eq 1 ] ||
26063                 error "dir1 expect index 1 got $stripe_index"
26064
26065         #check default stripe count/stripe index
26066         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
26067         test_300_check_default_striped_dir normal_dir 1 0
26068         test_300_check_default_striped_dir normal_dir -1 1
26069         test_300_check_default_striped_dir normal_dir 2 -1
26070
26071         #delete default stripe information
26072         echo "delete default stripeEA"
26073         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
26074                 error "set default stripe on striped dir error"
26075
26076         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
26077         for dir in $(find $DIR/$tdir/normal_dir/*); do
26078                 stripe_count=$($LFS getdirstripe -c $dir)
26079                 [ $stripe_count -eq 0 ] ||
26080                         error "expect 1 get $stripe_count for $dir"
26081         done
26082 }
26083 run_test 300g "check default striped directory for normal directory"
26084
26085 test_300h() {
26086         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26087         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26088                 skip "Need MDS version at least 2.7.55"
26089
26090         local dir
26091         local stripe_count
26092
26093         mkdir $DIR/$tdir
26094         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26095                 error "set striped dir error"
26096
26097         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
26098         test_300_check_default_striped_dir striped_dir 1 0
26099         test_300_check_default_striped_dir striped_dir -1 1
26100         test_300_check_default_striped_dir striped_dir 2 -1
26101
26102         #delete default stripe information
26103         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
26104                 error "set default stripe on striped dir error"
26105
26106         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26107         for dir in $(find $DIR/$tdir/striped_dir/*); do
26108                 stripe_count=$($LFS getdirstripe -c $dir)
26109                 [ $stripe_count -eq 0 ] ||
26110                         error "expect 1 get $stripe_count for $dir"
26111         done
26112 }
26113 run_test 300h "check default striped directory for striped directory"
26114
26115 test_300i() {
26116         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26117         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26118         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26119                 skip "Need MDS version at least 2.7.55"
26120
26121         local stripe_count
26122         local file
26123
26124         mkdir $DIR/$tdir
26125
26126         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26127                 error "set striped dir error"
26128
26129         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26130                 error "create files under striped dir failed"
26131
26132         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26133                 error "set striped hashdir error"
26134
26135         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26136                 error "create dir0 under hash dir failed"
26137         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26138                 error "create dir1 under hash dir failed"
26139         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26140                 error "create dir2 under hash dir failed"
26141
26142         # unfortunately, we need to umount to clear dir layout cache for now
26143         # once we fully implement dir layout, we can drop this
26144         umount_client $MOUNT || error "umount failed"
26145         mount_client $MOUNT || error "mount failed"
26146
26147         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26148         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26149         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26150
26151         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26152                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26153                         error "create crush2 dir $tdir/hashdir/d3 failed"
26154                 $LFS find -H crush2 $DIR/$tdir/hashdir
26155                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26156                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26157
26158                 # mkdir with an invalid hash type (hash=fail_val) from client
26159                 # should be replaced on MDS with a valid (default) hash type
26160                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26161                 $LCTL set_param fail_loc=0x1901 fail_val=99
26162                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26163
26164                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26165                 local expect=$(do_facet mds1 \
26166                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26167                 [[ $hash == $expect ]] ||
26168                         error "d99 hash '$hash' != expected hash '$expect'"
26169         fi
26170
26171         #set the stripe to be unknown hash type on read
26172         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26173         $LCTL set_param fail_loc=0x1901 fail_val=99
26174         for ((i = 0; i < 10; i++)); do
26175                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26176                         error "stat f-$i failed"
26177                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26178         done
26179
26180         touch $DIR/$tdir/striped_dir/f0 &&
26181                 error "create under striped dir with unknown hash should fail"
26182
26183         $LCTL set_param fail_loc=0
26184
26185         umount_client $MOUNT || error "umount failed"
26186         mount_client $MOUNT || error "mount failed"
26187
26188         return 0
26189 }
26190 run_test 300i "client handle unknown hash type striped directory"
26191
26192 test_300j() {
26193         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26195         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26196                 skip "Need MDS version at least 2.7.55"
26197
26198         local stripe_count
26199         local file
26200
26201         mkdir $DIR/$tdir
26202
26203         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26204         $LCTL set_param fail_loc=0x1702
26205         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26206                 error "set striped dir error"
26207
26208         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26209                 error "create files under striped dir failed"
26210
26211         $LCTL set_param fail_loc=0
26212
26213         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26214
26215         return 0
26216 }
26217 run_test 300j "test large update record"
26218
26219 test_300k() {
26220         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26221         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26222         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26223                 skip "Need MDS version at least 2.7.55"
26224
26225         # this test needs a huge transaction
26226         local kb
26227         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26228              osd*.$FSNAME-MDT0000.kbytestotal")
26229         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26230
26231         local stripe_count
26232         local file
26233
26234         mkdir $DIR/$tdir
26235
26236         #define OBD_FAIL_LARGE_STRIPE   0x1703
26237         $LCTL set_param fail_loc=0x1703
26238         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26239                 error "set striped dir error"
26240         $LCTL set_param fail_loc=0
26241
26242         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26243                 error "getstripeddir fails"
26244         rm -rf $DIR/$tdir/striped_dir ||
26245                 error "unlink striped dir fails"
26246
26247         return 0
26248 }
26249 run_test 300k "test large striped directory"
26250
26251 test_300l() {
26252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26253         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26254         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26255                 skip "Need MDS version at least 2.7.55"
26256
26257         local stripe_index
26258
26259         test_mkdir -p $DIR/$tdir/striped_dir
26260         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26261                         error "chown $RUNAS_ID failed"
26262         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26263                 error "set default striped dir failed"
26264
26265         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26266         $LCTL set_param fail_loc=0x80000158
26267         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26268
26269         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26270         [ $stripe_index -eq 1 ] ||
26271                 error "expect 1 get $stripe_index for $dir"
26272 }
26273 run_test 300l "non-root user to create dir under striped dir with stale layout"
26274
26275 test_300m() {
26276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26277         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26278         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26279                 skip "Need MDS version at least 2.7.55"
26280
26281         mkdir -p $DIR/$tdir/striped_dir
26282         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26283                 error "set default stripes dir error"
26284
26285         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26286
26287         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26288         [ $stripe_count -eq 0 ] ||
26289                         error "expect 0 get $stripe_count for a"
26290
26291         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26292                 error "set default stripes dir error"
26293
26294         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26295
26296         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26297         [ $stripe_count -eq 0 ] ||
26298                         error "expect 0 get $stripe_count for b"
26299
26300         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26301                 error "set default stripes dir error"
26302
26303         mkdir $DIR/$tdir/striped_dir/c &&
26304                 error "default stripe_index is invalid, mkdir c should fails"
26305
26306         rm -rf $DIR/$tdir || error "rmdir fails"
26307 }
26308 run_test 300m "setstriped directory on single MDT FS"
26309
26310 cleanup_300n() {
26311         local list=$(comma_list $(mdts_nodes))
26312
26313         trap 0
26314         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26315 }
26316
26317 test_300n() {
26318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26319         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26320         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26321                 skip "Need MDS version at least 2.7.55"
26322         remote_mds_nodsh && skip "remote MDS with nodsh"
26323
26324         local stripe_index
26325         local list=$(comma_list $(mdts_nodes))
26326
26327         trap cleanup_300n RETURN EXIT
26328         mkdir -p $DIR/$tdir
26329         chmod 777 $DIR/$tdir
26330         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26331                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26332                 error "create striped dir succeeds with gid=0"
26333
26334         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26335         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26336                 error "create striped dir fails with gid=-1"
26337
26338         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26339         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26340                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26341                 error "set default striped dir succeeds with gid=0"
26342
26343
26344         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26345         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26346                 error "set default striped dir fails with gid=-1"
26347
26348
26349         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26350         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26351                                         error "create test_dir fails"
26352         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26353                                         error "create test_dir1 fails"
26354         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26355                                         error "create test_dir2 fails"
26356         cleanup_300n
26357 }
26358 run_test 300n "non-root user to create dir under striped dir with default EA"
26359
26360 test_300o() {
26361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26362         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26363         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26364                 skip "Need MDS version at least 2.7.55"
26365
26366         local numfree1
26367         local numfree2
26368
26369         mkdir -p $DIR/$tdir
26370
26371         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26372         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26373         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26374                 skip "not enough free inodes $numfree1 $numfree2"
26375         fi
26376
26377         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26378         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26379         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26380                 skip "not enough free space $numfree1 $numfree2"
26381         fi
26382
26383         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26384                 error "setdirstripe fails"
26385
26386         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26387                 error "create dirs fails"
26388
26389         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26390         ls $DIR/$tdir/striped_dir > /dev/null ||
26391                 error "ls striped dir fails"
26392         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26393                 error "unlink big striped dir fails"
26394 }
26395 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26396
26397 test_300p() {
26398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26399         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26400         remote_mds_nodsh && skip "remote MDS with nodsh"
26401
26402         mkdir_on_mdt0 $DIR/$tdir
26403
26404         #define OBD_FAIL_OUT_ENOSPC     0x1704
26405         do_facet mds2 lctl set_param fail_loc=0x80001704
26406         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26407                  && error "create striped directory should fail"
26408
26409         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26410
26411         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26412         true
26413 }
26414 run_test 300p "create striped directory without space"
26415
26416 test_300q() {
26417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26418         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26419
26420         local fd=$(free_fd)
26421         local cmd="exec $fd<$tdir"
26422         cd $DIR
26423         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26424         eval $cmd
26425         cmd="exec $fd<&-"
26426         trap "eval $cmd" EXIT
26427         cd $tdir || error "cd $tdir fails"
26428         rmdir  ../$tdir || error "rmdir $tdir fails"
26429         mkdir local_dir && error "create dir succeeds"
26430         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26431         eval $cmd
26432         return 0
26433 }
26434 run_test 300q "create remote directory under orphan directory"
26435
26436 test_300r() {
26437         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26438                 skip "Need MDS version at least 2.7.55" && return
26439         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26440
26441         mkdir $DIR/$tdir
26442
26443         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26444                 error "set striped dir error"
26445
26446         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26447                 error "getstripeddir fails"
26448
26449         local stripe_count
26450         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26451                       awk '/lmv_stripe_count:/ { print $2 }')
26452
26453         [ $MDSCOUNT -ne $stripe_count ] &&
26454                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26455
26456         rm -rf $DIR/$tdir/striped_dir ||
26457                 error "unlink striped dir fails"
26458 }
26459 run_test 300r "test -1 striped directory"
26460
26461 test_300s_helper() {
26462         local count=$1
26463
26464         local stripe_dir=$DIR/$tdir/striped_dir.$count
26465
26466         $LFS mkdir -c $count $stripe_dir ||
26467                 error "lfs mkdir -c error"
26468
26469         $LFS getdirstripe $stripe_dir ||
26470                 error "lfs getdirstripe fails"
26471
26472         local stripe_count
26473         stripe_count=$($LFS getdirstripe $stripe_dir |
26474                       awk '/lmv_stripe_count:/ { print $2 }')
26475
26476         [ $count -ne $stripe_count ] &&
26477                 error_noexit "bad stripe count $stripe_count expected $count"
26478
26479         local dupe_stripes
26480         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26481                 awk '/0x/ {count[$1] += 1}; END {
26482                         for (idx in count) {
26483                                 if (count[idx]>1) {
26484                                         print "index " idx " count " count[idx]
26485                                 }
26486                         }
26487                 }')
26488
26489         if [[ -n "$dupe_stripes" ]] ; then
26490                 lfs getdirstripe $stripe_dir
26491                 error_noexit "Dupe MDT above: $dupe_stripes "
26492         fi
26493
26494         rm -rf $stripe_dir ||
26495                 error_noexit "unlink $stripe_dir fails"
26496 }
26497
26498 test_300s() {
26499         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26500                 skip "Need MDS version at least 2.7.55" && return
26501         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26502
26503         mkdir $DIR/$tdir
26504         for count in $(seq 2 $MDSCOUNT); do
26505                 test_300s_helper $count
26506         done
26507 }
26508 run_test 300s "test lfs mkdir -c without -i"
26509
26510 test_300t() {
26511         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26512                 skip "need MDS 2.14.55 or later"
26513         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26514
26515         local testdir="$DIR/$tdir/striped_dir"
26516         local dir1=$testdir/dir1
26517         local dir2=$testdir/dir2
26518
26519         mkdir -p $testdir
26520
26521         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26522                 error "failed to set default stripe count for $testdir"
26523
26524         mkdir $dir1
26525         local stripe_count=$($LFS getdirstripe -c $dir1)
26526
26527         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26528
26529         local max_count=$((MDSCOUNT - 1))
26530         local mdts=$(comma_list $(mdts_nodes))
26531
26532         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26533         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26534
26535         mkdir $dir2
26536         stripe_count=$($LFS getdirstripe -c $dir2)
26537
26538         (( $stripe_count == $max_count )) || error "wrong stripe count"
26539 }
26540 run_test 300t "test max_mdt_stripecount"
26541
26542 MDT_OVSTRP_VER="2.15.60"
26543 # 300u family tests MDT overstriping
26544 test_300ua() {
26545         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26546
26547         local setcount=$((MDSCOUNT * 2))
26548
26549         local expected_count
26550
26551         mkdir $DIR/$tdir
26552         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.0 ||
26553                 error "(0) failed basic overstriped dir creation test"
26554         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26555
26556         # This does a basic interop test - if the MDS does not support mdt
26557         # overstriping, we should get stripes == number of MDTs
26558         if (( $MDS1_VERSION < $(version_code $MDT_OVSTRP_VER) )); then
26559                 expected_count=$MDSCOUNT
26560         else
26561                 expected_count=$setcount
26562         fi
26563         (( getstripe_count == expected_count )) ||
26564                 error "(1) incorrect stripe count for simple overstriped dir"
26565
26566         rm -rf $DIR/$tdir/${tdir}.0 ||
26567                 error "(2) unable to rm overstriped dir"
26568
26569         # Tests after this require overstriping support
26570         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26571                 { echo "skipped for MDS < $MDT_OVSTRP_VER"; return 0; }
26572
26573         test_striped_dir 0 $setcount true ||
26574                 error "(3)failed on overstriped dir"
26575         test_striped_dir 1 $setcount true ||
26576                 error "(4)failed on overstriped dir"
26577
26578         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26579
26580         test_striped_dir 0 $setcount true ||
26581                 error "(5)failed on overstriped dir"
26582 }
26583 run_test 300ua "basic overstriped dir sanity test"
26584
26585 test_300ub() {
26586         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26587                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26588         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26589
26590         mkdir $DIR/$tdir
26591
26592         echo "Testing invalid stripe count, failure expected"
26593         local setcount=$((MDSCOUNT * 2))
26594
26595         $LFS setdirstripe -c $setcount $DIR/$tdir/${tdir}.0
26596         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.0)
26597
26598         (( getstripe_count <= MDSCOUNT )) ||
26599                 error "(0)stripe count ($setcount) > MDT count ($MDSCOUNT) succeeded with -c"
26600
26601         # When a user requests > LMV_MAX_STRIPES_PER_MDT, we reduce to that
26602         setcount=$((MDSCOUNT * 2 * LMV_MAX_STRIPES_PER_MDT))
26603         $LFS setdirstripe -C $setcount $DIR/$tdir/${tdir}.1
26604
26605         local maxcount=$((MDSCOUNT * LMV_MAX_STRIPES_PER_MDT))
26606
26607         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26608         (( getstripe_count == maxcount )) ||
26609                 error "(1)stripe_count is $getstripe_count, expect $maxcount"
26610
26611         # Test specific striping with -i
26612         $LFS setdirstripe -i 0,0,0,0 $DIR/$tdir/${tdir}.2
26613
26614         getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.2)
26615         (( getstripe_count == 4 )) ||
26616                 error "(2)stripe_count is $getstripe_count, expect 4"
26617
26618         local nonzeroindices=$($LFS getdirstripe $DIR/$tdir/${tdir}.2 | grep "\[" | \
26619                                grep -v mdtidx | awk '{print $1}' | grep -c -v 0)
26620
26621         [[ -n "$nonzeroindices" ]] ||
26622                 error "(3) stripes indices not all 0: $nonzeroindices"
26623
26624         # Test specific striping with too many stripes on one MDT
26625         echo "Testing invalid striping, failure expected"
26626         $LFS setdirstripe -i 0,1,0,1,0,1,0,1,0,1,0 $DIR/$tdir/${tdir}.3
26627         $LFS getdirstripe $DIR/$tdir/${tdir}.3
26628         getstripe_count=$($LFS getdirstripe $DIR/$tdir/${tdir}.3 | grep "\[" | \
26629                           grep -v mdtidx | awk '{print $1}' | grep -c '0')
26630         echo "stripes on MDT0: $getstripe_count"
26631         (( getstripe_count <= LMV_MAX_STRIPES_PER_MDT )) ||
26632                 error "(4) setstripe with too many stripes on MDT0 succeeded"
26633
26634         setcount=$((MDSCOUNT * 2))
26635         $LFS setdirstripe -C $setcount -H all_char $DIR/${tdir}.4 ||
26636                 error "(5) can't setdirstripe with manually set hash function"
26637
26638         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.4)
26639         (( getstripe_count == setcount )) ||
26640                 error "(6)stripe_count is $getstripe_count, expect $setcount"
26641
26642         setcount=$((MDSCOUNT * 2))
26643         mkdir $DIR/${tdir}.5
26644         $LFS setdirstripe -C $setcount -D -H crush $DIR/${tdir}.5 ||
26645                 error "(7) can't setdirstripe with manually set hash function"
26646         mkdir $DIR/${tdir}.5/${tdir}.6
26647
26648         getstripe_count=$($LFS getdirstripe -c $DIR/${tdir}.5/${tdir}.6)
26649         (( getstripe_count == setcount )) ||
26650                 error "(8)stripe_count is $getstripe_count, expect $setcount"
26651 }
26652 run_test 300ub "test MDT overstriping interface & limits"
26653
26654 test_300uc() {
26655         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26656                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26657         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26658
26659         mkdir $DIR/$tdir
26660
26661         local setcount=$((MDSCOUNT * 2))
26662
26663         $LFS setdirstripe -D -C $setcount $DIR/$tdir
26664
26665         mkdir $DIR/$tdir/${tdir}.1
26666
26667         local getstripe_count=$($LFS getdirstripe -c $DIR/$tdir/${tdir}.1)
26668
26669         (( getstripe_count == setcount )) ||
26670                 error "(0)stripe_count is $getstripe_count, expect $setcount"
26671
26672         mkdir $DIR/$tdir/${tdir}.1/${tdir}.2
26673
26674         local getstripe_count=$($LFS getdirstripe -c \
26675                                 $DIR/$tdir/${tdir}.1/${tdir}.2)
26676
26677         (( getstripe_count == setcount )) ||
26678                 error "(1)stripe_count is $getstripe_count, expect $setcount"
26679 }
26680 run_test 300uc "test MDT overstriping as default & inheritance"
26681
26682 test_300ud() {
26683         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26684                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26685         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26686
26687         local mdts=$(comma_list $(mdts_nodes))
26688         local timeout=100
26689
26690         local restripe_status
26691         local delta
26692         local i
26693
26694         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26695
26696         # in case "crush" hash type is not set
26697         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26698
26699         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26700                            mdt.*MDT0000.enable_dir_restripe)
26701         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26702         stack_trap "do_nodes $mdts $LCTL set_param \
26703                     mdt.*.enable_dir_restripe=$restripe_status"
26704
26705         mkdir $DIR/$tdir
26706         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26707                 error "create files under remote dir failed $i"
26708         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26709                 error "create dirs under remote dir failed $i"
26710
26711         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26712
26713         (( setcount < 13 )) || setcount=12
26714         for i in $(seq 2 $setcount); do
26715                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26716                 $LFS setdirstripe -C $i $DIR/$tdir ||
26717                         error "split -C $i $tdir failed"
26718                 wait_update $HOSTNAME \
26719                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
26720                         error "dir split not finished"
26721                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26722                         awk '/migrate/ {sum += $2} END { print sum }')
26723                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
26724                 # delta is around total_files/stripe_count, deviation 3%
26725                 (( delta < 100 * MDSCOUNT / i + 3 * MDSCOUNT )) ||
26726                         error "$delta files migrated >= $((100 * MDSCOUNT / i + 3 * MDSCOUNT))"
26727         done
26728 }
26729 run_test 300ud "dir split"
26730
26731 test_300ue() {
26732         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26733                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26734         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26735
26736         local mdts=$(comma_list $(mdts_nodes))
26737         local timeout=100
26738
26739         local restripe_status
26740         local delta
26741         local c
26742
26743         [[ $mds1_FSTYPE == zfs ]] && timeout=300
26744
26745         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
26746
26747         restripe_status=$(do_facet mds1 $LCTL get_param -n \
26748                            mdt.*MDT0000.enable_dir_restripe)
26749         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
26750         stack_trap "do_nodes $mdts $LCTL set_param \
26751                     mdt.*.enable_dir_restripe=$restripe_status"
26752
26753         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26754
26755         (( setcount < 13 )) || setcount=12
26756         test_mkdir -C $setcount -H crush $DIR/$tdir
26757         createmany -m $DIR/$tdir/f $((50 * MDSCOUNT)) ||
26758                 error "create files under remote dir failed"
26759         createmany -d $DIR/$tdir/d $((50 * MDSCOUNT)) ||
26760                 error "create dirs under remote dir failed"
26761
26762         for c in $(seq $((setcount - 1)) -1 1); do
26763                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
26764                 $LFS setdirstripe -C $c $DIR/$tdir ||
26765                         error "split -C $c $tdir failed"
26766                 wait_update $HOSTNAME \
26767                         "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" $timeout ||
26768                         error "dir merge not finished"
26769                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
26770                         awk '/migrate/ {sum += $2} END { print sum }')
26771                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
26772                 # delta is around total_files/stripe_count, deviation 3%
26773                 (( delta < 100 * MDSCOUNT / c + 3 * MDSCOUNT )) ||
26774                         error "$delta files migrated >= $((100 * MDSCOUNT / c + 3 * MDSCOUNT))"
26775         done
26776 }
26777 run_test 300ue "dir merge"
26778
26779 test_300uf() {
26780         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26781                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26782         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26783
26784         # maximum amount of local locks:
26785         # parent striped dir - 2 locks
26786         # new stripe in parent to migrate to - 1 lock
26787         # source and target - 2 locks
26788         # Total 5 locks for regular file
26789         #
26790         # NB: Overstriping should add several extra local locks
26791         # FIXME: Remove this once understood
26792         #lctl set_param *debug=-1 debug_mb=10000
26793         lctl clear
26794         lctl mark "touch/create"
26795         mkdir -p $DIR/$tdir
26796         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26797         local setcount=$((MDSCOUNT * 5))
26798
26799         $LFS mkdir -i1 -C $setcount $DIR/$tdir/dir1
26800         touch $DIR/$tdir/dir1/eee
26801
26802         lctl mark "hardlinks"
26803         # create 4 hardlink for 4 more locks
26804         # Total: 9 locks > RS_MAX_LOCKS (8)
26805         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
26806         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
26807         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
26808         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
26809         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
26810         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
26811         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
26812         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
26813
26814         lctl mark "cancel lru"
26815         cancel_lru_locks mdc
26816
26817         lctl mark "migrate"
26818         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
26819                 error "migrate dir fails"
26820
26821         rm -rf $DIR/$tdir || error "rm dir failed after migration"
26822 }
26823 run_test 300uf "migrate with too many local locks"
26824
26825 test_300ug() {
26826         (( MDS1_VERSION >= $(version_code $MDT_OVSTRP_VER) )) ||
26827                 skip "skipped for MDS < $MDT_OVSTRP_VER"
26828         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
26829
26830         mkdir -p $DIR/$tdir
26831         local migrate_dir=$DIR/$tdir/migrate_dir
26832         local setcount=$((MDSCOUNT * $LMV_MAX_STRIPES_PER_MDT))
26833         local setcount2=$((setcount - 2))
26834
26835         $LFS setdirstripe -c 2 $migrate_dir ||
26836                 error "(0) failed to create striped directory"
26837
26838         $LFS migrate -m 0 -C $setcount $migrate_dir ||
26839                 error "(1)failed to migrate to overstriped directory"
26840         local getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26841
26842         (( getstripe_count == setcount )) ||
26843                 error "(2)stripe_count is $getstripe_count, expect $setcount"
26844         touch $DIR/$tdir/migrate_dir/$tfile ||
26845                 error "(3)failed to create file in overstriped directory"
26846         $LFS migrate -m 0 -C $setcount2 $migrate_dir ||
26847                 error "(4)failed to migrate overstriped directory"
26848         # Check stripe count after migration
26849         $LFS getdirstripe $migrate_dir
26850         getstripe_count=$($LFS getdirstripe -c $migrate_dir)
26851         (( getstripe_count == setcount2 )) ||
26852                 error "(5)stripe_count is $getstripe_count, expect $setcount2"
26853
26854         rm -rf $migrate_dir || error "(6) unable to rm overstriped dir"
26855 }
26856 run_test 300ug "migrate overstriped dirs"
26857
26858 prepare_remote_file() {
26859         mkdir $DIR/$tdir/src_dir ||
26860                 error "create remote source failed"
26861
26862         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26863                  error "cp to remote source failed"
26864         touch $DIR/$tdir/src_dir/a
26865
26866         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26867                 error "create remote target dir failed"
26868
26869         touch $DIR/$tdir/tgt_dir/b
26870
26871         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26872                 error "rename dir cross MDT failed!"
26873
26874         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26875                 error "src_child still exists after rename"
26876
26877         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26878                 error "missing file(a) after rename"
26879
26880         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26881                 error "diff after rename"
26882 }
26883
26884 test_310a() {
26885         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26887
26888         local remote_file=$DIR/$tdir/tgt_dir/b
26889
26890         mkdir -p $DIR/$tdir
26891
26892         prepare_remote_file || error "prepare remote file failed"
26893
26894         #open-unlink file
26895         $OPENUNLINK $remote_file $remote_file ||
26896                 error "openunlink $remote_file failed"
26897         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26898 }
26899 run_test 310a "open unlink remote file"
26900
26901 test_310b() {
26902         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26904
26905         local remote_file=$DIR/$tdir/tgt_dir/b
26906
26907         mkdir -p $DIR/$tdir
26908
26909         prepare_remote_file || error "prepare remote file failed"
26910
26911         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26912         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26913         $CHECKSTAT -t file $remote_file || error "check file failed"
26914 }
26915 run_test 310b "unlink remote file with multiple links while open"
26916
26917 test_310c() {
26918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26919         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26920
26921         local remote_file=$DIR/$tdir/tgt_dir/b
26922
26923         mkdir -p $DIR/$tdir
26924
26925         prepare_remote_file || error "prepare remote file failed"
26926
26927         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26928         multiop_bg_pause $remote_file O_uc ||
26929                         error "mulitop failed for remote file"
26930         MULTIPID=$!
26931         $MULTIOP $DIR/$tfile Ouc
26932         kill -USR1 $MULTIPID
26933         wait $MULTIPID
26934 }
26935 run_test 310c "open-unlink remote file with multiple links"
26936
26937 #LU-4825
26938 test_311() {
26939         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26940         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26941         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26942                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26943         remote_mds_nodsh && skip "remote MDS with nodsh"
26944
26945         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26946         local mdts=$(comma_list $(mdts_nodes))
26947
26948         mkdir -p $DIR/$tdir
26949         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26950         createmany -o $DIR/$tdir/$tfile. 1000
26951
26952         # statfs data is not real time, let's just calculate it
26953         old_iused=$((old_iused + 1000))
26954
26955         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26956                         osp.*OST0000*MDT0000.create_count")
26957         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26958                                 osp.*OST0000*MDT0000.max_create_count")
26959         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26960
26961         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26962         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26963         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26964
26965         unlinkmany $DIR/$tdir/$tfile. 1000
26966
26967         do_nodes $mdts "$LCTL set_param -n \
26968                         osp.*OST0000*.max_create_count=$max_count"
26969         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26970                 do_nodes $mdts "$LCTL set_param -n \
26971                                 osp.*OST0000*.create_count=$count"
26972         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26973                         grep "=0" && error "create_count is zero"
26974
26975         local new_iused
26976         for i in $(seq 120); do
26977                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26978                 # system may be too busy to destroy all objs in time, use
26979                 # a somewhat small value to not fail autotest
26980                 [ $((old_iused - new_iused)) -gt 400 ] && break
26981                 sleep 1
26982         done
26983
26984         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26985         [ $((old_iused - new_iused)) -gt 400 ] ||
26986                 error "objs not destroyed after unlink"
26987 }
26988 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26989
26990 zfs_get_objid()
26991 {
26992         local ost=$1
26993         local tf=$2
26994         local fid=($($LFS getstripe $tf | grep 0x))
26995         local seq=${fid[3]#0x}
26996         local objid=${fid[1]}
26997
26998         local vdevdir=$(dirname $(facet_vdevice $ost))
26999         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
27000         local zfs_zapid=$(do_facet $ost $cmd |
27001                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
27002                           awk '/Object/{getline; print $1}')
27003         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
27004                           awk "/$objid = /"'{printf $3}')
27005
27006         echo $zfs_objid
27007 }
27008
27009 zfs_object_blksz() {
27010         local ost=$1
27011         local objid=$2
27012
27013         local vdevdir=$(dirname $(facet_vdevice $ost))
27014         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
27015         local blksz=$(do_facet $ost $cmd $objid |
27016                       awk '/dblk/{getline; printf $4}')
27017
27018         case "${blksz: -1}" in
27019                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
27020                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
27021                 *) ;;
27022         esac
27023
27024         echo $blksz
27025 }
27026
27027 test_312() { # LU-4856
27028         remote_ost_nodsh && skip "remote OST with nodsh"
27029         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
27030
27031         local max_blksz=$(do_facet ost1 \
27032                           $ZFS get -p recordsize $(facet_device ost1) |
27033                           awk '!/VALUE/{print $3}')
27034         local tf=$DIR/$tfile
27035
27036         $LFS setstripe -c1 $tf
27037         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
27038
27039         # Get ZFS object id
27040         local zfs_objid=$(zfs_get_objid $facet $tf)
27041         # block size change by sequential overwrite
27042         local bs
27043
27044         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
27045                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
27046
27047                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
27048                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
27049         done
27050         rm -f $tf
27051
27052         $LFS setstripe -c1 $tf
27053         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27054
27055         # block size change by sequential append write
27056         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
27057         zfs_objid=$(zfs_get_objid $facet $tf)
27058         local count
27059
27060         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
27061                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
27062                         oflag=sync conv=notrunc
27063
27064                 blksz=$(zfs_object_blksz $facet $zfs_objid)
27065                 (( $blksz == 2 * count * PAGE_SIZE )) ||
27066                         error "blksz error, actual $blksz, " \
27067                                 "expected: 2 * $count * $PAGE_SIZE"
27068         done
27069         rm -f $tf
27070
27071         # random write
27072         $LFS setstripe -c1 $tf
27073         facet="ost$(($($LFS getstripe -i $tf) + 1))"
27074         zfs_objid=$(zfs_get_objid $facet $tf)
27075
27076         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
27077         blksz=$(zfs_object_blksz $facet $zfs_objid)
27078         (( blksz == PAGE_SIZE )) ||
27079                 error "blksz error: $blksz, expected: $PAGE_SIZE"
27080
27081         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
27082         blksz=$(zfs_object_blksz $facet $zfs_objid)
27083         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
27084
27085         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
27086         blksz=$(zfs_object_blksz $facet $zfs_objid)
27087         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
27088 }
27089 run_test 312 "make sure ZFS adjusts its block size by write pattern"
27090
27091 test_313() {
27092         remote_ost_nodsh && skip "remote OST with nodsh"
27093
27094         local file=$DIR/$tfile
27095
27096         rm -f $file
27097         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
27098
27099         # define OBD_FAIL_TGT_RCVD_EIO           0x720
27100         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27101         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
27102                 error "write should failed"
27103         do_facet ost1 "$LCTL set_param fail_loc=0"
27104         rm -f $file
27105 }
27106 run_test 313 "io should fail after last_rcvd update fail"
27107
27108 test_314() {
27109         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
27110
27111         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
27112         do_facet ost1 "$LCTL set_param fail_loc=0x720"
27113         rm -f $DIR/$tfile
27114         wait_delete_completed
27115         do_facet ost1 "$LCTL set_param fail_loc=0"
27116 }
27117 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
27118
27119 test_315() { # LU-618
27120         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
27121
27122         local file=$DIR/$tfile
27123         rm -f $file
27124
27125         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
27126                 error "multiop file write failed"
27127         $MULTIOP $file oO_RDONLY:r4063232_c &
27128         PID=$!
27129
27130         sleep 2
27131
27132         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
27133         kill -USR1 $PID
27134
27135         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
27136         rm -f $file
27137 }
27138 run_test 315 "read should be accounted"
27139
27140 test_316() {
27141         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27142         large_xattr_enabled || skip "ea_inode feature disabled"
27143
27144         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
27145         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
27146         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
27147         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
27148
27149         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
27150 }
27151 run_test 316 "lfs migrate of file with large_xattr enabled"
27152
27153 test_317() {
27154         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
27155                 skip "Need MDS version at least 2.11.53"
27156         if [ "$ost1_FSTYPE" == "zfs" ]; then
27157                 skip "LU-10370: no implementation for ZFS"
27158         fi
27159
27160         local trunc_sz
27161         local grant_blk_size
27162
27163         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
27164                         awk '/grant_block_size:/ { print $2; exit; }')
27165         #
27166         # Create File of size 5M. Truncate it to below size's and verify
27167         # blocks count.
27168         #
27169         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
27170                 error "Create file $DIR/$tfile failed"
27171         stack_trap "rm -f $DIR/$tfile" EXIT
27172
27173         for trunc_sz in 2097152 4097 4000 509 0; do
27174                 $TRUNCATE $DIR/$tfile $trunc_sz ||
27175                         error "truncate $tfile to $trunc_sz failed"
27176                 local sz=$(stat --format=%s $DIR/$tfile)
27177                 local blk=$(stat --format=%b $DIR/$tfile)
27178                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
27179                                      grant_blk_size) * 8))
27180
27181                 if [[ $blk -ne $trunc_blk ]]; then
27182                         $(which stat) $DIR/$tfile
27183                         error "Expected Block $trunc_blk got $blk for $tfile"
27184                 fi
27185
27186                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27187                         error "Expected Size $trunc_sz got $sz for $tfile"
27188         done
27189
27190         #
27191         # sparse file test
27192         # Create file with a hole and write actual 65536 bytes which aligned
27193         # with 4K and 64K PAGE_SIZE. Block count must be 128.
27194         #
27195         local bs=65536
27196         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
27197                 error "Create file : $DIR/$tfile"
27198
27199         #
27200         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
27201         # blocks. The block count must drop to 8.
27202         #
27203         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
27204                 ((bs - grant_blk_size) + 1)))
27205         $TRUNCATE $DIR/$tfile $trunc_sz ||
27206                 error "truncate $tfile to $trunc_sz failed"
27207
27208         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
27209         sz=$(stat --format=%s $DIR/$tfile)
27210         blk=$(stat --format=%b $DIR/$tfile)
27211
27212         if [[ $blk -ne $trunc_bsz ]]; then
27213                 $(which stat) $DIR/$tfile
27214                 error "Expected Block $trunc_bsz got $blk for $tfile"
27215         fi
27216
27217         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
27218                 error "Expected Size $trunc_sz got $sz for $tfile"
27219 }
27220 run_test 317 "Verify blocks get correctly update after truncate"
27221
27222 test_318() {
27223         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
27224         local old_max_active=$($LCTL get_param -n \
27225                             ${llite_name}.max_read_ahead_async_active \
27226                             2>/dev/null)
27227
27228         $LCTL set_param llite.*.max_read_ahead_async_active=256
27229         local max_active=$($LCTL get_param -n \
27230                            ${llite_name}.max_read_ahead_async_active \
27231                            2>/dev/null)
27232         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
27233
27234         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
27235                 error "set max_read_ahead_async_active should succeed"
27236
27237         $LCTL set_param llite.*.max_read_ahead_async_active=512
27238         max_active=$($LCTL get_param -n \
27239                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
27240         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
27241
27242         # restore @max_active
27243         [ $old_max_active -ne 0 ] && $LCTL set_param \
27244                 llite.*.max_read_ahead_async_active=$old_max_active
27245
27246         local old_threshold=$($LCTL get_param -n \
27247                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27248         local max_per_file_mb=$($LCTL get_param -n \
27249                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
27250
27251         local invalid=$(($max_per_file_mb + 1))
27252         $LCTL set_param \
27253                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
27254                         && error "set $invalid should fail"
27255
27256         local valid=$(($invalid - 1))
27257         $LCTL set_param \
27258                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
27259                         error "set $valid should succeed"
27260         local threshold=$($LCTL get_param -n \
27261                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
27262         [ $threshold -eq $valid ] || error \
27263                 "expect threshold $valid got $threshold"
27264         $LCTL set_param \
27265                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
27266 }
27267 run_test 318 "Verify async readahead tunables"
27268
27269 test_319() {
27270         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
27271
27272         local before=$(date +%s)
27273         local evict
27274         local mdir=$DIR/$tdir
27275         local file=$mdir/xxx
27276
27277         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
27278         touch $file
27279
27280 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
27281         $LCTL set_param fail_val=5 fail_loc=0x8000032c
27282         $LFS migrate -m1 $mdir &
27283
27284         sleep 1
27285         dd if=$file of=/dev/null
27286         wait
27287         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
27288           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
27289
27290         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
27291 }
27292 run_test 319 "lost lease lock on migrate error"
27293
27294 test_360() {
27295         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
27296                 skip "Need OST version at least 2.15.58.96"
27297         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
27298
27299         check_set_fallocate_or_skip
27300         local param="osd-ldiskfs.delayed_unlink_mb"
27301         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
27302
27303         do_facet ost1 "$LCTL set_param $param=1MiB"
27304         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
27305
27306         mkdir $DIR/$tdir/
27307         do_facet ost1 $LCTL set_param debug=+inode
27308         do_facet ost1 $LCTL clear
27309         local files=100
27310
27311         for ((i = 0; i < $files; i++)); do
27312                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
27313                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
27314         done
27315         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
27316
27317         for ((i = 0; i < $files; i++)); do
27318                 unlink $DIR/$tdir/$tfile.$i ||
27319                         error "unlink $DIR/$tdir/$tfile.$i failed"
27320         done
27321
27322         local count=0
27323         local loop
27324
27325         for (( loop = 0; loop < 30 && count < min; loop++)); do
27326                 sleep 1
27327                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
27328                 echo "Count[$loop]: $count"
27329         done
27330         (( count >= min )) || error "$count < $min delayed iput after $loop s"
27331 }
27332 run_test 360 "ldiskfs unlink in a separate thread"
27333
27334 test_398a() { # LU-4198
27335         local ost1_imp=$(get_osc_import_name client ost1)
27336         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27337                          cut -d'.' -f2)
27338
27339         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27340         stack_trap "rm -f $DIR/$tfile"
27341         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27342
27343         # request a new lock on client
27344         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
27345
27346         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27347         local lock_count=$($LCTL get_param -n \
27348                            ldlm.namespaces.$imp_name.lru_size)
27349         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
27350
27351         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27352
27353         # no lock cached, should use lockless DIO and not enqueue new lock
27354         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
27355         lock_count=$($LCTL get_param -n \
27356                      ldlm.namespaces.$imp_name.lru_size)
27357         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
27358
27359         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
27360
27361         # no lock cached, should use locked DIO append
27362         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
27363                 conv=notrunc || error "DIO append failed"
27364         lock_count=$($LCTL get_param -n \
27365                      ldlm.namespaces.$imp_name.lru_size)
27366         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
27367 }
27368 run_test 398a "direct IO should cancel lock otherwise lockless"
27369
27370 test_398b() { # LU-4198
27371         local before=$(date +%s)
27372         local njobs=4
27373         local size=48
27374
27375         which fio || skip_env "no fio installed"
27376         $LFS setstripe -c -1 -S 1M $DIR/$tfile
27377         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
27378
27379         # Single page, multiple pages, stripe size, 4*stripe size
27380         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
27381                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
27382                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
27383                         --numjobs=$njobs --fallocate=none \
27384                         --iodepth=16 --allow_file_create=0 \
27385                         --size=$((size/njobs))M \
27386                         --filename=$DIR/$tfile &
27387                 bg_pid=$!
27388
27389                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
27390                 fio --name=rand-rw --rw=randrw --bs=$bsize \
27391                         --numjobs=$njobs --fallocate=none \
27392                         --iodepth=16 --allow_file_create=0 \
27393                         --size=$((size/njobs))M \
27394                         --filename=$DIR/$tfile || true
27395                 wait $bg_pid
27396         done
27397
27398         evict=$(do_facet client $LCTL get_param \
27399                 osc.$FSNAME-OST*-osc-*/state |
27400             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
27401
27402         [ -z "$evict" ] || [[ $evict -le $before ]] ||
27403                 (do_facet client $LCTL get_param \
27404                         osc.$FSNAME-OST*-osc-*/state;
27405                     error "eviction happened: $evict before:$before")
27406
27407         rm -f $DIR/$tfile
27408 }
27409 run_test 398b "DIO and buffer IO race"
27410
27411 test_398c() { # LU-4198
27412         local ost1_imp=$(get_osc_import_name client ost1)
27413         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
27414                          cut -d'.' -f2)
27415
27416         which fio || skip_env "no fio installed"
27417
27418         saved_debug=$($LCTL get_param -n debug)
27419         $LCTL set_param debug=0
27420
27421         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27422         ((size /= 1024)) # by megabytes
27423         ((size /= 2)) # write half of the OST at most
27424         [ $size -gt 40 ] && size=40 #reduce test time anyway
27425
27426         $LFS setstripe -c 1 $DIR/$tfile
27427
27428         # it seems like ldiskfs reserves more space than necessary if the
27429         # writing blocks are not mapped, so it extends the file firstly
27430         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27431         cancel_lru_locks osc
27432
27433         # clear and verify rpc_stats later
27434         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27435
27436         local njobs=4
27437         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27438         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27439                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27440                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27441                 --filename=$DIR/$tfile
27442         [ $? -eq 0 ] || error "fio write error"
27443
27444         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27445                 error "Locks were requested while doing AIO"
27446
27447         # get the percentage of 1-page I/O
27448         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27449                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27450                 awk '{print $7}')
27451         (( $pct <= 50 )) || {
27452                 $LCTL get_param osc.${imp_name}.rpc_stats
27453                 error "$pct% of I/O are 1-page"
27454         }
27455
27456         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27457         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27458                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27459                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27460                 --filename=$DIR/$tfile
27461         [ $? -eq 0 ] || error "fio mixed read write error"
27462
27463         echo "AIO with large block size ${size}M"
27464         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27465                 --numjobs=1 --fallocate=none --ioengine=libaio \
27466                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27467                 --filename=$DIR/$tfile
27468         [ $? -eq 0 ] || error "fio large block size failed"
27469
27470         rm -f $DIR/$tfile
27471         $LCTL set_param debug="$saved_debug"
27472 }
27473 run_test 398c "run fio to test AIO"
27474
27475 test_398d() { #  LU-13846
27476         which aiocp || skip_env "no aiocp installed"
27477         local aio_file=$DIR/$tfile.aio
27478
27479         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27480
27481         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27482         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27483         stack_trap "rm -f $DIR/$tfile $aio_file"
27484
27485         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27486
27487         # test memory unaligned aio
27488         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27489                 error "unaligned aio failed"
27490         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27491
27492         rm -f $DIR/$tfile $aio_file
27493 }
27494 run_test 398d "run aiocp to verify block size > stripe size"
27495
27496 test_398e() {
27497         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27498         touch $DIR/$tfile.new
27499         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27500 }
27501 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27502
27503 test_398f() { #  LU-14687
27504         which aiocp || skip_env "no aiocp installed"
27505         local aio_file=$DIR/$tfile.aio
27506
27507         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27508
27509         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27510         stack_trap "rm -f $DIR/$tfile $aio_file"
27511
27512         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27513         $LCTL set_param fail_loc=0x1418
27514         # make sure we don't crash and fail properly
27515         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27516                 error "aio with page allocation failure succeeded"
27517         $LCTL set_param fail_loc=0
27518         diff $DIR/$tfile $aio_file
27519         [[ $? != 0 ]] || error "no diff after failed aiocp"
27520 }
27521 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27522
27523 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27524 # stripe and i/o size must be > stripe size
27525 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27526 # single RPC in flight.  This test shows async DIO submission is working by
27527 # showing multiple RPCs in flight.
27528 test_398g() { #  LU-13798
27529         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27530
27531         # We need to do some i/o first to acquire enough grant to put our RPCs
27532         # in flight; otherwise a new connection may not have enough grant
27533         # available
27534         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27535                 error "parallel dio failed"
27536         stack_trap "rm -f $DIR/$tfile"
27537
27538         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27539         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27540         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27541         stack_trap "$LCTL set_param -n $pages_per_rpc"
27542
27543         # Recreate file so it's empty
27544         rm -f $DIR/$tfile
27545         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27546         #Pause rpc completion to guarantee we see multiple rpcs in flight
27547         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27548         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27549         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27550
27551         # Clear rpc stats
27552         $LCTL set_param osc.*.rpc_stats=c
27553
27554         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27555                 error "parallel dio failed"
27556         stack_trap "rm -f $DIR/$tfile"
27557
27558         $LCTL get_param osc.*-OST0000-*.rpc_stats
27559         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27560                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27561                 grep "8:" | awk '{print $8}')
27562         # We look at the "8 rpcs in flight" field, and verify A) it is present
27563         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27564         # as expected for an 8M DIO to a file with 1M stripes.
27565         # NB: There is occasionally a mystery extra write RPC to a different
27566         # file.  I can't identify why that's happening, so we set up a margin
27567         # of 1 RPC here, ie, 8/9 RPCs at this size, or ~88%
27568         [ $pct -gt 87 ] || error "we should see 8 RPCs in flight"
27569
27570         # Verify turning off parallel dio works as expected
27571         # Clear rpc stats
27572         $LCTL set_param osc.*.rpc_stats=c
27573         $LCTL set_param llite.*.parallel_dio=0
27574         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27575
27576         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27577                 error "dio with parallel dio disabled failed"
27578
27579         # Ideally, we would see only one RPC in flight here, but there is an
27580         # unavoidable race between i/o completion and RPC in flight counting,
27581         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27582         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27583         # So instead we just verify it's always < 8.
27584         $LCTL get_param osc.*-OST0000-*.rpc_stats
27585         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27586                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27587                 grep '^$' -B1 | grep . | awk '{print $1}')
27588         [ $ret != "8:" ] ||
27589                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27590 }
27591 run_test 398g "verify parallel dio async RPC submission"
27592
27593 test_398h() { #  LU-13798
27594         local dio_file=$DIR/$tfile.dio
27595
27596         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27597
27598         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27599         stack_trap "rm -f $DIR/$tfile $dio_file"
27600
27601         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27602                 error "parallel dio failed"
27603         diff $DIR/$tfile $dio_file
27604         [[ $? == 0 ]] || error "file diff after aiocp"
27605 }
27606 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27607
27608 test_398i() { #  LU-13798
27609         local dio_file=$DIR/$tfile.dio
27610
27611         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27612
27613         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27614         stack_trap "rm -f $DIR/$tfile $dio_file"
27615
27616         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27617         $LCTL set_param fail_loc=0x1418
27618         # make sure we don't crash and fail properly
27619         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27620                 error "parallel dio page allocation failure succeeded"
27621         diff $DIR/$tfile $dio_file
27622         [[ $? != 0 ]] || error "no diff after failed aiocp"
27623 }
27624 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27625
27626 test_398j() { #  LU-13798
27627         # Stripe size > RPC size but less than i/o size tests split across
27628         # stripes and RPCs for individual i/o op
27629         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27630
27631         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27632         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27633         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27634         stack_trap "$LCTL set_param -n $pages_per_rpc"
27635
27636         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27637                 error "parallel dio write failed"
27638         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27639
27640         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27641                 error "parallel dio read failed"
27642         diff $DIR/$tfile $DIR/$tfile.2
27643         [[ $? == 0 ]] || error "file diff after parallel dio read"
27644 }
27645 run_test 398j "test parallel dio where stripe size > rpc_size"
27646
27647 test_398k() { #  LU-13798
27648         wait_delete_completed
27649         wait_mds_ost_sync
27650
27651         # 4 stripe file; we will cause out of space on OST0
27652         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27653
27654         # Fill OST0 (if it's not too large)
27655         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27656                    head -n1)
27657         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27658                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27659         fi
27660         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27661         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27662                 error "dd should fill OST0"
27663         stack_trap "rm -f $DIR/$tfile.1"
27664
27665         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27666         err=$?
27667
27668         ls -la $DIR/$tfile
27669         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27670                 error "file is not 0 bytes in size"
27671
27672         # dd above should not succeed, but don't error until here so we can
27673         # get debug info above
27674         [[ $err != 0 ]] ||
27675                 error "parallel dio write with enospc succeeded"
27676         stack_trap "rm -f $DIR/$tfile"
27677 }
27678 run_test 398k "test enospc on first stripe"
27679
27680 test_398l() { #  LU-13798
27681         wait_delete_completed
27682         wait_mds_ost_sync
27683
27684         # 4 stripe file; we will cause out of space on OST0
27685         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27686         # happens on the second i/o chunk we issue
27687         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27688
27689         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27690         stack_trap "rm -f $DIR/$tfile"
27691
27692         # Fill OST0 (if it's not too large)
27693         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27694                    head -n1)
27695         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27696                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27697         fi
27698         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27699         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27700                 error "dd should fill OST0"
27701         stack_trap "rm -f $DIR/$tfile.1"
27702
27703         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27704         err=$?
27705         stack_trap "rm -f $DIR/$tfile.2"
27706
27707         # Check that short write completed as expected
27708         ls -la $DIR/$tfile.2
27709         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27710                 error "file is not 1M in size"
27711
27712         # dd above should not succeed, but don't error until here so we can
27713         # get debug info above
27714         [[ $err != 0 ]] ||
27715                 error "parallel dio write with enospc succeeded"
27716
27717         # Truncate source file to same length as output file and diff them
27718         $TRUNCATE $DIR/$tfile 1048576
27719         diff $DIR/$tfile $DIR/$tfile.2
27720         [[ $? == 0 ]] || error "data incorrect after short write"
27721 }
27722 run_test 398l "test enospc on intermediate stripe/RPC"
27723
27724 test_398m() { #  LU-13798
27725         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27726
27727         # Set up failure on OST0, the first stripe:
27728         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27729         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27730         # OST0 is on ost1, OST1 is on ost2.
27731         # So this fail_val specifies OST0
27732         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27733         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27734
27735         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27736                 error "parallel dio write with failure on first stripe succeeded"
27737         stack_trap "rm -f $DIR/$tfile"
27738         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27739
27740         # Place data in file for read
27741         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27742                 error "parallel dio write failed"
27743
27744         # Fail read on OST0, first stripe
27745         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27746         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27747         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27748                 error "parallel dio read with error on first stripe succeeded"
27749         rm -f $DIR/$tfile.2
27750         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27751
27752         # Switch to testing on OST1, second stripe
27753         # Clear file contents, maintain striping
27754         echo > $DIR/$tfile
27755         # Set up failure on OST1, second stripe:
27756         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27757         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27758
27759         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27760                 error "parallel dio write with failure on second stripe succeeded"
27761         stack_trap "rm -f $DIR/$tfile"
27762         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27763
27764         # Place data in file for read
27765         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27766                 error "parallel dio write failed"
27767
27768         # Fail read on OST1, second stripe
27769         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27770         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27771         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27772                 error "parallel dio read with error on second stripe succeeded"
27773         rm -f $DIR/$tfile.2
27774         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27775 }
27776 run_test 398m "test RPC failures with parallel dio"
27777
27778 # Parallel submission of DIO should not cause problems for append, but it's
27779 # important to verify.
27780 test_398n() { #  LU-13798
27781         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27782
27783         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27784                 error "dd to create source file failed"
27785         stack_trap "rm -f $DIR/$tfile"
27786
27787         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27788                 error "parallel dio write with failure on second stripe succeeded"
27789         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27790         diff $DIR/$tfile $DIR/$tfile.1
27791         [[ $? == 0 ]] || error "data incorrect after append"
27792
27793 }
27794 run_test 398n "test append with parallel DIO"
27795
27796 test_398o() {
27797         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27798 }
27799 run_test 398o "right kms with DIO"
27800
27801 test_398p()
27802 {
27803         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27804         which aiocp || skip_env "no aiocp installed"
27805
27806         local stripe_size=$((1024 * 1024)) #1 MiB
27807         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27808         local file_size=$((25 * stripe_size))
27809
27810         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27811         stack_trap "rm -f $DIR/$tfile*"
27812         # Just a bit bigger than the largest size in the test set below
27813         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27814                 error "buffered i/o to create file failed"
27815
27816         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27817                 $((stripe_size * 4)); do
27818
27819                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27820
27821                 echo "bs: $bs, file_size $file_size"
27822                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27823                         $DIR/$tfile.1 $DIR/$tfile.2 &
27824                 pid_dio1=$!
27825                 # Buffered I/O with similar but not the same block size
27826                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27827                         conv=notrunc &
27828                 pid_bio2=$!
27829                 wait $pid_dio1
27830                 rc1=$?
27831                 wait $pid_bio2
27832                 rc2=$?
27833                 if (( rc1 != 0 )); then
27834                         error "aio copy 1 w/bsize $bs failed: $rc1"
27835                 fi
27836                 if (( rc2 != 0 )); then
27837                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27838                 fi
27839
27840                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27841                         error "size incorrect"
27842                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27843                         error "files differ, bsize $bs"
27844                 rm -f $DIR/$tfile.2
27845         done
27846 }
27847 run_test 398p "race aio with buffered i/o"
27848
27849 test_398q()
27850 {
27851         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27852
27853         local stripe_size=$((1024 * 1024)) #1 MiB
27854         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27855         local file_size=$((25 * stripe_size))
27856
27857         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27858         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27859
27860         # Just a bit bigger than the largest size in the test set below
27861         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27862                 error "buffered i/o to create file failed"
27863
27864         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27865                 $((stripe_size * 4)); do
27866
27867                 echo "bs: $bs, file_size $file_size"
27868                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27869                         conv=notrunc oflag=direct iflag=direct &
27870                 pid_dio1=$!
27871                 # Buffered I/O with similar but not the same block size
27872                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27873                         conv=notrunc &
27874                 pid_bio2=$!
27875                 wait $pid_dio1
27876                 rc1=$?
27877                 wait $pid_bio2
27878                 rc2=$?
27879                 if (( rc1 != 0 )); then
27880                         error "dio copy 1 w/bsize $bs failed: $rc1"
27881                 fi
27882                 if (( rc2 != 0 )); then
27883                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27884                 fi
27885
27886                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27887                         error "size incorrect"
27888                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27889                         error "files differ, bsize $bs"
27890         done
27891
27892         rm -f $DIR/$tfile*
27893 }
27894 run_test 398q "race dio with buffered i/o"
27895
27896 test_fake_rw() {
27897         local read_write=$1
27898         if [ "$read_write" = "write" ]; then
27899                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27900         elif [ "$read_write" = "read" ]; then
27901                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27902         else
27903                 error "argument error"
27904         fi
27905
27906         # turn off debug for performance testing
27907         local saved_debug=$($LCTL get_param -n debug)
27908         $LCTL set_param debug=0
27909
27910         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27911
27912         # get ost1 size - $FSNAME-OST0000
27913         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27914         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27915         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27916
27917         if [ "$read_write" = "read" ]; then
27918                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27919         fi
27920
27921         local start_time=$(date +%s.%N)
27922         $dd_cmd bs=1M count=$blocks oflag=sync ||
27923                 error "real dd $read_write error"
27924         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27925
27926         if [ "$read_write" = "write" ]; then
27927                 rm -f $DIR/$tfile
27928         fi
27929
27930         # define OBD_FAIL_OST_FAKE_RW           0x238
27931         do_facet ost1 $LCTL set_param fail_loc=0x238
27932
27933         local start_time=$(date +%s.%N)
27934         $dd_cmd bs=1M count=$blocks oflag=sync ||
27935                 error "fake dd $read_write error"
27936         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27937
27938         if [ "$read_write" = "write" ]; then
27939                 # verify file size
27940                 cancel_lru_locks osc
27941                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27942                         error "$tfile size not $blocks MB"
27943         fi
27944         do_facet ost1 $LCTL set_param fail_loc=0
27945
27946         echo "fake $read_write $duration_fake vs. normal $read_write" \
27947                 "$duration in seconds"
27948         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27949                 error_not_in_vm "fake write is slower"
27950
27951         $LCTL set_param -n debug="$saved_debug"
27952         rm -f $DIR/$tfile
27953 }
27954 test_399a() { # LU-7655 for OST fake write
27955         remote_ost_nodsh && skip "remote OST with nodsh"
27956
27957         test_fake_rw write
27958 }
27959 run_test 399a "fake write should not be slower than normal write"
27960
27961 test_399b() { # LU-8726 for OST fake read
27962         remote_ost_nodsh && skip "remote OST with nodsh"
27963         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27964                 skip_env "ldiskfs only test"
27965         fi
27966
27967         test_fake_rw read
27968 }
27969 run_test 399b "fake read should not be slower than normal read"
27970
27971 test_400a() { # LU-1606, was conf-sanity test_74
27972         if ! which $CC > /dev/null 2>&1; then
27973                 skip_env "$CC is not installed"
27974         fi
27975
27976         local extra_flags=''
27977         local out=$TMP/$tfile
27978         local prefix=/usr/include/lustre
27979         local prog
27980
27981         # Oleg removes .c files in his test rig so test if any c files exist
27982         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27983                 skip_env "Needed .c test files are missing"
27984
27985         if ! [[ -d $prefix ]]; then
27986                 # Assume we're running in tree and fixup the include path.
27987                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27988                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27989                 extra_flags+=" -L$LUSTRE/utils/.libs"
27990         fi
27991
27992         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27993                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27994                         error "client api broken"
27995         done
27996         rm -f $out
27997 }
27998 run_test 400a "Lustre client api program can compile and link"
27999
28000 test_400b() { # LU-1606, LU-5011
28001         local header
28002         local out=$TMP/$tfile
28003         local prefix=/usr/include/linux/lustre
28004
28005         # We use a hard coded prefix so that this test will not fail
28006         # when run in tree. There are headers in lustre/include/lustre/
28007         # that are not packaged (like lustre_idl.h) and have more
28008         # complicated include dependencies (like config.h and lnet/types.h).
28009         # Since this test about correct packaging we just skip them when
28010         # they don't exist (see below) rather than try to fixup cppflags.
28011
28012         if ! which $CC > /dev/null 2>&1; then
28013                 skip_env "$CC is not installed"
28014         fi
28015
28016         for header in $prefix/*.h; do
28017                 if ! [[ -f "$header" ]]; then
28018                         continue
28019                 fi
28020
28021                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
28022                         continue # lustre_ioctl.h is internal header
28023                 fi
28024
28025                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
28026                         error "cannot compile '$header'"
28027         done
28028         rm -f $out
28029 }
28030 run_test 400b "packaged headers can be compiled"
28031
28032 test_401a() { #LU-7437
28033         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
28034         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
28035
28036         #count the number of parameters by "list_param -R"
28037         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
28038         #count the number of parameters by listing proc files
28039         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
28040         echo "proc_dirs='$proc_dirs'"
28041         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
28042         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
28043                       sort -u | wc -l)
28044
28045         [ $params -eq $procs ] ||
28046                 error "found $params parameters vs. $procs proc files"
28047
28048         # test the list_param -D option only returns directories
28049         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
28050         #count the number of parameters by listing proc directories
28051         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
28052                 sort -u | wc -l)
28053
28054         [ $params -eq $procs ] ||
28055                 error "found $params parameters vs. $procs proc files"
28056 }
28057 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
28058
28059 test_401b() {
28060         # jobid_var may not allow arbitrary values, so use jobid_name
28061         # if available
28062         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28063                 local testname=jobid_name tmp='testing%p'
28064         else
28065                 local testname=jobid_var tmp=testing
28066         fi
28067
28068         local save=$($LCTL get_param -n $testname)
28069
28070         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
28071                 error "no error returned when setting bad parameters"
28072
28073         local jobid_new=$($LCTL get_param -n foe $testname baz)
28074         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
28075
28076         $LCTL set_param -n fog=bam $testname=$save bat=fog
28077         local jobid_old=$($LCTL get_param -n foe $testname bag)
28078         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
28079 }
28080 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
28081
28082 test_401c() {
28083         # jobid_var may not allow arbitrary values, so use jobid_name
28084         # if available
28085         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28086                 local testname=jobid_name
28087         else
28088                 local testname=jobid_var
28089         fi
28090
28091         local jobid_var_old=$($LCTL get_param -n $testname)
28092         local jobid_var_new
28093
28094         $LCTL set_param $testname= &&
28095                 error "no error returned for 'set_param a='"
28096
28097         jobid_var_new=$($LCTL get_param -n $testname)
28098         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28099                 error "$testname was changed by setting without value"
28100
28101         $LCTL set_param $testname &&
28102                 error "no error returned for 'set_param a'"
28103
28104         jobid_var_new=$($LCTL get_param -n $testname)
28105         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
28106                 error "$testname was changed by setting without value"
28107 }
28108 run_test 401c "Verify 'lctl set_param' without value fails in either format."
28109
28110 test_401d() {
28111         # jobid_var may not allow arbitrary values, so use jobid_name
28112         # if available
28113         if $LCTL list_param jobid_name > /dev/null 2>&1; then
28114                 local testname=jobid_name new_value='foo=bar%p'
28115         else
28116                 local testname=jobid_var new_valuie=foo=bar
28117         fi
28118
28119         local jobid_var_old=$($LCTL get_param -n $testname)
28120         local jobid_var_new
28121
28122         $LCTL set_param $testname=$new_value ||
28123                 error "'set_param a=b' did not accept a value containing '='"
28124
28125         jobid_var_new=$($LCTL get_param -n $testname)
28126         [[ "$jobid_var_new" == "$new_value" ]] ||
28127                 error "'set_param a=b' failed on a value containing '='"
28128
28129         # Reset the $testname to test the other format
28130         $LCTL set_param $testname=$jobid_var_old
28131         jobid_var_new=$($LCTL get_param -n $testname)
28132         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28133                 error "failed to reset $testname"
28134
28135         $LCTL set_param $testname $new_value ||
28136                 error "'set_param a b' did not accept a value containing '='"
28137
28138         jobid_var_new=$($LCTL get_param -n $testname)
28139         [[ "$jobid_var_new" == "$new_value" ]] ||
28140                 error "'set_param a b' failed on a value containing '='"
28141
28142         $LCTL set_param $testname $jobid_var_old
28143         jobid_var_new=$($LCTL get_param -n $testname)
28144         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
28145                 error "failed to reset $testname"
28146 }
28147 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
28148
28149 test_401e() { # LU-14779
28150         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
28151                 error "lctl list_param MGC* failed"
28152         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
28153         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
28154                 error "lctl get_param lru_size failed"
28155 }
28156 run_test 401e "verify 'lctl get_param' works with NID in parameter"
28157
28158 test_402() {
28159         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
28160         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
28161                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
28162         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
28163                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
28164                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
28165         remote_mds_nodsh && skip "remote MDS with nodsh"
28166
28167         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
28168 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
28169         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
28170         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
28171                 echo "Touch failed - OK"
28172 }
28173 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
28174
28175 test_403() {
28176         local file1=$DIR/$tfile.1
28177         local file2=$DIR/$tfile.2
28178         local tfile=$TMP/$tfile
28179
28180         rm -f $file1 $file2 $tfile
28181
28182         touch $file1
28183         ln $file1 $file2
28184
28185         # 30 sec OBD_TIMEOUT in ll_getattr()
28186         # right before populating st_nlink
28187         $LCTL set_param fail_loc=0x80001409
28188         stat -c %h $file1 > $tfile &
28189
28190         # create an alias, drop all locks and reclaim the dentry
28191         < $file2
28192         cancel_lru_locks mdc
28193         cancel_lru_locks osc
28194         sysctl -w vm.drop_caches=2
28195
28196         wait
28197
28198         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
28199
28200         rm -f $tfile $file1 $file2
28201 }
28202 run_test 403 "i_nlink should not drop to zero due to aliasing"
28203
28204 test_404() { # LU-6601
28205         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
28206                 skip "Need server version newer than 2.8.52"
28207         remote_mds_nodsh && skip "remote MDS with nodsh"
28208
28209         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
28210                 awk '/osp .*-osc-MDT/ { print $4}')
28211
28212         local osp
28213         for osp in $mosps; do
28214                 echo "Deactivate: " $osp
28215                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
28216                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28217                         awk -vp=$osp '$4 == p { print $2 }')
28218                 [ $stat = IN ] || {
28219                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28220                         error "deactivate error"
28221                 }
28222                 echo "Activate: " $osp
28223                 do_facet $SINGLEMDS $LCTL --device %$osp activate
28224                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
28225                         awk -vp=$osp '$4 == p { print $2 }')
28226                 [ $stat = UP ] || {
28227                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
28228                         error "activate error"
28229                 }
28230         done
28231 }
28232 run_test 404 "validate manual {de}activated works properly for OSPs"
28233
28234 test_405() {
28235         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28236         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
28237                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
28238                         skip "Layout swap lock is not supported"
28239
28240         check_swap_layouts_support
28241         check_swap_layout_no_dom $DIR
28242
28243         test_mkdir $DIR/$tdir
28244         swap_lock_test -d $DIR/$tdir ||
28245                 error "One layout swap locked test failed"
28246 }
28247 run_test 405 "Various layout swap lock tests"
28248
28249 test_406() {
28250         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28251         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
28252         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
28253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28254         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
28255                 skip "Need MDS version at least 2.8.50"
28256
28257         local def_stripe_size=$($LFS getstripe -S $MOUNT)
28258         local test_pool=$TESTNAME
28259
28260         pool_add $test_pool || error "pool_add failed"
28261         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
28262                 error "pool_add_targets failed"
28263
28264         save_layout_restore_at_exit $MOUNT
28265
28266         # parent set default stripe count only, child will stripe from both
28267         # parent and fs default
28268         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
28269                 error "setstripe $MOUNT failed"
28270         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
28271         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
28272         for i in $(seq 10); do
28273                 local f=$DIR/$tdir/$tfile.$i
28274                 touch $f || error "touch failed"
28275                 local count=$($LFS getstripe -c $f)
28276                 [ $count -eq $OSTCOUNT ] ||
28277                         error "$f stripe count $count != $OSTCOUNT"
28278                 local offset=$($LFS getstripe -i $f)
28279                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
28280                 local size=$($LFS getstripe -S $f)
28281                 [ $size -eq $((def_stripe_size * 2)) ] ||
28282                         error "$f stripe size $size != $((def_stripe_size * 2))"
28283                 local pool=$($LFS getstripe -p $f)
28284                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
28285         done
28286
28287         # change fs default striping, delete parent default striping, now child
28288         # will stripe from new fs default striping only
28289         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
28290                 error "change $MOUNT default stripe failed"
28291         $LFS setstripe -c 0 $DIR/$tdir ||
28292                 error "delete $tdir default stripe failed"
28293         for i in $(seq 11 20); do
28294                 local f=$DIR/$tdir/$tfile.$i
28295                 touch $f || error "touch $f failed"
28296                 local count=$($LFS getstripe -c $f)
28297                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
28298                 local offset=$($LFS getstripe -i $f)
28299                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
28300                 local size=$($LFS getstripe -S $f)
28301                 [ $size -eq $def_stripe_size ] ||
28302                         error "$f stripe size $size != $def_stripe_size"
28303                 local pool=$($LFS getstripe -p $f)
28304                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
28305         done
28306
28307         unlinkmany $DIR/$tdir/$tfile. 1 20
28308
28309         local f=$DIR/$tdir/$tfile
28310         pool_remove_all_targets $test_pool $f
28311         pool_remove $test_pool $f
28312 }
28313 run_test 406 "DNE support fs default striping"
28314
28315 test_407() {
28316         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28317         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
28318                 skip "Need MDS version at least 2.8.55"
28319         remote_mds_nodsh && skip "remote MDS with nodsh"
28320
28321         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
28322                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
28323         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
28324                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
28325         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
28326
28327         #define OBD_FAIL_DT_TXN_STOP    0x2019
28328         for idx in $(seq $MDSCOUNT); do
28329                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
28330         done
28331         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
28332         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
28333                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
28334         true
28335 }
28336 run_test 407 "transaction fail should cause operation fail"
28337
28338 test_408() {
28339         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
28340
28341         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
28342         lctl set_param fail_loc=0x8000040a
28343         # let ll_prepare_partial_page() fail
28344         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
28345
28346         rm -f $DIR/$tfile
28347
28348         # create at least 100 unused inodes so that
28349         # shrink_icache_memory(0) should not return 0
28350         touch $DIR/$tfile-{0..100}
28351         rm -f $DIR/$tfile-{0..100}
28352         sync
28353
28354         echo 2 > /proc/sys/vm/drop_caches
28355 }
28356 run_test 408 "drop_caches should not hang due to page leaks"
28357
28358 test_409()
28359 {
28360         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
28361
28362         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
28363         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
28364         touch $DIR/$tdir/guard || error "(2) Fail to create"
28365
28366         local PREFIX=$(str_repeat 'A' 128)
28367         echo "Create 1K hard links start at $(date)"
28368         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28369                 error "(3) Fail to hard link"
28370
28371         echo "Links count should be right although linkEA overflow"
28372         stat $DIR/$tdir/guard || error "(4) Fail to stat"
28373         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
28374         [ $linkcount -eq 1001 ] ||
28375                 error "(5) Unexpected hard links count: $linkcount"
28376
28377         echo "List all links start at $(date)"
28378         ls -l $DIR/$tdir/foo > /dev/null ||
28379                 error "(6) Fail to list $DIR/$tdir/foo"
28380
28381         echo "Unlink hard links start at $(date)"
28382         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
28383                 error "(7) Fail to unlink"
28384         echo "Unlink hard links finished at $(date)"
28385 }
28386 run_test 409 "Large amount of cross-MDTs hard links on the same file"
28387
28388 test_410()
28389 {
28390         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
28391                 skip "Need client version at least 2.9.59"
28392         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
28393                 skip "Need MODULES build"
28394
28395         # Create a file, and stat it from the kernel
28396         local testfile=$DIR/$tfile
28397         touch $testfile
28398
28399         local run_id=$RANDOM
28400         local my_ino=$(stat --format "%i" $testfile)
28401
28402         # Try to insert the module. This will always fail as the
28403         # module is designed to not be inserted.
28404         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
28405             &> /dev/null
28406
28407         # Anything but success is a test failure
28408         dmesg | grep -q \
28409             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
28410             error "no inode match"
28411 }
28412 run_test 410 "Test inode number returned from kernel thread"
28413
28414 cleanup_test411_cgroup() {
28415         trap 0
28416         cat $1/memory.stat
28417         rmdir "$1"
28418 }
28419
28420 test_411a() {
28421         local cg_basedir=/sys/fs/cgroup/memory
28422         # LU-9966
28423         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
28424                 skip "no setup for cgroup"
28425
28426         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28427                 error "test file creation failed"
28428         cancel_lru_locks osc
28429
28430         # Create a very small memory cgroup to force a slab allocation error
28431         local cgdir=$cg_basedir/osc_slab_alloc
28432         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28433         trap "cleanup_test411_cgroup $cgdir" EXIT
28434         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28435         echo 1M > $cgdir/memory.limit_in_bytes
28436
28437         # Should not LBUG, just be killed by oom-killer
28438         # dd will return 0 even allocation failure in some environment.
28439         # So don't check return value
28440         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28441         cleanup_test411_cgroup $cgdir
28442
28443         return 0
28444 }
28445 run_test 411a "Slab allocation error with cgroup does not LBUG"
28446
28447 test_411b() {
28448         local cg_basedir=/sys/fs/cgroup/memory
28449         # LU-9966
28450         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28451                 skip "no setup for cgroup"
28452         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28453         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28454         # limit, so we have 384M in cgroup
28455         # (arm) this seems to hit OOM more often than x86, so 1024M
28456         if [[ $(uname -m) = aarch64 ]]; then
28457                 local memlimit_mb=1024
28458         else
28459                 local memlimit_mb=384
28460         fi
28461
28462         # Create a cgroup and set memory limit
28463         # (tfile is used as an easy way to get a recognizable cgroup name)
28464         local cgdir=$cg_basedir/$tfile
28465         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28466         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28467         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28468
28469         echo "writing first file"
28470         # Write a file 4x the memory limit in size
28471         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28472                 error "(1) failed to write successfully"
28473
28474         sync
28475         cancel_lru_locks osc
28476
28477         rm -f $DIR/$tfile
28478         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28479
28480         # Try writing at a larger block size
28481         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28482         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28483         # need *some* memory to do IO in)
28484         echo "writing at larger block size"
28485         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28486                 error "(3) failed to write successfully"
28487
28488         sync
28489         cancel_lru_locks osc
28490         rm -f $DIR/$tfile
28491         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28492
28493         # Try writing multiple files at once
28494         echo "writing multiple files"
28495         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28496         local pid1=$!
28497         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28498         local pid2=$!
28499         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28500         local pid3=$!
28501         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28502         local pid4=$!
28503
28504         wait $pid1
28505         local rc1=$?
28506         wait $pid2
28507         local rc2=$?
28508         wait $pid3
28509         local rc3=$?
28510         wait $pid4
28511         local rc4=$?
28512         if (( rc1 != 0)); then
28513                 error "error $rc1 writing to file from $pid1"
28514         fi
28515         if (( rc2 != 0)); then
28516                 error "error $rc2 writing to file from $pid2"
28517         fi
28518         if (( rc3 != 0)); then
28519                 error "error $rc3 writing to file from $pid3"
28520         fi
28521         if (( rc4 != 0)); then
28522                 error "error $rc4 writing to file from $pid4"
28523         fi
28524
28525         sync
28526         cancel_lru_locks osc
28527
28528         # These files can be large-ish (~1 GiB total), so delete them rather
28529         # than leave for later cleanup
28530         rm -f $DIR/$tfile.*
28531         return 0
28532 }
28533 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28534
28535 test_412() {
28536         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28537         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28538                 skip "Need server version at least 2.10.55"
28539
28540         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28541                 error "mkdir failed"
28542         $LFS getdirstripe $DIR/$tdir
28543         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28544         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28545                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28546         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28547         [ $stripe_count -eq 2 ] ||
28548                 error "expect 2 get $stripe_count"
28549
28550         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28551
28552         local index
28553         local index2
28554
28555         # subdirs should be on the same MDT as parent
28556         for i in $(seq 0 $((MDSCOUNT - 1))); do
28557                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28558                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28559                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28560                 (( index == i )) || error "mdt$i/sub on MDT$index"
28561         done
28562
28563         # stripe offset -1, ditto
28564         for i in {1..10}; do
28565                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28566                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28567                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28568                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28569                 (( index == index2 )) ||
28570                         error "qos$i on MDT$index, sub on MDT$index2"
28571         done
28572
28573         local testdir=$DIR/$tdir/inherit
28574
28575         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28576         # inherit 2 levels
28577         for i in 1 2; do
28578                 testdir=$testdir/s$i
28579                 mkdir $testdir || error "mkdir $testdir failed"
28580                 index=$($LFS getstripe -m $testdir)
28581                 (( index == 1 )) ||
28582                         error "$testdir on MDT$index"
28583         done
28584
28585         # not inherit any more
28586         testdir=$testdir/s3
28587         mkdir $testdir || error "mkdir $testdir failed"
28588         getfattr -d -m dmv $testdir | grep dmv &&
28589                 error "default LMV set on $testdir" || true
28590 }
28591 run_test 412 "mkdir on specific MDTs"
28592
28593 TEST413_COUNT=${TEST413_COUNT:-200}
28594
28595 #
28596 # set_maxage() is used by test_413 only.
28597 # This is a helper function to set maxage. Does not return any value.
28598 # Input: maxage to set
28599 #
28600 set_maxage() {
28601         local lmv_qos_maxage
28602         local lod_qos_maxage
28603         local new_maxage=$1
28604
28605         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28606         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28607         stack_trap "$LCTL set_param \
28608                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28609         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28610                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28611         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28612                 lod.*.mdt_qos_maxage=$new_maxage
28613         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28614                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28615 }
28616
28617 generate_uneven_mdts() {
28618         local threshold=$1
28619         local ffree
28620         local bavail
28621         local max
28622         local min
28623         local max_index
28624         local min_index
28625         local tmp
28626         local i
28627
28628         echo
28629         echo "Check for uneven MDTs: "
28630
28631         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28632         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28633         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28634
28635         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28636         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28637         max_index=0
28638         min_index=0
28639         for ((i = 1; i < ${#ffree[@]}; i++)); do
28640                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28641                 if [ $tmp -gt $max ]; then
28642                         max=$tmp
28643                         max_index=$i
28644                 fi
28645                 if [ $tmp -lt $min ]; then
28646                         min=$tmp
28647                         min_index=$i
28648                 fi
28649         done
28650
28651         (( min > 0 )) || skip "low space on MDT$min_index"
28652         (( ${ffree[min_index]} > 0 )) ||
28653                 skip "no free files on MDT$min_index"
28654         (( ${ffree[min_index]} < 10000000 )) ||
28655                 skip "too many free files on MDT$min_index"
28656
28657         # Check if we need to generate uneven MDTs
28658         local diff=$(((max - min) * 100 / min))
28659         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28660         local testdir # individual folder within $testdirp
28661         local start
28662         local cmd
28663
28664         # fallocate is faster to consume space on MDT, if available
28665         if check_fallocate_supported mds$((min_index + 1)); then
28666                 cmd="fallocate -l 128K "
28667         else
28668                 cmd="dd if=/dev/zero bs=128K count=1 of="
28669         fi
28670
28671         echo "using cmd $cmd"
28672         for (( i = 0; diff < threshold; i++ )); do
28673                 testdir=${testdirp}/$i
28674                 [ -d $testdir ] && continue
28675
28676                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28677
28678                 mkdir -p $testdirp
28679                 # generate uneven MDTs, create till $threshold% diff
28680                 echo -n "weight diff=$diff% must be > $threshold% ..."
28681                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28682                 $LFS mkdir -i $min_index $testdir ||
28683                         error "mkdir $testdir failed"
28684                 $LFS setstripe -E 1M -L mdt $testdir ||
28685                         error "setstripe $testdir failed"
28686                 start=$SECONDS
28687                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28688                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28689                 done
28690                 sync; sleep 1; sync
28691
28692                 # wait for QOS to update
28693                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28694
28695                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28696                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28697                 max=$(((${ffree[max_index]} >> 8) *
28698                         (${bavail[max_index]} * bsize >> 16)))
28699                 min=$(((${ffree[min_index]} >> 8) *
28700                         (${bavail[min_index]} * bsize >> 16)))
28701                 (( min > 0 )) || skip "low space on MDT$min_index"
28702                 diff=$(((max - min) * 100 / min))
28703         done
28704
28705         echo "MDT filesfree available: ${ffree[*]}"
28706         echo "MDT blocks available: ${bavail[*]}"
28707         echo "weight diff=$diff%"
28708 }
28709
28710 test_qos_mkdir() {
28711         local mkdir_cmd=$1
28712         local stripe_count=$2
28713         local mdts=$(comma_list $(mdts_nodes))
28714
28715         local testdir
28716         local lmv_qos_prio_free
28717         local lmv_qos_threshold_rr
28718         local lod_qos_prio_free
28719         local lod_qos_threshold_rr
28720         local total
28721         local count
28722         local i
28723
28724         # @total is total directories created if it's testing plain
28725         # directories, otherwise it's total stripe object count for
28726         # striped directories test.
28727         # remote/striped directory unlinking is slow on zfs and may
28728         # timeout, test with fewer directories
28729         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28730
28731         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28732         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28733         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28734                 head -n1)
28735         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28736         stack_trap "$LCTL set_param \
28737                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28738         stack_trap "$LCTL set_param \
28739                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28740
28741         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28742                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28743         lod_qos_prio_free=${lod_qos_prio_free%%%}
28744         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28745                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28746         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28747         stack_trap "do_nodes $mdts $LCTL set_param \
28748                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28749         stack_trap "do_nodes $mdts $LCTL set_param \
28750                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28751
28752         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28753         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28754
28755         testdir=$DIR/$tdir-s$stripe_count/rr
28756
28757         local stripe_index=$($LFS getstripe -m $testdir)
28758         local test_mkdir_rr=true
28759
28760         getfattr -d -m dmv -e hex $testdir | grep dmv
28761         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28762                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28763                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28764                         test_mkdir_rr=false
28765         fi
28766
28767         echo
28768         $test_mkdir_rr &&
28769                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28770                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28771
28772         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28773         for (( i = 0; i < total / stripe_count; i++ )); do
28774                 eval $mkdir_cmd $testdir/subdir$i ||
28775                         error "$mkdir_cmd subdir$i failed"
28776         done
28777
28778         for (( i = 0; i < $MDSCOUNT; i++ )); do
28779                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28780                 echo "$count directories created on MDT$i"
28781                 if $test_mkdir_rr; then
28782                         (( count == total / stripe_count / MDSCOUNT )) ||
28783                                 error "subdirs are not evenly distributed"
28784                 elif (( i == stripe_index )); then
28785                         (( count == total / stripe_count )) ||
28786                                 error "$count subdirs created on MDT$i"
28787                 else
28788                         (( count == 0 )) ||
28789                                 error "$count subdirs created on MDT$i"
28790                 fi
28791
28792                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28793                         count=$($LFS getdirstripe $testdir/* |
28794                                 grep -c -P "^\s+$i\t")
28795                         echo "$count stripes created on MDT$i"
28796                         # deviation should < 5% of average
28797                         delta=$((count - total / MDSCOUNT))
28798                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28799                                 error "stripes are not evenly distributed"
28800                 fi
28801         done
28802
28803         echo
28804         echo "Check for uneven MDTs: "
28805
28806         local ffree
28807         local bavail
28808         local max
28809         local min
28810         local max_index
28811         local min_index
28812         local tmp
28813
28814         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28815         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28816         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28817
28818         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28819         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28820         max_index=0
28821         min_index=0
28822         for ((i = 1; i < ${#ffree[@]}; i++)); do
28823                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28824                 if [ $tmp -gt $max ]; then
28825                         max=$tmp
28826                         max_index=$i
28827                 fi
28828                 if [ $tmp -lt $min ]; then
28829                         min=$tmp
28830                         min_index=$i
28831                 fi
28832         done
28833         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28834
28835         (( min > 0 )) || skip "low space on MDT$min_index"
28836         (( ${ffree[min_index]} < 10000000 )) ||
28837                 skip "too many free files on MDT$min_index"
28838
28839         generate_uneven_mdts 120
28840
28841         echo "MDT filesfree available: ${ffree[*]}"
28842         echo "MDT blocks available: ${bavail[*]}"
28843         echo "weight diff=$(((max - min) * 100 / min))%"
28844         echo
28845         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28846
28847         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28848         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28849         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28850         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28851         # decrease statfs age, so that it can be updated in time
28852         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28853         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28854
28855         sleep 1
28856
28857         testdir=$DIR/$tdir-s$stripe_count/qos
28858
28859         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28860         for (( i = 0; i < total / stripe_count; i++ )); do
28861                 eval $mkdir_cmd $testdir/subdir$i ||
28862                         error "$mkdir_cmd subdir$i failed"
28863         done
28864
28865         max=0
28866         for (( i = 0; i < $MDSCOUNT; i++ )); do
28867                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28868                 (( count > max )) && max=$count
28869                 echo "$count directories created on MDT$i : curmax=$max"
28870         done
28871
28872         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28873
28874         # D-value should > 10% of average
28875         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28876                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28877
28878         # ditto for stripes
28879         if (( stripe_count > 1 )); then
28880                 max=0
28881                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28882                         count=$($LFS getdirstripe $testdir/* |
28883                                 grep -c -P "^\s+$i\t")
28884                         (( count > max )) && max=$count
28885                         echo "$count stripes created on MDT$i"
28886                 done
28887
28888                 min=$($LFS getdirstripe $testdir/* |
28889                         grep -c -P "^\s+$min_index\t")
28890                 (( max - min > total / MDSCOUNT / 10 )) ||
28891                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28892         fi
28893 }
28894
28895 most_full_mdt() {
28896         local ffree
28897         local bavail
28898         local bsize
28899         local min
28900         local min_index
28901         local tmp
28902
28903         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28904         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28905         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28906
28907         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28908         min_index=0
28909         for ((i = 1; i < ${#ffree[@]}; i++)); do
28910                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28911                 (( tmp < min )) && min=$tmp && min_index=$i
28912         done
28913
28914         echo -n $min_index
28915 }
28916
28917 test_413a() {
28918         [ $MDSCOUNT -lt 2 ] &&
28919                 skip "We need at least 2 MDTs for this test"
28920
28921         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28922                 skip "Need server version at least 2.12.52"
28923
28924         local stripe_max=$((MDSCOUNT - 1))
28925         local stripe_count
28926
28927         # let caller set maxage for latest result
28928         set_maxage 1
28929
28930         # fill MDT unevenly
28931         generate_uneven_mdts 120
28932
28933         # test 4-stripe directory at most, otherwise it's too slow
28934         # We are being very defensive. Although Autotest uses 4 MDTs.
28935         # We make sure stripe_max does not go over 4.
28936         (( stripe_max > 4 )) && stripe_max=4
28937         # unlinking striped directory is slow on zfs, and may timeout, only test
28938         # plain directory
28939         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28940         for stripe_count in $(seq 1 $stripe_max); do
28941                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28942                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28943                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28944                         error "mkdir failed"
28945                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28946         done
28947 }
28948 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28949
28950 test_413b() {
28951         [ $MDSCOUNT -lt 2 ] &&
28952                 skip "We need at least 2 MDTs for this test"
28953
28954         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28955                 skip "Need server version at least 2.12.52"
28956
28957         local stripe_max=$((MDSCOUNT - 1))
28958         local testdir
28959         local stripe_count
28960
28961         # let caller set maxage for latest result
28962         set_maxage 1
28963
28964         # fill MDT unevenly
28965         generate_uneven_mdts 120
28966
28967         # test 4-stripe directory at most, otherwise it's too slow
28968         # We are being very defensive. Although Autotest uses 4 MDTs.
28969         # We make sure stripe_max does not go over 4.
28970         (( stripe_max > 4 )) && stripe_max=4
28971         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28972         for stripe_count in $(seq 1 $stripe_max); do
28973                 testdir=$DIR/$tdir-s$stripe_count
28974                 mkdir $testdir || error "mkdir $testdir failed"
28975                 mkdir $testdir/rr || error "mkdir rr failed"
28976                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28977                         error "mkdir qos failed"
28978                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28979                         $testdir/rr || error "setdirstripe rr failed"
28980                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28981                         error "setdirstripe failed"
28982                 test_qos_mkdir "mkdir" $stripe_count
28983         done
28984 }
28985 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28986
28987 test_413c() {
28988         (( $MDSCOUNT >= 2 )) ||
28989                 skip "We need at least 2 MDTs for this test"
28990
28991         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28992                 skip "Need server version at least 2.14.51"
28993
28994         local testdir
28995         local inherit
28996         local inherit_rr
28997         local lmv_qos_maxage
28998         local lod_qos_maxage
28999
29000         # let caller set maxage for latest result
29001         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29002         $LCTL set_param lmv.*.qos_maxage=1
29003         stack_trap "$LCTL set_param \
29004                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
29005         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
29006                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
29007         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29008                 lod.*.mdt_qos_maxage=1
29009         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
29010                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
29011
29012         # fill MDT unevenly
29013         generate_uneven_mdts 120
29014
29015         testdir=$DIR/${tdir}-s1
29016         mkdir $testdir || error "mkdir $testdir failed"
29017         mkdir $testdir/rr || error "mkdir rr failed"
29018         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
29019         # default max_inherit is -1, default max_inherit_rr is 0
29020         $LFS setdirstripe -D -c 1 $testdir/rr ||
29021                 error "setdirstripe rr failed"
29022         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
29023                 error "setdirstripe qos failed"
29024         test_qos_mkdir "mkdir" 1
29025
29026         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
29027         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
29028         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
29029         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
29030         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
29031
29032         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
29033         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
29034         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
29035         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
29036         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
29037         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
29038         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
29039                 error "level2 shouldn't have default LMV" || true
29040 }
29041 run_test 413c "mkdir with default LMV max inherit rr"
29042
29043 test_413d() {
29044         (( MDSCOUNT >= 2 )) ||
29045                 skip "We need at least 2 MDTs for this test"
29046
29047         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
29048                 skip "Need server version at least 2.14.51"
29049
29050         local lmv_qos_threshold_rr
29051
29052         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
29053                 head -n1)
29054         stack_trap "$LCTL set_param \
29055                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
29056
29057         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
29058         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29059         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
29060                 error "$tdir shouldn't have default LMV"
29061         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
29062                 error "mkdir sub failed"
29063
29064         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
29065
29066         (( count == 100 )) || error "$count subdirs on MDT0"
29067 }
29068 run_test 413d "inherit ROOT default LMV"
29069
29070 test_413e() {
29071         (( MDSCOUNT >= 2 )) ||
29072                 skip "We need at least 2 MDTs for this test"
29073         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29074                 skip "Need server version at least 2.14.55"
29075
29076         local testdir=$DIR/$tdir
29077         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
29078         local max_inherit
29079         local sub_max_inherit
29080
29081         mkdir -p $testdir || error "failed to create $testdir"
29082
29083         # set default max-inherit to -1 if stripe count is 0 or 1
29084         $LFS setdirstripe -D -c 1 $testdir ||
29085                 error "failed to set default LMV"
29086         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29087         (( max_inherit == -1 )) ||
29088                 error "wrong max_inherit value $max_inherit"
29089
29090         # set default max_inherit to a fixed value if stripe count is not 0 or 1
29091         $LFS setdirstripe -D -c -1 $testdir ||
29092                 error "failed to set default LMV"
29093         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29094         (( max_inherit > 0 )) ||
29095                 error "wrong max_inherit value $max_inherit"
29096
29097         # and the subdir will decrease the max_inherit by 1
29098         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
29099         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
29100         (( sub_max_inherit == max_inherit - 1)) ||
29101                 error "wrong max-inherit of subdir $sub_max_inherit"
29102
29103         # check specified --max-inherit and warning message
29104         stack_trap "rm -f $tmpfile"
29105         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
29106                 error "failed to set default LMV"
29107         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
29108         (( max_inherit == -1 )) ||
29109                 error "wrong max_inherit value $max_inherit"
29110
29111         # check the warning messages
29112         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
29113                 error "failed to detect warning string"
29114         fi
29115 }
29116 run_test 413e "check default max-inherit value"
29117
29118 test_fs_dmv_inherit()
29119 {
29120         local testdir=$DIR/$tdir
29121
29122         local count
29123         local inherit
29124         local inherit_rr
29125
29126         for i in 1 2; do
29127                 mkdir $testdir || error "mkdir $testdir failed"
29128                 count=$($LFS getdirstripe -D -c $testdir)
29129                 (( count == 1 )) ||
29130                         error "$testdir default LMV count mismatch $count != 1"
29131                 inherit=$($LFS getdirstripe -D -X $testdir)
29132                 (( inherit == 3 - i )) ||
29133                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
29134                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29135                 (( inherit_rr == 3 - i )) ||
29136                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
29137                 testdir=$testdir/sub
29138         done
29139
29140         mkdir $testdir || error "mkdir $testdir failed"
29141         count=$($LFS getdirstripe -D -c $testdir)
29142         (( count == 0 )) ||
29143                 error "$testdir default LMV count not zero: $count"
29144 }
29145
29146 test_413f() {
29147         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29148
29149         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29150                 skip "Need server version at least 2.14.55"
29151
29152         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29153                 error "dump $DIR default LMV failed"
29154         stack_trap "setfattr --restore=$TMP/dmv.ea"
29155
29156         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29157                 error "set $DIR default LMV failed"
29158
29159         test_fs_dmv_inherit
29160 }
29161 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
29162
29163 test_413g() {
29164         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
29165
29166         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
29167         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29168                 error "dump $DIR default LMV failed"
29169         stack_trap "setfattr --restore=$TMP/dmv.ea"
29170
29171         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
29172                 error "set $DIR default LMV failed"
29173
29174         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
29175                 error "mount $MOUNT2 failed"
29176         stack_trap "umount_client $MOUNT2"
29177
29178         local saved_DIR=$DIR
29179
29180         export DIR=$MOUNT2
29181
29182         stack_trap "export DIR=$saved_DIR"
29183
29184         # first check filesystem-wide default LMV inheritance
29185         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
29186
29187         # then check subdirs are spread to all MDTs
29188         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
29189
29190         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
29191
29192         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
29193 }
29194 run_test 413g "enforce ROOT default LMV on subdir mount"
29195
29196 test_413h() {
29197         (( MDSCOUNT >= 2 )) ||
29198                 skip "We need at least 2 MDTs for this test"
29199
29200         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
29201                 skip "Need server version at least 2.15.50.6"
29202
29203         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
29204
29205         stack_trap "$LCTL set_param \
29206                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
29207         $LCTL set_param lmv.*.qos_maxage=1
29208
29209         local depth=5
29210         local rr_depth=4
29211         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
29212         local count=$((MDSCOUNT * 20))
29213
29214         generate_uneven_mdts 50
29215
29216         mkdir -p $dir || error "mkdir $dir failed"
29217         stack_trap "rm -rf $dir"
29218         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
29219                 --max-inherit-rr=$rr_depth $dir
29220
29221         for ((d=0; d < depth + 2; d++)); do
29222                 log "dir=$dir:"
29223                 for ((sub=0; sub < count; sub++)); do
29224                         mkdir $dir/d$sub
29225                 done
29226                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
29227                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
29228                 # subdirs within $rr_depth should be created round-robin
29229                 if (( d < rr_depth )); then
29230                         (( ${num[0]} != count )) ||
29231                                 error "all objects created on MDT ${num[1]}"
29232                 fi
29233
29234                 dir=$dir/d0
29235         done
29236 }
29237 run_test 413h "don't stick to parent for round-robin dirs"
29238
29239 test_413i() {
29240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
29241
29242         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
29243                 skip "Need server version at least 2.14.55"
29244
29245         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
29246                 error "dump $DIR default LMV failed"
29247         stack_trap "setfattr --restore=$TMP/dmv.ea"
29248
29249         local testdir=$DIR/$tdir
29250         local def_max_rr=1
29251         local def_max=3
29252         local count
29253
29254         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
29255                 --max-inherit-rr=$def_max_rr $DIR ||
29256                 error "set $DIR default LMV failed"
29257
29258         for i in $(seq 2 3); do
29259                 def_max=$((def_max - 1))
29260                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
29261
29262                 mkdir $testdir
29263                 # RR is decremented and keeps zeroed once exhausted
29264                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
29265                 (( count == def_max_rr )) ||
29266                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
29267
29268                 # max-inherit is decremented
29269                 count=$($LFS getdirstripe -D --max-inherit $testdir)
29270                 (( count == def_max )) ||
29271                         error_noexit "$testdir: max-inherit $count != $def_max"
29272
29273                 testdir=$testdir/d$i
29274         done
29275
29276         # d3 is the last inherited from ROOT, no inheritance anymore
29277         # i.e. no the default layout anymore
29278         mkdir -p $testdir/d4/d5
29279         count=$($LFS getdirstripe -D --max-inherit $testdir)
29280         (( count == -1 )) ||
29281                 error_noexit "$testdir: max-inherit $count != -1"
29282
29283         local p_count=$($LFS getdirstripe -i $testdir)
29284
29285         for i in $(seq 4 5); do
29286                 testdir=$testdir/d$i
29287
29288                 # the root default layout is not applied once exhausted
29289                 count=$($LFS getdirstripe -i $testdir)
29290                 (( count == p_count )) ||
29291                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
29292         done
29293
29294         $LFS setdirstripe -i 0 $DIR/d2
29295         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
29296         (( count == -1 )) ||
29297                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
29298 }
29299 run_test 413i "check default layout inheritance"
29300
29301 test_413j()
29302 {
29303         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
29304
29305         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
29306         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
29307                 error "setdirstripe $tdir failed"
29308
29309         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
29310                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29311
29312         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
29313         # setfattr dmv calls setdirstripe -D
29314         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
29315                 error "setfattr sub failed"
29316         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
29317                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
29318
29319         [ $value == $value2 ] || error "dmv mismatch"
29320
29321         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
29322
29323         # do not allow remove dmv by setfattr -x
29324         do_nodes $(comma_list $(mdts_nodes)) \
29325                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29326         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29327         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
29328
29329         # allow remove dmv by setfattr -x
29330         do_nodes $(comma_list $(mdts_nodes)) \
29331                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
29332         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
29333         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
29334         do_nodes $(comma_list $(mdts_nodes)) \
29335                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
29336 }
29337 run_test 413j "set default LMV by setxattr"
29338
29339 test_413z() {
29340         local pids=""
29341         local subdir
29342         local pid
29343
29344         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
29345                 unlinkmany $subdir/f. $TEST413_COUNT &
29346                 pids="$pids $!"
29347         done
29348
29349         for pid in $pids; do
29350                 wait $pid
29351         done
29352
29353         true
29354 }
29355 run_test 413z "413 test cleanup"
29356
29357 test_414() {
29358 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
29359         $LCTL set_param fail_loc=0x80000521
29360         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29361         rm -f $DIR/$tfile
29362 }
29363 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
29364
29365 test_415() {
29366         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
29367         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
29368                 skip "Need server version at least 2.11.52"
29369
29370         # LU-11102
29371         local total=500
29372         local max=120
29373
29374         # this test may be slow on ZFS
29375         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
29376
29377         # though this test is designed for striped directory, let's test normal
29378         # directory too since lock is always saved as CoS lock.
29379         test_mkdir $DIR/$tdir || error "mkdir $tdir"
29380         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
29381         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
29382         # if looping with ONLY_REPEAT, wait for previous deletions to finish
29383         wait_delete_completed_mds
29384
29385         # run a loop without concurrent touch to measure rename duration.
29386         # only for test debug/robustness, NOT part of COS functional test.
29387         local start_time=$SECONDS
29388         for ((i = 0; i < total; i++)); do
29389                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
29390                         > /dev/null
29391         done
29392         local baseline=$((SECONDS - start_time))
29393         echo "rename $total files without 'touch' took $baseline sec"
29394
29395         (
29396                 while true; do
29397                         touch $DIR/$tdir
29398                 done
29399         ) &
29400         local setattr_pid=$!
29401
29402         # rename files back to original name so unlinkmany works
29403         start_time=$SECONDS
29404         for ((i = 0; i < total; i++)); do
29405                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
29406                         > /dev/null
29407         done
29408         local duration=$((SECONDS - start_time))
29409
29410         kill -9 $setattr_pid
29411
29412         echo "rename $total files with 'touch' took $duration sec"
29413         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
29414         (( duration <= max )) ||
29415                 error_not_in_vm "rename took $duration > $max sec"
29416 }
29417 run_test 415 "lock revoke is not missing"
29418
29419 test_416() {
29420         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29421                 skip "Need server version at least 2.11.55"
29422
29423         # define OBD_FAIL_OSD_TXN_START    0x19a
29424         do_facet mds1 lctl set_param fail_loc=0x19a
29425
29426         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29427
29428         true
29429 }
29430 run_test 416 "transaction start failure won't cause system hung"
29431
29432 cleanup_417() {
29433         trap 0
29434         do_nodes $(comma_list $(mdts_nodes)) \
29435                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29436         do_nodes $(comma_list $(mdts_nodes)) \
29437                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29438         do_nodes $(comma_list $(mdts_nodes)) \
29439                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29440 }
29441
29442 test_417() {
29443         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29444         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29445                 skip "Need MDS version at least 2.11.56"
29446
29447         trap cleanup_417 RETURN EXIT
29448
29449         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29450         do_nodes $(comma_list $(mdts_nodes)) \
29451                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29452         $LFS migrate -m 0 $DIR/$tdir.1 &&
29453                 error "migrate dir $tdir.1 should fail"
29454
29455         do_nodes $(comma_list $(mdts_nodes)) \
29456                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29457         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29458                 error "create remote dir $tdir.2 should fail"
29459
29460         do_nodes $(comma_list $(mdts_nodes)) \
29461                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29462         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29463                 error "create striped dir $tdir.3 should fail"
29464         true
29465 }
29466 run_test 417 "disable remote dir, striped dir and dir migration"
29467
29468 # Checks that the outputs of df [-i] and lfs df [-i] match
29469 #
29470 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29471 check_lfs_df() {
29472         local dir=$2
29473         local inodes
29474         local df_out
29475         local lfs_df_out
29476         local count
29477         local passed=false
29478
29479         # blocks or inodes
29480         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29481
29482         for count in {1..100}; do
29483                 do_nodes "$CLIENTS" \
29484                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29485                 sync; sleep 0.2
29486
29487                 # read the lines of interest
29488                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29489                         error "df $inodes $dir | tail -n +2 failed"
29490                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29491                         error "lfs df $inodes $dir | grep summary: failed"
29492
29493                 # skip first substrings of each output as they are different
29494                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29495                 # compare the two outputs
29496                 passed=true
29497                 #  skip "available" on MDT until LU-13997 is fixed.
29498                 #for i in {1..5}; do
29499                 for i in 1 2 4 5; do
29500                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29501                 done
29502                 $passed && break
29503         done
29504
29505         if ! $passed; then
29506                 df -P $inodes $dir
29507                 echo
29508                 lfs df $inodes $dir
29509                 error "df and lfs df $1 output mismatch: "      \
29510                       "df ${inodes}: ${df_out[*]}, "            \
29511                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29512         fi
29513 }
29514
29515 test_418() {
29516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29517
29518         local dir=$DIR/$tdir
29519         local numfiles=$((RANDOM % 4096 + 2))
29520         local numblocks=$((RANDOM % 256 + 1))
29521
29522         wait_delete_completed
29523         test_mkdir $dir
29524
29525         # check block output
29526         check_lfs_df blocks $dir
29527         # check inode output
29528         check_lfs_df inodes $dir
29529
29530         # create a single file and retest
29531         echo "Creating a single file and testing"
29532         createmany -o $dir/$tfile- 1 &>/dev/null ||
29533                 error "creating 1 file in $dir failed"
29534         check_lfs_df blocks $dir
29535         check_lfs_df inodes $dir
29536
29537         # create a random number of files
29538         echo "Creating $((numfiles - 1)) files and testing"
29539         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29540                 error "creating $((numfiles - 1)) files in $dir failed"
29541
29542         # write a random number of blocks to the first test file
29543         echo "Writing $numblocks 4K blocks and testing"
29544         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29545                 count=$numblocks &>/dev/null ||
29546                 error "dd to $dir/${tfile}-0 failed"
29547
29548         # retest
29549         check_lfs_df blocks $dir
29550         check_lfs_df inodes $dir
29551
29552         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29553                 error "unlinking $numfiles files in $dir failed"
29554 }
29555 run_test 418 "df and lfs df outputs match"
29556
29557 test_419()
29558 {
29559         local dir=$DIR/$tdir
29560
29561         mkdir -p $dir
29562         touch $dir/file
29563
29564         cancel_lru_locks mdc
29565
29566         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29567         $LCTL set_param fail_loc=0x1410
29568         cat $dir/file
29569         $LCTL set_param fail_loc=0
29570         rm -rf $dir
29571 }
29572 run_test 419 "Verify open file by name doesn't crash kernel"
29573
29574 test_420()
29575 {
29576         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29577                 skip "Need MDS version at least 2.12.53"
29578
29579         local SAVE_UMASK=$(umask)
29580         local dir=$DIR/$tdir
29581         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29582
29583         mkdir -p $dir
29584         umask 0000
29585         mkdir -m03777 $dir/testdir
29586         ls -dn $dir/testdir
29587         # Need to remove trailing '.' when SELinux is enabled
29588         local dirperms=$(ls -dn $dir/testdir |
29589                          awk '{ sub(/\.$/, "", $1); print $1}')
29590         [ $dirperms == "drwxrwsrwt" ] ||
29591                 error "incorrect perms on $dir/testdir"
29592
29593         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29594                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29595         ls -n $dir/testdir/testfile
29596         local fileperms=$(ls -n $dir/testdir/testfile |
29597                           awk '{ sub(/\.$/, "", $1); print $1}')
29598         [ $fileperms == "-rwxr-xr-x" ] ||
29599                 error "incorrect perms on $dir/testdir/testfile"
29600
29601         umask $SAVE_UMASK
29602 }
29603 run_test 420 "clear SGID bit on non-directories for non-members"
29604
29605 test_421a() {
29606         local cnt
29607         local fid1
29608         local fid2
29609
29610         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29611                 skip "Need MDS version at least 2.12.54"
29612
29613         test_mkdir $DIR/$tdir
29614         createmany -o $DIR/$tdir/f 3
29615         cnt=$(ls -1 $DIR/$tdir | wc -l)
29616         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29617
29618         fid1=$(lfs path2fid $DIR/$tdir/f1)
29619         fid2=$(lfs path2fid $DIR/$tdir/f2)
29620         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29621
29622         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29623         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29624
29625         cnt=$(ls -1 $DIR/$tdir | wc -l)
29626         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29627
29628         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29629         createmany -o $DIR/$tdir/f 3
29630         cnt=$(ls -1 $DIR/$tdir | wc -l)
29631         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29632
29633         fid1=$(lfs path2fid $DIR/$tdir/f1)
29634         fid2=$(lfs path2fid $DIR/$tdir/f2)
29635         echo "remove using fsname $FSNAME"
29636         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29637
29638         cnt=$(ls -1 $DIR/$tdir | wc -l)
29639         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29640 }
29641 run_test 421a "simple rm by fid"
29642
29643 test_421b() {
29644         local cnt
29645         local FID1
29646         local FID2
29647
29648         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29649                 skip "Need MDS version at least 2.12.54"
29650
29651         test_mkdir $DIR/$tdir
29652         createmany -o $DIR/$tdir/f 3
29653         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29654         MULTIPID=$!
29655
29656         FID1=$(lfs path2fid $DIR/$tdir/f1)
29657         FID2=$(lfs path2fid $DIR/$tdir/f2)
29658         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29659
29660         kill -USR1 $MULTIPID
29661         wait
29662
29663         cnt=$(ls $DIR/$tdir | wc -l)
29664         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29665 }
29666 run_test 421b "rm by fid on open file"
29667
29668 test_421c() {
29669         local cnt
29670         local FIDS
29671
29672         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29673                 skip "Need MDS version at least 2.12.54"
29674
29675         test_mkdir $DIR/$tdir
29676         createmany -o $DIR/$tdir/f 3
29677         touch $DIR/$tdir/$tfile
29678         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29679         cnt=$(ls -1 $DIR/$tdir | wc -l)
29680         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29681
29682         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29683         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29684
29685         cnt=$(ls $DIR/$tdir | wc -l)
29686         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29687 }
29688 run_test 421c "rm by fid against hardlinked files"
29689
29690 test_421d() {
29691         local cnt
29692         local FIDS
29693
29694         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29695                 skip "Need MDS version at least 2.12.54"
29696
29697         test_mkdir $DIR/$tdir
29698         createmany -o $DIR/$tdir/f 4097
29699         cnt=$(ls -1 $DIR/$tdir | wc -l)
29700         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29701
29702         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29703         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29704
29705         cnt=$(ls $DIR/$tdir | wc -l)
29706         rm -rf $DIR/$tdir
29707         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29708 }
29709 run_test 421d "rmfid en masse"
29710
29711 test_421e() {
29712         local cnt
29713         local FID
29714
29715         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29716         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29717                 skip "Need MDS version at least 2.12.54"
29718
29719         mkdir -p $DIR/$tdir
29720         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29721         createmany -o $DIR/$tdir/striped_dir/f 512
29722         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29723         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29724
29725         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29726                 sed "s/[/][^:]*://g")
29727         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29728
29729         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29730         rm -rf $DIR/$tdir
29731         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29732 }
29733 run_test 421e "rmfid in DNE"
29734
29735 test_421f() {
29736         local cnt
29737         local FID
29738
29739         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29740                 skip "Need MDS version at least 2.12.54"
29741
29742         test_mkdir $DIR/$tdir
29743         touch $DIR/$tdir/f
29744         cnt=$(ls -1 $DIR/$tdir | wc -l)
29745         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29746
29747         FID=$(lfs path2fid $DIR/$tdir/f)
29748         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29749         # rmfid should fail
29750         cnt=$(ls -1 $DIR/$tdir | wc -l)
29751         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29752
29753         chmod a+rw $DIR/$tdir
29754         ls -la $DIR/$tdir
29755         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29756         # rmfid should fail
29757         cnt=$(ls -1 $DIR/$tdir | wc -l)
29758         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29759
29760         rm -f $DIR/$tdir/f
29761         $RUNAS touch $DIR/$tdir/f
29762         FID=$(lfs path2fid $DIR/$tdir/f)
29763         echo "rmfid as root"
29764         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29765         cnt=$(ls -1 $DIR/$tdir | wc -l)
29766         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29767
29768         rm -f $DIR/$tdir/f
29769         $RUNAS touch $DIR/$tdir/f
29770         cnt=$(ls -1 $DIR/$tdir | wc -l)
29771         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29772         FID=$(lfs path2fid $DIR/$tdir/f)
29773         # rmfid w/o user_fid2path mount option should fail
29774         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29775         cnt=$(ls -1 $DIR/$tdir | wc -l)
29776         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29777
29778         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29779         stack_trap "rmdir $tmpdir"
29780         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29781                 error "failed to mount client'"
29782         stack_trap "umount_client $tmpdir"
29783
29784         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29785         # rmfid should succeed
29786         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29787         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29788
29789         # rmfid shouldn't allow to remove files due to dir's permission
29790         chmod a+rwx $tmpdir/$tdir
29791         touch $tmpdir/$tdir/f
29792         ls -la $tmpdir/$tdir
29793         FID=$(lfs path2fid $tmpdir/$tdir/f)
29794         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29795         return 0
29796 }
29797 run_test 421f "rmfid checks permissions"
29798
29799 test_421g() {
29800         local cnt
29801         local FIDS
29802
29803         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29804         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29805                 skip "Need MDS version at least 2.12.54"
29806
29807         mkdir -p $DIR/$tdir
29808         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29809         createmany -o $DIR/$tdir/striped_dir/f 512
29810         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29811         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29812
29813         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29814                 sed "s/[/][^:]*://g")
29815
29816         rm -f $DIR/$tdir/striped_dir/f1*
29817         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29818         removed=$((512 - cnt))
29819
29820         # few files have been just removed, so we expect
29821         # rmfid to fail on their fids
29822         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29823         [ $removed != $errors ] && error "$errors != $removed"
29824
29825         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29826         rm -rf $DIR/$tdir
29827         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29828 }
29829 run_test 421g "rmfid to return errors properly"
29830
29831 test_421h() {
29832         local mount_other
29833         local mount_ret
29834         local rmfid_ret
29835         local old_fid
29836         local fidA
29837         local fidB
29838         local fidC
29839         local fidD
29840
29841         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29842                 skip "Need MDS version at least 2.15.53"
29843
29844         test_mkdir $DIR/$tdir
29845         test_mkdir $DIR/$tdir/subdir
29846         touch $DIR/$tdir/subdir/file0
29847         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29848         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29849         rm -f $DIR/$tdir/subdir/file0
29850         touch $DIR/$tdir/subdir/fileA
29851         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29852         echo File $DIR/$tdir/subdir/fileA FID $fidA
29853         touch $DIR/$tdir/subdir/fileB
29854         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29855         echo File $DIR/$tdir/subdir/fileB FID $fidB
29856         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29857         touch $DIR/$tdir/subdir/fileC
29858         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29859         echo File $DIR/$tdir/subdir/fileC FID $fidC
29860         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29861         touch $DIR/$tdir/fileD
29862         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29863         echo File $DIR/$tdir/fileD FID $fidD
29864
29865         # mount another client mount point with subdirectory mount
29866         export FILESET=/$tdir/subdir
29867         mount_other=${MOUNT}_other
29868         mount_client $mount_other ${MOUNT_OPTS}
29869         mount_ret=$?
29870         export FILESET=""
29871         (( mount_ret == 0 )) || error "mount $mount_other failed"
29872
29873         echo Removing FIDs:
29874         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29875         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29876         rmfid_ret=$?
29877
29878         umount_client $mount_other || error "umount $mount_other failed"
29879
29880         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29881
29882         # fileA should have been deleted
29883         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29884
29885         # fileB should have been deleted
29886         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29887
29888         # fileC should not have been deleted, fid also exists outside of fileset
29889         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29890
29891         # fileD should not have been deleted, it exists outside of fileset
29892         stat $DIR/$tdir/fileD || error "fileD deleted"
29893 }
29894 run_test 421h "rmfid with fileset mount"
29895
29896 test_422() {
29897         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29898         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29899         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29900         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29901         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29902
29903         local amc=$(at_max_get client)
29904         local amo=$(at_max_get mds1)
29905         local timeout=`lctl get_param -n timeout`
29906
29907         at_max_set 0 client
29908         at_max_set 0 mds1
29909
29910 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29911         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29912                         fail_val=$(((2*timeout + 10)*1000))
29913         touch $DIR/$tdir/d3/file &
29914         sleep 2
29915 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29916         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29917                         fail_val=$((2*timeout + 5))
29918         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29919         local pid=$!
29920         sleep 1
29921         kill -9 $pid
29922         sleep $((2 * timeout))
29923         echo kill $pid
29924         kill -9 $pid
29925         lctl mark touch
29926         touch $DIR/$tdir/d2/file3
29927         touch $DIR/$tdir/d2/file4
29928         touch $DIR/$tdir/d2/file5
29929
29930         wait
29931         at_max_set $amc client
29932         at_max_set $amo mds1
29933
29934         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29935         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29936                 error "Watchdog is always throttled"
29937 }
29938 run_test 422 "kill a process with RPC in progress"
29939
29940 stat_test() {
29941     df -h $MOUNT &
29942     df -h $MOUNT &
29943     df -h $MOUNT &
29944     df -h $MOUNT &
29945     df -h $MOUNT &
29946     df -h $MOUNT &
29947 }
29948
29949 test_423() {
29950     local _stats
29951     # ensure statfs cache is expired
29952     sleep 2;
29953
29954     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29955     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29956
29957     return 0
29958 }
29959 run_test 423 "statfs should return a right data"
29960
29961 test_424() {
29962 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29963         $LCTL set_param fail_loc=0x80000522
29964         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29965         rm -f $DIR/$tfile
29966 }
29967 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29968
29969 test_425() {
29970         test_mkdir -c -1 $DIR/$tdir
29971         $LFS setstripe -c -1 $DIR/$tdir
29972
29973         lru_resize_disable "" 100
29974         stack_trap "lru_resize_enable" EXIT
29975
29976         sleep 5
29977
29978         for i in $(seq $((MDSCOUNT * 125))); do
29979                 local t=$DIR/$tdir/$tfile_$i
29980
29981                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29982                         error_noexit "Create file $t"
29983         done
29984         stack_trap "rm -rf $DIR/$tdir" EXIT
29985
29986         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29987                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29988                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29989
29990                 [ $lock_count -le $lru_size ] ||
29991                         error "osc lock count $lock_count > lru size $lru_size"
29992         done
29993
29994         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29995                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29996                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29997
29998                 [ $lock_count -le $lru_size ] ||
29999                         error "mdc lock count $lock_count > lru size $lru_size"
30000         done
30001 }
30002 run_test 425 "lock count should not exceed lru size"
30003
30004 test_426() {
30005         splice-test -r $DIR/$tfile
30006         splice-test -rd $DIR/$tfile
30007         splice-test $DIR/$tfile
30008         splice-test -d $DIR/$tfile
30009 }
30010 run_test 426 "splice test on Lustre"
30011
30012 test_427() {
30013         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
30014         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
30015                 skip "Need MDS version at least 2.12.4"
30016         local log
30017
30018         mkdir $DIR/$tdir
30019         mkdir $DIR/$tdir/1
30020         mkdir $DIR/$tdir/2
30021         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
30022         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
30023
30024         $LFS getdirstripe $DIR/$tdir/1/dir
30025
30026         #first setfattr for creating updatelog
30027         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
30028
30029 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
30030         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
30031         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
30032         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
30033
30034         sleep 2
30035         fail mds2
30036         wait_recovery_complete mds2 $((2*TIMEOUT))
30037
30038         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
30039         echo $log | grep "get update log failed" &&
30040                 error "update log corruption is detected" || true
30041 }
30042 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
30043
30044 test_428() {
30045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30046         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
30047                               awk '/^max_cached_mb/ { print $2 }')
30048         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
30049
30050         $LCTL set_param -n llite.*.max_cached_mb=64
30051
30052         mkdir $DIR/$tdir
30053         $LFS setstripe -c 1 $DIR/$tdir
30054         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
30055         stack_trap "rm -f $DIR/$tdir/$tfile.*"
30056         #test write
30057         for f in $(seq 4); do
30058                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
30059         done
30060         wait
30061
30062         cancel_lru_locks osc
30063         # Test read
30064         for f in $(seq 4); do
30065                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
30066         done
30067         wait
30068 }
30069 run_test 428 "large block size IO should not hang"
30070
30071 test_429() { # LU-7915 / LU-10948
30072         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
30073         local testfile=$DIR/$tfile
30074         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
30075         local new_flag=1
30076         local first_rpc
30077         local second_rpc
30078         local third_rpc
30079
30080         $LCTL get_param $ll_opencache_threshold_count ||
30081                 skip "client does not have opencache parameter"
30082
30083         set_opencache $new_flag
30084         stack_trap "restore_opencache"
30085         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
30086                 error "enable opencache failed"
30087         touch $testfile
30088         # drop MDC DLM locks
30089         cancel_lru_locks mdc
30090         # clear MDC RPC stats counters
30091         $LCTL set_param $mdc_rpcstats=clear
30092
30093         # According to the current implementation, we need to run 3 times
30094         # open & close file to verify if opencache is enabled correctly.
30095         # 1st, RPCs are sent for lookup/open and open handle is released on
30096         #      close finally.
30097         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
30098         #      so open handle won't be released thereafter.
30099         # 3rd, No RPC is sent out.
30100         $MULTIOP $testfile oc || error "multiop failed"
30101         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30102         echo "1st: $first_rpc RPCs in flight"
30103
30104         $MULTIOP $testfile oc || error "multiop failed"
30105         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30106         echo "2nd: $second_rpc RPCs in flight"
30107
30108         $MULTIOP $testfile oc || error "multiop failed"
30109         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
30110         echo "3rd: $third_rpc RPCs in flight"
30111
30112         #verify no MDC RPC is sent
30113         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
30114 }
30115 run_test 429 "verify if opencache flag on client side does work"
30116
30117 lseek_test_430() {
30118         local offset
30119         local file=$1
30120
30121         # data at [200K, 400K)
30122         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
30123                 error "256K->512K dd fails"
30124         # data at [2M, 3M)
30125         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
30126                 error "2M->3M dd fails"
30127         # data at [4M, 5M)
30128         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
30129                 error "4M->5M dd fails"
30130         echo "Data at 256K...512K, 2M...3M and 4M...5M"
30131         # start at first component hole #1
30132         printf "Seeking hole from 1000 ... "
30133         offset=$(lseek_test -l 1000 $file)
30134         echo $offset
30135         [[ $offset == 1000 ]] || error "offset $offset != 1000"
30136         printf "Seeking data from 1000 ... "
30137         offset=$(lseek_test -d 1000 $file)
30138         echo $offset
30139         [[ $offset == 262144 ]] || error "offset $offset != 262144"
30140
30141         # start at first component data block
30142         printf "Seeking hole from 300000 ... "
30143         offset=$(lseek_test -l 300000 $file)
30144         echo $offset
30145         [[ $offset == 524288 ]] || error "offset $offset != 524288"
30146         printf "Seeking data from 300000 ... "
30147         offset=$(lseek_test -d 300000 $file)
30148         echo $offset
30149         [[ $offset == 300000 ]] || error "offset $offset != 300000"
30150
30151         # start at the first component but beyond end of object size
30152         printf "Seeking hole from 1000000 ... "
30153         offset=$(lseek_test -l 1000000 $file)
30154         echo $offset
30155         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30156         printf "Seeking data from 1000000 ... "
30157         offset=$(lseek_test -d 1000000 $file)
30158         echo $offset
30159         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30160
30161         # start at second component stripe 2 (empty file)
30162         printf "Seeking hole from 1500000 ... "
30163         offset=$(lseek_test -l 1500000 $file)
30164         echo $offset
30165         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
30166         printf "Seeking data from 1500000 ... "
30167         offset=$(lseek_test -d 1500000 $file)
30168         echo $offset
30169         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
30170
30171         # start at second component stripe 1 (all data)
30172         printf "Seeking hole from 3000000 ... "
30173         offset=$(lseek_test -l 3000000 $file)
30174         echo $offset
30175         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
30176         printf "Seeking data from 3000000 ... "
30177         offset=$(lseek_test -d 3000000 $file)
30178         echo $offset
30179         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
30180
30181         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
30182                 error "2nd dd fails"
30183         echo "Add data block at 640K...1280K"
30184
30185         # start at before new data block, in hole
30186         printf "Seeking hole from 600000 ... "
30187         offset=$(lseek_test -l 600000 $file)
30188         echo $offset
30189         [[ $offset == 600000 ]] || error "offset $offset != 600000"
30190         printf "Seeking data from 600000 ... "
30191         offset=$(lseek_test -d 600000 $file)
30192         echo $offset
30193         [[ $offset == 655360 ]] || error "offset $offset != 655360"
30194
30195         # start at the first component new data block
30196         printf "Seeking hole from 1000000 ... "
30197         offset=$(lseek_test -l 1000000 $file)
30198         echo $offset
30199         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30200         printf "Seeking data from 1000000 ... "
30201         offset=$(lseek_test -d 1000000 $file)
30202         echo $offset
30203         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30204
30205         # start at second component stripe 2, new data
30206         printf "Seeking hole from 1200000 ... "
30207         offset=$(lseek_test -l 1200000 $file)
30208         echo $offset
30209         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
30210         printf "Seeking data from 1200000 ... "
30211         offset=$(lseek_test -d 1200000 $file)
30212         echo $offset
30213         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
30214
30215         # start beyond file end
30216         printf "Using offset > filesize ... "
30217         lseek_test -l 4000000 $file && error "lseek should fail"
30218         printf "Using offset > filesize ... "
30219         lseek_test -d 4000000 $file && error "lseek should fail"
30220
30221         printf "Done\n\n"
30222 }
30223
30224 test_430a() {
30225         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
30226                 skip "MDT does not support SEEK_HOLE"
30227
30228         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30229                 skip "OST does not support SEEK_HOLE"
30230
30231         local file=$DIR/$tdir/$tfile
30232
30233         mkdir -p $DIR/$tdir
30234
30235         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
30236         # OST stripe #1 will have continuous data at [1M, 3M)
30237         # OST stripe #2 is empty
30238         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
30239         lseek_test_430 $file
30240         rm $file
30241         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
30242         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
30243         lseek_test_430 $file
30244         rm $file
30245         $LFS setstripe -c2 -S 512K $file
30246         echo "Two stripes, stripe size 512K"
30247         lseek_test_430 $file
30248         rm $file
30249         # FLR with stale mirror
30250         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
30251                        -N -c2 -S 1M $file
30252         echo "Mirrored file:"
30253         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
30254         echo "Plain 2 stripes 1M"
30255         lseek_test_430 $file
30256         rm $file
30257 }
30258 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
30259
30260 test_430b() {
30261         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30262                 skip "OST does not support SEEK_HOLE"
30263
30264         local offset
30265         local file=$DIR/$tdir/$tfile
30266
30267         mkdir -p $DIR/$tdir
30268         # Empty layout lseek should fail
30269         $MCREATE $file
30270         # seek from 0
30271         printf "Seeking hole from 0 ... "
30272         lseek_test -l 0 $file && error "lseek should fail"
30273         printf "Seeking data from 0 ... "
30274         lseek_test -d 0 $file && error "lseek should fail"
30275         rm $file
30276
30277         # 1M-hole file
30278         $LFS setstripe -E 1M -c2 -E eof $file
30279         $TRUNCATE $file 1048576
30280         printf "Seeking hole from 1000000 ... "
30281         offset=$(lseek_test -l 1000000 $file)
30282         echo $offset
30283         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
30284         printf "Seeking data from 1000000 ... "
30285         lseek_test -d 1000000 $file && error "lseek should fail"
30286         rm $file
30287
30288         # full component followed by non-inited one
30289         $LFS setstripe -E 1M -c2 -E eof $file
30290         dd if=/dev/urandom of=$file bs=1M count=1
30291         printf "Seeking hole from 1000000 ... "
30292         offset=$(lseek_test -l 1000000 $file)
30293         echo $offset
30294         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30295         printf "Seeking hole from 1048576 ... "
30296         lseek_test -l 1048576 $file && error "lseek should fail"
30297         # init second component and truncate back
30298         echo "123" >> $file
30299         $TRUNCATE $file 1048576
30300         printf "Seeking hole from 1000000 ... "
30301         offset=$(lseek_test -l 1000000 $file)
30302         echo $offset
30303         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
30304         printf "Seeking hole from 1048576 ... "
30305         lseek_test -l 1048576 $file && error "lseek should fail"
30306         # boundary checks for big values
30307         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
30308         offset=$(lseek_test -d 0 $file.10g)
30309         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
30310         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
30311         offset=$(lseek_test -d 0 $file.100g)
30312         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
30313         return 0
30314 }
30315 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
30316
30317 test_430c() {
30318         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
30319                 skip "OST does not support SEEK_HOLE"
30320
30321         local file=$DIR/$tdir/$tfile
30322         local start
30323
30324         mkdir -p $DIR/$tdir
30325         stack_trap "rm -f $file $file.tmp"
30326         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
30327
30328         # cp version 8.33+ prefers lseek over fiemap
30329         local ver=$(cp --version | awk '{ print $4; exit; }')
30330
30331         echo "cp $ver installed"
30332         if (( $(version_code $ver) >= $(version_code 8.33) )); then
30333                 start=$SECONDS
30334                 time cp -v $file $file.tmp || error "cp $file failed"
30335                 (( SECONDS - start < 5 )) || {
30336                         strace cp $file $file.tmp |&
30337                                 grep -E "open|read|seek|FIEMAP" |
30338                                 grep -A 100 $file
30339                         error "cp: too long runtime $((SECONDS - start))"
30340                 }
30341         else
30342                 echo "cp test skipped due to $ver < 8.33"
30343         fi
30344
30345         # tar version 1.29+ supports SEEK_HOLE/DATA
30346         ver=$(tar --version | awk '{ print $4; exit; }')
30347         echo "tar $ver installed"
30348         if (( $(version_code $ver) >= $(version_code 1.29) )); then
30349                 start=$SECONDS
30350                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
30351                 (( SECONDS - start < 5 )) || {
30352                         strace tar cf $file.tmp --sparse $file |&
30353                                 grep -E "open|read|seek|FIEMAP" |
30354                                 grep -A 100 $file
30355                         error "tar: too long runtime $((SECONDS - start))"
30356                 }
30357         else
30358                 echo "tar test skipped due to $ver < 1.29"
30359         fi
30360 }
30361 run_test 430c "lseek: external tools check"
30362
30363 test_431() { # LU-14187
30364         local file=$DIR/$tdir/$tfile
30365
30366         mkdir -p $DIR/$tdir
30367         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
30368         dd if=/dev/urandom of=$file bs=4k count=1
30369         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
30370         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
30371         #define OBD_FAIL_OST_RESTART_IO 0x251
30372         do_facet ost1 "$LCTL set_param fail_loc=0x251"
30373         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
30374         cp $file $file.0
30375         cancel_lru_locks
30376         sync_all_data
30377         echo 3 > /proc/sys/vm/drop_caches
30378         diff  $file $file.0 || error "data diff"
30379 }
30380 run_test 431 "Restart transaction for IO"
30381
30382 cleanup_test_432() {
30383         do_facet mgs $LCTL nodemap_activate 0
30384         wait_nm_sync active
30385 }
30386
30387 test_432() {
30388         local tmpdir=$TMP/dir432
30389
30390         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
30391                 skip "Need MDS version at least 2.14.52"
30392
30393         stack_trap cleanup_test_432 EXIT
30394         mkdir $DIR/$tdir
30395         mkdir $tmpdir
30396
30397         do_facet mgs $LCTL nodemap_activate 1
30398         wait_nm_sync active
30399         do_facet mgs $LCTL nodemap_modify --name default \
30400                 --property admin --value 1
30401         do_facet mgs $LCTL nodemap_modify --name default \
30402                 --property trusted --value 1
30403         cancel_lru_locks mdc
30404         wait_nm_sync default admin_nodemap
30405         wait_nm_sync default trusted_nodemap
30406
30407         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
30408                grep -ci "Operation not permitted") -ne 0 ]; then
30409                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
30410         fi
30411 }
30412 run_test 432 "mv dir from outside Lustre"
30413
30414 test_433() {
30415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30416
30417         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
30418                 skip "inode cache not supported"
30419
30420         $LCTL set_param llite.*.inode_cache=0
30421         stack_trap "$LCTL set_param llite.*.inode_cache=1"
30422
30423         local count=256
30424         local before
30425         local after
30426
30427         cancel_lru_locks mdc
30428         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30429         createmany -m $DIR/$tdir/f $count
30430         createmany -d $DIR/$tdir/d $count
30431         ls -l $DIR/$tdir > /dev/null
30432         stack_trap "rm -rf $DIR/$tdir"
30433
30434         before=$(num_objects)
30435         cancel_lru_locks mdc
30436         after=$(num_objects)
30437
30438         # sometimes even @before is less than 2 * count
30439         while (( before - after < count )); do
30440                 sleep 1
30441                 after=$(num_objects)
30442                 wait=$((wait + 1))
30443                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30444                 if (( wait > 60 )); then
30445                         error "inode slab grew from $before to $after"
30446                 fi
30447         done
30448
30449         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30450 }
30451 run_test 433 "ldlm lock cancel releases dentries and inodes"
30452
30453 test_434() {
30454         local file
30455         local getxattr_count
30456         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30457         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30458
30459         [[ $(getenforce) == "Disabled" ]] ||
30460                 skip "lsm selinux module have to be disabled for this test"
30461
30462         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30463                 error "fail to create $DIR/$tdir/ on MDT0000"
30464
30465         touch $DIR/$tdir/$tfile-{001..100}
30466
30467         # disable the xattr cache
30468         save_lustre_params client "llite.*.xattr_cache" > $p
30469         lctl set_param llite.*.xattr_cache=0
30470         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30471
30472         # clear clients mdc stats
30473         clear_stats $mdc_stat_param ||
30474                 error "fail to clear stats on mdc MDT0000"
30475
30476         for file in $DIR/$tdir/$tfile-{001..100}; do
30477                 getfattr -n security.selinux $file |&
30478                         grep -q "Operation not supported" ||
30479                         error "getxattr on security.selinux should return EOPNOTSUPP"
30480         done
30481
30482         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30483         (( getxattr_count < 100 )) ||
30484                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30485 }
30486 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30487
30488 test_440() {
30489         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30490                 source $LUSTRE/scripts/bash-completion/lustre
30491         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30492                 source /usr/share/bash-completion/completions/lustre
30493         else
30494                 skip "bash completion scripts not found"
30495         fi
30496
30497         local lctl_completions
30498         local lfs_completions
30499
30500         lctl_completions=$(_lustre_cmds lctl)
30501         if [[ ! $lctl_completions =~ "get_param" ]]; then
30502                 error "lctl bash completion failed"
30503         fi
30504
30505         lfs_completions=$(_lustre_cmds lfs)
30506         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30507                 error "lfs bash completion failed"
30508         fi
30509 }
30510 run_test 440 "bash completion for lfs, lctl"
30511
30512 test_442() {
30513         local pid1
30514         local pid2
30515         mkdir -p $DIR/$tdir
30516         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30517         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30518         sleep 1
30519         touch $DIR/$tdir/$tfile.2
30520         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30521         $LCTL set_param fail_loc=0x1430
30522         kill -USR1 $pid1
30523         sleep 1
30524         kill -USR1 $pid2
30525         wait
30526 }
30527 run_test 442 "truncate vs read/write should not panic"
30528
30529 test_460d() {
30530         verify_yaml_available || skip_env "YAML verification not installed"
30531         $LCTL get_param -n sptlrpc.page_pools
30532         $LCTL get_param -n sptlrpc.page_pools | verify_yaml ||
30533                 error "The output of encrypt_page_pools is not an valid YAML"
30534 }
30535 run_test 460d "Check encrypt pools output"
30536
30537 prep_801() {
30538         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30539         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30540                 skip "Need server version at least 2.9.55"
30541
30542         start_full_debug_logging
30543 }
30544
30545 post_801() {
30546         stop_full_debug_logging
30547 }
30548
30549 barrier_stat() {
30550         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30551                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30552                            awk '/The barrier for/ { print $7 }')
30553                 echo $st
30554         else
30555                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30556                 echo \'$st\'
30557         fi
30558 }
30559
30560 barrier_expired() {
30561         local expired
30562
30563         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30564                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30565                           awk '/will be expired/ { print $7 }')
30566         else
30567                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30568         fi
30569
30570         echo $expired
30571 }
30572
30573 test_801a() {
30574         prep_801
30575
30576         echo "Start barrier_freeze at: $(date)"
30577         #define OBD_FAIL_BARRIER_DELAY          0x2202
30578         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30579         # Do not reduce barrier time - See LU-11873
30580         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30581
30582         sleep 2
30583         local b_status=$(barrier_stat)
30584         echo "Got barrier status at: $(date)"
30585         [ "$b_status" = "'freezing_p1'" ] ||
30586                 error "(1) unexpected barrier status $b_status"
30587
30588         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30589         wait
30590         b_status=$(barrier_stat)
30591         [ "$b_status" = "'frozen'" ] ||
30592                 error "(2) unexpected barrier status $b_status"
30593
30594         local expired=$(barrier_expired)
30595         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30596         sleep $((expired + 3))
30597
30598         b_status=$(barrier_stat)
30599         [ "$b_status" = "'expired'" ] ||
30600                 error "(3) unexpected barrier status $b_status"
30601
30602         # Do not reduce barrier time - See LU-11873
30603         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30604                 error "(4) fail to freeze barrier"
30605
30606         b_status=$(barrier_stat)
30607         [ "$b_status" = "'frozen'" ] ||
30608                 error "(5) unexpected barrier status $b_status"
30609
30610         echo "Start barrier_thaw at: $(date)"
30611         #define OBD_FAIL_BARRIER_DELAY          0x2202
30612         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30613         do_facet mgs $LCTL barrier_thaw $FSNAME &
30614
30615         sleep 2
30616         b_status=$(barrier_stat)
30617         echo "Got barrier status at: $(date)"
30618         [ "$b_status" = "'thawing'" ] ||
30619                 error "(6) unexpected barrier status $b_status"
30620
30621         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30622         wait
30623         b_status=$(barrier_stat)
30624         [ "$b_status" = "'thawed'" ] ||
30625                 error "(7) unexpected barrier status $b_status"
30626
30627         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30628         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30629         do_facet mgs $LCTL barrier_freeze $FSNAME
30630
30631         b_status=$(barrier_stat)
30632         [ "$b_status" = "'failed'" ] ||
30633                 error "(8) unexpected barrier status $b_status"
30634
30635         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30636         do_facet mgs $LCTL barrier_thaw $FSNAME
30637
30638         post_801
30639 }
30640 run_test 801a "write barrier user interfaces and stat machine"
30641
30642 test_801b() {
30643         prep_801
30644
30645         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30646         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30647         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30648         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30649         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30650
30651         cancel_lru_locks mdc
30652
30653         # 180 seconds should be long enough
30654         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30655
30656         local b_status=$(barrier_stat)
30657         [ "$b_status" = "'frozen'" ] ||
30658                 error "(6) unexpected barrier status $b_status"
30659
30660         mkdir $DIR/$tdir/d0/d10 &
30661         mkdir_pid=$!
30662
30663         touch $DIR/$tdir/d1/f13 &
30664         touch_pid=$!
30665
30666         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30667         ln_pid=$!
30668
30669         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30670         mv_pid=$!
30671
30672         rm -f $DIR/$tdir/d4/f12 &
30673         rm_pid=$!
30674
30675         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30676
30677         # To guarantee taht the 'stat' is not blocked
30678         b_status=$(barrier_stat)
30679         [ "$b_status" = "'frozen'" ] ||
30680                 error "(8) unexpected barrier status $b_status"
30681
30682         # let above commands to run at background
30683         sleep 5
30684
30685         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30686         ps -p $touch_pid || error "(10) touch should be blocked"
30687         ps -p $ln_pid || error "(11) link should be blocked"
30688         ps -p $mv_pid || error "(12) rename should be blocked"
30689         ps -p $rm_pid || error "(13) unlink should be blocked"
30690
30691         b_status=$(barrier_stat)
30692         [ "$b_status" = "'frozen'" ] ||
30693                 error "(14) unexpected barrier status $b_status"
30694
30695         do_facet mgs $LCTL barrier_thaw $FSNAME
30696         b_status=$(barrier_stat)
30697         [ "$b_status" = "'thawed'" ] ||
30698                 error "(15) unexpected barrier status $b_status"
30699
30700         wait $mkdir_pid || error "(16) mkdir should succeed"
30701         wait $touch_pid || error "(17) touch should succeed"
30702         wait $ln_pid || error "(18) link should succeed"
30703         wait $mv_pid || error "(19) rename should succeed"
30704         wait $rm_pid || error "(20) unlink should succeed"
30705
30706         post_801
30707 }
30708 run_test 801b "modification will be blocked by write barrier"
30709
30710 test_801c() {
30711         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30712
30713         prep_801
30714
30715         stop mds2 || error "(1) Fail to stop mds2"
30716
30717         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30718
30719         local b_status=$(barrier_stat)
30720         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30721                 do_facet mgs $LCTL barrier_thaw $FSNAME
30722                 error "(2) unexpected barrier status $b_status"
30723         }
30724
30725         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30726                 error "(3) Fail to rescan barrier bitmap"
30727
30728         # Do not reduce barrier time - See LU-11873
30729         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30730
30731         b_status=$(barrier_stat)
30732         [ "$b_status" = "'frozen'" ] ||
30733                 error "(4) unexpected barrier status $b_status"
30734
30735         do_facet mgs $LCTL barrier_thaw $FSNAME
30736         b_status=$(barrier_stat)
30737         [ "$b_status" = "'thawed'" ] ||
30738                 error "(5) unexpected barrier status $b_status"
30739
30740         local devname=$(mdsdevname 2)
30741
30742         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30743
30744         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30745                 error "(7) Fail to rescan barrier bitmap"
30746
30747         post_801
30748 }
30749 run_test 801c "rescan barrier bitmap"
30750
30751 test_802b() {
30752         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30753         remote_mds_nodsh && skip "remote MDS with nodsh"
30754
30755         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30756                 skip "readonly option not available"
30757
30758         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30759
30760         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30761                 error "(2) Fail to copy"
30762
30763         # write back all cached data before setting MDT to readonly
30764         cancel_lru_locks
30765         sync_all_data
30766
30767         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30768         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30769
30770         echo "Modify should be refused"
30771         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30772
30773         echo "Read should be allowed"
30774         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30775                 error "(7) Read should succeed under ro mode"
30776
30777         # disable readonly
30778         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30779 }
30780 run_test 802b "be able to set MDTs to readonly"
30781
30782 test_803a() {
30783         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30784         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30785                 skip "MDS needs to be newer than 2.10.54"
30786
30787         mkdir_on_mdt0 $DIR/$tdir
30788         # Create some objects on all MDTs to trigger related logs objects
30789         for idx in $(seq $MDSCOUNT); do
30790                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30791                         $DIR/$tdir/dir${idx} ||
30792                         error "Fail to create $DIR/$tdir/dir${idx}"
30793         done
30794
30795         wait_delete_completed # ensure old test cleanups are finished
30796         sleep 3
30797         echo "before create:"
30798         $LFS df -i $MOUNT
30799         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30800
30801         for i in {1..10}; do
30802                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30803                         error "Fail to create $DIR/$tdir/foo$i"
30804         done
30805
30806         # sync ZFS-on-MDS to refresh statfs data
30807         wait_zfs_commit mds1
30808         sleep 3
30809         echo "after create:"
30810         $LFS df -i $MOUNT
30811         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30812
30813         # allow for an llog to be cleaned up during the test
30814         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30815                 error "before ($before_used) + 10 > after ($after_used)"
30816
30817         for i in {1..10}; do
30818                 rm -rf $DIR/$tdir/foo$i ||
30819                         error "Fail to remove $DIR/$tdir/foo$i"
30820         done
30821
30822         # sync ZFS-on-MDS to refresh statfs data
30823         wait_zfs_commit mds1
30824         wait_delete_completed
30825         sleep 3 # avoid MDT return cached statfs
30826         echo "after unlink:"
30827         $LFS df -i $MOUNT
30828         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30829
30830         # allow for an llog to be created during the test
30831         [ $after_used -le $((before_used + 1)) ] ||
30832                 error "after ($after_used) > before ($before_used) + 1"
30833 }
30834 run_test 803a "verify agent object for remote object"
30835
30836 test_803b() {
30837         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30838         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30839                 skip "MDS needs to be newer than 2.13.56"
30840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30841
30842         for i in $(seq 0 $((MDSCOUNT - 1))); do
30843                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30844         done
30845
30846         local before=0
30847         local after=0
30848
30849         local tmp
30850
30851         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30852         for i in $(seq 0 $((MDSCOUNT - 1))); do
30853                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30854                         awk '/getattr/ { print $2 }')
30855                 before=$((before + tmp))
30856         done
30857         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30858         for i in $(seq 0 $((MDSCOUNT - 1))); do
30859                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30860                         awk '/getattr/ { print $2 }')
30861                 after=$((after + tmp))
30862         done
30863
30864         [ $before -eq $after ] || error "getattr count $before != $after"
30865 }
30866 run_test 803b "remote object can getattr from cache"
30867
30868 test_804() {
30869         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30870         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30871                 skip "MDS needs to be newer than 2.10.54"
30872         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30873
30874         mkdir -p $DIR/$tdir
30875         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30876                 error "Fail to create $DIR/$tdir/dir0"
30877
30878         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30879         local dev=$(mdsdevname 2)
30880
30881         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30882                 grep ${fid} || error "NOT found agent entry for dir0"
30883
30884         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30885                 error "Fail to create $DIR/$tdir/dir1"
30886
30887         touch $DIR/$tdir/dir1/foo0 ||
30888                 error "Fail to create $DIR/$tdir/dir1/foo0"
30889         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30890         local rc=0
30891
30892         for idx in $(seq $MDSCOUNT); do
30893                 dev=$(mdsdevname $idx)
30894                 do_facet mds${idx} \
30895                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30896                         grep ${fid} && rc=$idx
30897         done
30898
30899         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30900                 error "Fail to rename foo0 to foo1"
30901         if [ $rc -eq 0 ]; then
30902                 for idx in $(seq $MDSCOUNT); do
30903                         dev=$(mdsdevname $idx)
30904                         do_facet mds${idx} \
30905                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30906                         grep ${fid} && rc=$idx
30907                 done
30908         fi
30909
30910         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30911                 error "Fail to rename foo1 to foo2"
30912         if [ $rc -eq 0 ]; then
30913                 for idx in $(seq $MDSCOUNT); do
30914                         dev=$(mdsdevname $idx)
30915                         do_facet mds${idx} \
30916                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30917                         grep ${fid} && rc=$idx
30918                 done
30919         fi
30920
30921         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30922
30923         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30924                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30925         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30926                 error "Fail to rename foo2 to foo0"
30927         unlink $DIR/$tdir/dir1/foo0 ||
30928                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30929         rm -rf $DIR/$tdir/dir0 ||
30930                 error "Fail to rm $DIR/$tdir/dir0"
30931
30932         for idx in $(seq $MDSCOUNT); do
30933                 rc=0
30934
30935                 stop mds${idx}
30936                 dev=$(mdsdevname $idx)
30937                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30938                         rc=$?
30939                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30940                         error "mount mds$idx failed"
30941                 df $MOUNT > /dev/null 2>&1
30942
30943                 # e2fsck should not return error
30944                 [ $rc -eq 0 ] ||
30945                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30946         done
30947 }
30948 run_test 804 "verify agent entry for remote entry"
30949
30950 cleanup_805() {
30951         do_facet $SINGLEMDS zfs set quota=$old $fsset
30952         unlinkmany $DIR/$tdir/f- 1000000
30953         trap 0
30954 }
30955
30956 test_805() {
30957         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30958         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30959         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30960                 skip "netfree not implemented before 0.7"
30961         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30962                 skip "Need MDS version at least 2.10.57"
30963
30964         local fsset
30965         local freekb
30966         local usedkb
30967         local old
30968         local quota
30969         local pref="osd-zfs.$FSNAME-MDT0000."
30970
30971         # limit available space on MDS dataset to meet nospace issue
30972         # quickly. then ZFS 0.7.2 can use reserved space if asked
30973         # properly (using netfree flag in osd_declare_destroy()
30974         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30975         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30976                 gawk '{print $3}')
30977         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30978         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30979         let "usedkb=usedkb-freekb"
30980         let "freekb=freekb/2"
30981         if let "freekb > 5000"; then
30982                 let "freekb=5000"
30983         fi
30984         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30985         trap cleanup_805 EXIT
30986         mkdir_on_mdt0 $DIR/$tdir
30987         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30988                 error "Can't set PFL layout"
30989         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30990         rm -rf $DIR/$tdir || error "not able to remove"
30991         do_facet $SINGLEMDS zfs set quota=$old $fsset
30992         trap 0
30993 }
30994 run_test 805 "ZFS can remove from full fs"
30995
30996 # Size-on-MDS test
30997 check_lsom_data()
30998 {
30999         local file=$1
31000         local expect=$(stat -c %s $file)
31001
31002         check_lsom_size $1 $expect
31003
31004         local blocks=$($LFS getsom -b $file)
31005         expect=$(stat -c %b $file)
31006         [[ $blocks == $expect ]] ||
31007                 error "$file expected blocks: $expect, got: $blocks"
31008 }
31009
31010 check_lsom_size()
31011 {
31012         local size
31013         local expect=$2
31014
31015         cancel_lru_locks mdc
31016
31017         size=$($LFS getsom -s $1)
31018         [[ $size == $expect ]] ||
31019                 error "$file expected size: $expect, got: $size"
31020 }
31021
31022 test_806() {
31023         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31024                 skip "Need MDS version at least 2.11.52"
31025
31026         local bs=1048576
31027
31028         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
31029
31030         disable_opencache
31031         stack_trap "restore_opencache"
31032
31033         # single-threaded write
31034         echo "Test SOM for single-threaded write"
31035         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
31036                 error "write $tfile failed"
31037         check_lsom_size $DIR/$tfile $bs
31038
31039         local num=32
31040         local size=$(($num * $bs))
31041         local offset=0
31042         local i
31043
31044         echo "Test SOM for single client multi-threaded($num) write"
31045         $TRUNCATE $DIR/$tfile 0
31046         for ((i = 0; i < $num; i++)); do
31047                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31048                 local pids[$i]=$!
31049                 offset=$((offset + $bs))
31050         done
31051         for (( i=0; i < $num; i++ )); do
31052                 wait ${pids[$i]}
31053         done
31054         check_lsom_size $DIR/$tfile $size
31055
31056         $TRUNCATE $DIR/$tfile 0
31057         for ((i = 0; i < $num; i++)); do
31058                 offset=$((offset - $bs))
31059                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31060                 local pids[$i]=$!
31061         done
31062         for (( i=0; i < $num; i++ )); do
31063                 wait ${pids[$i]}
31064         done
31065         check_lsom_size $DIR/$tfile $size
31066
31067         # multi-client writes
31068         num=$(get_node_count ${CLIENTS//,/ })
31069         size=$(($num * $bs))
31070         offset=0
31071         i=0
31072
31073         echo "Test SOM for multi-client ($num) writes"
31074         $TRUNCATE $DIR/$tfile 0
31075         for client in ${CLIENTS//,/ }; do
31076                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31077                 local pids[$i]=$!
31078                 i=$((i + 1))
31079                 offset=$((offset + $bs))
31080         done
31081         for (( i=0; i < $num; i++ )); do
31082                 wait ${pids[$i]}
31083         done
31084         check_lsom_size $DIR/$tfile $offset
31085
31086         i=0
31087         $TRUNCATE $DIR/$tfile 0
31088         for client in ${CLIENTS//,/ }; do
31089                 offset=$((offset - $bs))
31090                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31091                 local pids[$i]=$!
31092                 i=$((i + 1))
31093         done
31094         for (( i=0; i < $num; i++ )); do
31095                 wait ${pids[$i]}
31096         done
31097         check_lsom_size $DIR/$tfile $size
31098
31099         # verify SOM blocks count
31100         echo "Verify SOM block count"
31101         $TRUNCATE $DIR/$tfile 0
31102         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
31103                 error "failed to write file $tfile with fdatasync and fstat"
31104         check_lsom_data $DIR/$tfile
31105
31106         $TRUNCATE $DIR/$tfile 0
31107         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
31108                 error "failed to write file $tfile with fdatasync"
31109         check_lsom_data $DIR/$tfile
31110
31111         $TRUNCATE $DIR/$tfile 0
31112         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
31113                 error "failed to write file $tfile with sync IO"
31114         check_lsom_data $DIR/$tfile
31115
31116         # verify truncate
31117         echo "Test SOM for truncate"
31118         # use ftruncate to sync blocks on close request
31119         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
31120         check_lsom_size $DIR/$tfile 16384
31121         check_lsom_data $DIR/$tfile
31122
31123         $TRUNCATE $DIR/$tfile 1234
31124         check_lsom_size $DIR/$tfile 1234
31125         # sync blocks on the MDT
31126         $MULTIOP $DIR/$tfile oc
31127         check_lsom_data $DIR/$tfile
31128 }
31129 run_test 806 "Verify Lazy Size on MDS"
31130
31131 test_807() {
31132         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
31133         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
31134                 skip "Need MDS version at least 2.11.52"
31135
31136         # Registration step
31137         changelog_register || error "changelog_register failed"
31138         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
31139         changelog_users $SINGLEMDS | grep -q $cl_user ||
31140                 error "User $cl_user not found in changelog_users"
31141
31142         rm -rf $DIR/$tdir || error "rm $tdir failed"
31143         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31144         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
31145         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
31146         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
31147                 error "truncate $tdir/trunc failed"
31148
31149         local bs=1048576
31150         echo "Test SOM for single-threaded write with fsync"
31151         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
31152                 error "write $tfile failed"
31153         sync;sync;sync
31154
31155         # multi-client wirtes
31156         local num=$(get_node_count ${CLIENTS//,/ })
31157         local offset=0
31158         local i=0
31159
31160         echo "Test SOM for multi-client ($num) writes"
31161         touch $DIR/$tfile || error "touch $tfile failed"
31162         $TRUNCATE $DIR/$tfile 0
31163         for client in ${CLIENTS//,/ }; do
31164                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
31165                 local pids[$i]=$!
31166                 i=$((i + 1))
31167                 offset=$((offset + $bs))
31168         done
31169         for (( i=0; i < $num; i++ )); do
31170                 wait ${pids[$i]}
31171         done
31172
31173         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
31174         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
31175         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
31176         check_lsom_data $DIR/$tdir/trunc
31177         check_lsom_data $DIR/$tdir/single_dd
31178         check_lsom_data $DIR/$tfile
31179
31180         rm -rf $DIR/$tdir
31181         # Deregistration step
31182         changelog_deregister || error "changelog_deregister failed"
31183 }
31184 run_test 807 "verify LSOM syncing tool"
31185
31186 check_som_nologged()
31187 {
31188         local lines=$($LFS changelog $FSNAME-MDT0000 |
31189                 grep 'x=trusted.som' | wc -l)
31190         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
31191 }
31192
31193 test_808() {
31194         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
31195                 skip "Need MDS version at least 2.11.55"
31196
31197         # Registration step
31198         changelog_register || error "changelog_register failed"
31199
31200         touch $DIR/$tfile || error "touch $tfile failed"
31201         check_som_nologged
31202
31203         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
31204                 error "write $tfile failed"
31205         check_som_nologged
31206
31207         $TRUNCATE $DIR/$tfile 1234
31208         check_som_nologged
31209
31210         $TRUNCATE $DIR/$tfile 1048576
31211         check_som_nologged
31212
31213         # Deregistration step
31214         changelog_deregister || error "changelog_deregister failed"
31215 }
31216 run_test 808 "Check trusted.som xattr not logged in Changelogs"
31217
31218 check_som_nodata()
31219 {
31220         $LFS getsom $1
31221         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
31222 }
31223
31224 test_809() {
31225         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
31226                 skip "Need MDS version at least 2.11.56"
31227
31228         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
31229                 error "failed to create DoM-only file $DIR/$tfile"
31230         touch $DIR/$tfile || error "touch $tfile failed"
31231         check_som_nodata $DIR/$tfile
31232
31233         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
31234                 error "write $tfile failed"
31235         check_som_nodata $DIR/$tfile
31236
31237         $TRUNCATE $DIR/$tfile 1234
31238         check_som_nodata $DIR/$tfile
31239
31240         $TRUNCATE $DIR/$tfile 4097
31241         check_som_nodata $DIR/$file
31242 }
31243 run_test 809 "Verify no SOM xattr store for DoM-only files"
31244
31245 test_810() {
31246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31247         $GSS && skip_env "could not run with gss"
31248         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
31249                 skip "OST < 2.12.58 doesn't align checksum"
31250
31251         set_checksums 1
31252         stack_trap "set_checksums $ORIG_CSUM" EXIT
31253         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
31254
31255         local csum
31256         local before
31257         local after
31258         for csum in $CKSUM_TYPES; do
31259                 #define OBD_FAIL_OSC_NO_GRANT   0x411
31260                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
31261                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
31262                         eval set -- $i
31263                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
31264                         before=$(md5sum $DIR/$tfile)
31265                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
31266                         after=$(md5sum $DIR/$tfile)
31267                         [ "$before" == "$after" ] ||
31268                                 error "$csum: $before != $after bs=$1 seek=$2"
31269                 done
31270         done
31271 }
31272 run_test 810 "partial page writes on ZFS (LU-11663)"
31273
31274 test_812a() {
31275         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31276                 skip "OST < 2.12.51 doesn't support this fail_loc"
31277
31278         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31279         # ensure ost1 is connected
31280         stat $DIR/$tfile >/dev/null || error "can't stat"
31281         wait_osc_import_state client ost1 FULL
31282         # no locks, no reqs to let the connection idle
31283         cancel_lru_locks osc
31284
31285         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31286 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31287         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31288         wait_osc_import_state client ost1 CONNECTING
31289         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31290
31291         stat $DIR/$tfile >/dev/null || error "can't stat file"
31292 }
31293 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
31294
31295 test_812b() { # LU-12378
31296         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
31297                 skip "OST < 2.12.51 doesn't support this fail_loc"
31298
31299         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
31300         # ensure ost1 is connected
31301         stat $DIR/$tfile >/dev/null || error "can't stat"
31302         wait_osc_import_state client ost1 FULL
31303         # no locks, no reqs to let the connection idle
31304         cancel_lru_locks osc
31305
31306         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
31307 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
31308         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
31309         wait_osc_import_state client ost1 CONNECTING
31310         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
31311
31312         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
31313         wait_osc_import_state client ost1 IDLE
31314 }
31315 run_test 812b "do not drop no resend request for idle connect"
31316
31317 test_812c() {
31318         local old
31319
31320         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
31321
31322         $LFS setstripe -c 1 -o 0 $DIR/$tfile
31323         $LFS getstripe $DIR/$tfile
31324         $LCTL set_param osc.*.idle_timeout=10
31325         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
31326         # ensure ost1 is connected
31327         stat $DIR/$tfile >/dev/null || error "can't stat"
31328         wait_osc_import_state client ost1 FULL
31329         # no locks, no reqs to let the connection idle
31330         cancel_lru_locks osc
31331
31332 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
31333         $LCTL set_param fail_loc=0x80000533
31334         sleep 15
31335         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
31336 }
31337 run_test 812c "idle import vs lock enqueue race"
31338
31339 test_813() {
31340         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
31341         [ -z "$file_heat_sav" ] && skip "no file heat support"
31342
31343         local readsample
31344         local writesample
31345         local readbyte
31346         local writebyte
31347         local readsample1
31348         local writesample1
31349         local readbyte1
31350         local writebyte1
31351
31352         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
31353         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
31354
31355         $LCTL set_param -n llite.*.file_heat=1
31356         echo "Turn on file heat"
31357         echo "Period second: $period_second, Decay percentage: $decay_pct"
31358
31359         echo "QQQQ" > $DIR/$tfile
31360         echo "QQQQ" > $DIR/$tfile
31361         echo "QQQQ" > $DIR/$tfile
31362         cat $DIR/$tfile > /dev/null
31363         cat $DIR/$tfile > /dev/null
31364         cat $DIR/$tfile > /dev/null
31365         cat $DIR/$tfile > /dev/null
31366
31367         local out=$($LFS heat_get $DIR/$tfile)
31368
31369         $LFS heat_get $DIR/$tfile
31370         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31371         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31372         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31373         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31374
31375         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
31376         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
31377         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
31378         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
31379
31380         sleep $((period_second + 3))
31381         echo "Sleep $((period_second + 3)) seconds..."
31382         # The recursion formula to calculate the heat of the file f is as
31383         # follow:
31384         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
31385         # Where Hi is the heat value in the period between time points i*I and
31386         # (i+1)*I; Ci is the access count in the period; the symbol P refers
31387         # to the weight of Ci.
31388         out=$($LFS heat_get $DIR/$tfile)
31389         $LFS heat_get $DIR/$tfile
31390         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31391         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31392         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31393         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31394
31395         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
31396                 error "read sample ($readsample) is wrong"
31397         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
31398                 error "write sample ($writesample) is wrong"
31399         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
31400                 error "read bytes ($readbyte) is wrong"
31401         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
31402                 error "write bytes ($writebyte) is wrong"
31403
31404         echo "QQQQ" > $DIR/$tfile
31405         echo "QQQQ" > $DIR/$tfile
31406         echo "QQQQ" > $DIR/$tfile
31407         cat $DIR/$tfile > /dev/null
31408         cat $DIR/$tfile > /dev/null
31409         cat $DIR/$tfile > /dev/null
31410         cat $DIR/$tfile > /dev/null
31411
31412         sleep $((period_second + 3))
31413         echo "Sleep $((period_second + 3)) seconds..."
31414
31415         out=$($LFS heat_get $DIR/$tfile)
31416         $LFS heat_get $DIR/$tfile
31417         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31418         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31419         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31420         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31421
31422         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
31423                 4 * $decay_pct) / 100") -eq 1 ] ||
31424                 error "read sample ($readsample1) is wrong"
31425         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
31426                 3 * $decay_pct) / 100") -eq 1 ] ||
31427                 error "write sample ($writesample1) is wrong"
31428         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
31429                 20 * $decay_pct) / 100") -eq 1 ] ||
31430                 error "read bytes ($readbyte1) is wrong"
31431         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
31432                 15 * $decay_pct) / 100") -eq 1 ] ||
31433                 error "write bytes ($writebyte1) is wrong"
31434
31435         echo "Turn off file heat for the file $DIR/$tfile"
31436         $LFS heat_set -o $DIR/$tfile
31437
31438         echo "QQQQ" > $DIR/$tfile
31439         echo "QQQQ" > $DIR/$tfile
31440         echo "QQQQ" > $DIR/$tfile
31441         cat $DIR/$tfile > /dev/null
31442         cat $DIR/$tfile > /dev/null
31443         cat $DIR/$tfile > /dev/null
31444         cat $DIR/$tfile > /dev/null
31445
31446         out=$($LFS heat_get $DIR/$tfile)
31447         $LFS heat_get $DIR/$tfile
31448         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31449         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31450         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31451         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31452
31453         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31454         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31455         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31456         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31457
31458         echo "Trun on file heat for the file $DIR/$tfile"
31459         $LFS heat_set -O $DIR/$tfile
31460
31461         echo "QQQQ" > $DIR/$tfile
31462         echo "QQQQ" > $DIR/$tfile
31463         echo "QQQQ" > $DIR/$tfile
31464         cat $DIR/$tfile > /dev/null
31465         cat $DIR/$tfile > /dev/null
31466         cat $DIR/$tfile > /dev/null
31467         cat $DIR/$tfile > /dev/null
31468
31469         out=$($LFS heat_get $DIR/$tfile)
31470         $LFS heat_get $DIR/$tfile
31471         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31472         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31473         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31474         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31475
31476         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31477         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31478         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31479         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31480
31481         $LFS heat_set -c $DIR/$tfile
31482         $LCTL set_param -n llite.*.file_heat=0
31483         echo "Turn off file heat support for the Lustre filesystem"
31484
31485         echo "QQQQ" > $DIR/$tfile
31486         echo "QQQQ" > $DIR/$tfile
31487         echo "QQQQ" > $DIR/$tfile
31488         cat $DIR/$tfile > /dev/null
31489         cat $DIR/$tfile > /dev/null
31490         cat $DIR/$tfile > /dev/null
31491         cat $DIR/$tfile > /dev/null
31492
31493         out=$($LFS heat_get $DIR/$tfile)
31494         $LFS heat_get $DIR/$tfile
31495         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31496         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31497         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31498         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31499
31500         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31501         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31502         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31503         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31504
31505         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31506         rm -f $DIR/$tfile
31507 }
31508 run_test 813 "File heat verfication"
31509
31510 test_814()
31511 {
31512         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31513         echo -n y >> $DIR/$tfile
31514         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31515         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31516 }
31517 run_test 814 "sparse cp works as expected (LU-12361)"
31518
31519 test_815()
31520 {
31521         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31522         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31523 }
31524 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31525
31526 test_816() {
31527         local ost1_imp=$(get_osc_import_name client ost1)
31528         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31529                          cut -d'.' -f2)
31530
31531         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31532         # ensure ost1 is connected
31533
31534         stat $DIR/$tfile >/dev/null || error "can't stat"
31535         wait_osc_import_state client ost1 FULL
31536         # no locks, no reqs to let the connection idle
31537         cancel_lru_locks osc
31538         lru_resize_disable osc
31539         local before
31540         local now
31541         before=$($LCTL get_param -n \
31542                  ldlm.namespaces.$imp_name.lru_size)
31543
31544         wait_osc_import_state client ost1 IDLE
31545         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31546         now=$($LCTL get_param -n \
31547               ldlm.namespaces.$imp_name.lru_size)
31548         [ $before == $now ] || error "lru_size changed $before != $now"
31549 }
31550 run_test 816 "do not reset lru_resize on idle reconnect"
31551
31552 cleanup_817() {
31553         umount $tmpdir
31554         exportfs -u localhost:$DIR/nfsexp
31555         rm -rf $DIR/nfsexp
31556 }
31557
31558 test_817() {
31559         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31560
31561         mkdir -p $DIR/nfsexp
31562         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31563                 error "failed to export nfs"
31564
31565         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31566         stack_trap cleanup_817 EXIT
31567
31568         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31569                 error "failed to mount nfs to $tmpdir"
31570
31571         cp /bin/true $tmpdir
31572         $DIR/nfsexp/true || error "failed to execute 'true' command"
31573 }
31574 run_test 817 "nfsd won't cache write lock for exec file"
31575
31576 test_818() {
31577         test_mkdir -i0 -c1 $DIR/$tdir
31578         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31579         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31580         stop $SINGLEMDS
31581
31582         # restore osp-syn threads
31583         stack_trap "fail $SINGLEMDS"
31584
31585         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31586         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31587         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31588                 error "start $SINGLEMDS failed"
31589         rm -rf $DIR/$tdir
31590
31591         local testid=$(echo $TESTNAME | tr '_' ' ')
31592
31593         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31594                 grep "run LFSCK" || error "run LFSCK is not suggested"
31595 }
31596 run_test 818 "unlink with failed llog"
31597
31598 test_819a() {
31599         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31600         cancel_lru_locks osc
31601         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31602         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31603         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31604         rm -f $TDIR/$tfile
31605 }
31606 run_test 819a "too big niobuf in read"
31607
31608 test_819b() {
31609         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31610         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31611         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31612         cancel_lru_locks osc
31613         sleep 1
31614         rm -f $TDIR/$tfile
31615 }
31616 run_test 819b "too big niobuf in write"
31617
31618
31619 function test_820_start_ost() {
31620         sleep 5
31621
31622         for num in $(seq $OSTCOUNT); do
31623                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31624         done
31625 }
31626
31627 test_820() {
31628         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31629
31630         mkdir $DIR/$tdir
31631         umount_client $MOUNT || error "umount failed"
31632         for num in $(seq $OSTCOUNT); do
31633                 stop ost$num
31634         done
31635
31636         # mount client with no active OSTs
31637         # so that the client can't initialize max LOV EA size
31638         # from OSC notifications
31639         mount_client $MOUNT || error "mount failed"
31640         # delay OST starting to keep this 0 max EA size for a while
31641         test_820_start_ost &
31642
31643         # create a directory on MDS2
31644         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31645                 error "Failed to create directory"
31646         # open intent should update default EA size
31647         # see mdc_update_max_ea_from_body()
31648         # notice this is the very first RPC to MDS2
31649         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31650         ret=$?
31651         echo $out
31652         # With SSK, this situation can lead to -EPERM being returned.
31653         # In that case, simply retry.
31654         if [ $ret -ne 0 ] && $SHARED_KEY; then
31655                 if echo "$out" | grep -q "not permitted"; then
31656                         cp /etc/services $DIR/$tdir/mds2
31657                         ret=$?
31658                 fi
31659         fi
31660         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31661 }
31662 run_test 820 "update max EA from open intent"
31663
31664 test_823() {
31665         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31666         local OST_MAX_PRECREATE=20000
31667
31668         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31669                 skip "Need MDS version at least 2.14.56"
31670
31671         save_lustre_params mds1 \
31672                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31673         do_facet $SINGLEMDS "$LCTL set_param -n \
31674                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31675         do_facet $SINGLEMDS "$LCTL set_param -n \
31676                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31677
31678         stack_trap "restore_lustre_params < $p; rm $p"
31679
31680         do_facet $SINGLEMDS "$LCTL set_param -n \
31681                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31682
31683         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31684                       osp.$FSNAME-OST0000*MDT0000.create_count")
31685         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31686                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31687         local expect_count=$(((($max/2)/256) * 256))
31688
31689         log "setting create_count to 100200:"
31690         log " -result- count: $count with max: $max, expecting: $expect_count"
31691
31692         [[ $count -eq expect_count ]] ||
31693                 error "Create count not set to max precreate."
31694 }
31695 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31696
31697 test_831() {
31698         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31699                 skip "Need MDS version 2.14.56"
31700
31701         local sync_changes=$(do_facet $SINGLEMDS \
31702                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31703
31704         [ "$sync_changes" -gt 100 ] &&
31705                 skip "Sync changes $sync_changes > 100 already"
31706
31707         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31708
31709         $LFS mkdir -i 0 $DIR/$tdir
31710         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31711
31712         save_lustre_params mds1 \
31713                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31714         save_lustre_params mds1 \
31715                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31716
31717         do_facet mds1 "$LCTL set_param -n \
31718                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31719                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31720         stack_trap "restore_lustre_params < $p" EXIT
31721
31722         createmany -o $DIR/$tdir/f- 1000
31723         unlinkmany $DIR/$tdir/f- 1000 &
31724         local UNLINK_PID=$!
31725
31726         while sleep 1; do
31727                 sync_changes=$(do_facet mds1 \
31728                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31729                 # the check in the code is racy, fail the test
31730                 # if the value above the limit by 10.
31731                 [ $sync_changes -gt 110 ] && {
31732                         kill -2 $UNLINK_PID
31733                         wait
31734                         error "osp changes throttling failed, $sync_changes>110"
31735                 }
31736                 kill -0 $UNLINK_PID 2> /dev/null || break
31737         done
31738         wait
31739 }
31740 run_test 831 "throttling unlink/setattr queuing on OSP"
31741
31742 test_832() {
31743         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31744         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31745                 skip "Need MDS version 2.15.52+"
31746         is_rmentry_supported || skip "rm_entry not supported"
31747
31748         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31749         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31750         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31751                 error "mkdir remote_dir failed"
31752         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31753                 error "mkdir striped_dir failed"
31754         touch $DIR/$tdir/file || error "touch file failed"
31755         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31756         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31757 }
31758 run_test 832 "lfs rm_entry"
31759
31760 test_833() {
31761         local file=$DIR/$tfile
31762
31763         stack_trap "rm -f $file" EXIT
31764         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31765
31766         local wpid
31767         local rpid
31768         local rpid2
31769
31770         # Buffered I/O write
31771         (
31772                 while [ ! -e $DIR/sanity.833.lck ]; do
31773                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31774                                 error "failed to write $file"
31775                         sleep 0.$((RANDOM % 4 + 1))
31776                 done
31777         )&
31778         wpid=$!
31779
31780         # Buffered I/O read
31781         (
31782                 while [ ! -e $DIR/sanity.833.lck ]; do
31783                         dd if=$file of=/dev/null bs=1M count=50 ||
31784                                 error "failed to read $file"
31785                         sleep 0.$((RANDOM % 4 + 1))
31786                 done
31787         )&
31788         rpid=$!
31789
31790         # Direct I/O read
31791         (
31792                 while [ ! -e $DIR/sanity.833.lck ]; do
31793                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31794                                 error "failed to read $file in direct I/O mode"
31795                         sleep 0.$((RANDOM % 4 + 1))
31796                 done
31797         )&
31798         rpid2=$!
31799
31800         sleep 30
31801         touch $DIR/sanity.833.lck
31802         wait $wpid || error "$?: buffered write failed"
31803         wait $rpid || error "$?: buffered read failed"
31804         wait $rpid2 || error "$?: direct read failed"
31805 }
31806 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31807
31808 test_850() {
31809         local dir=$DIR/$tdir
31810         local file=$dir/$tfile
31811         local statsfile=$dir/all_job_stats.txt
31812
31813         test_mkdir -p $dir || error "failed to create dir $dir"
31814         echo "abcdefg" > $file || error "failed to create file $file"
31815
31816         # read job_stats in the living system
31817         lljobstat -n 1 ||
31818                 error "failed to run lljobstat on living system"
31819
31820         $LCTL get_param *.*.job_stats > $statsfile
31821         lljobstat --statsfile=$statsfile ||
31822                 error "failed to run lljobstat on file $statsfile"
31823 }
31824 run_test 850 "lljobstat can parse living and aggregated job_stats"
31825
31826 #
31827 # tests that do cleanup/setup should be run at the end
31828 #
31829
31830 test_900() {
31831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31832         local ls
31833
31834         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31835         $LCTL set_param fail_loc=0x903
31836
31837         cancel_lru_locks MGC
31838
31839         FAIL_ON_ERROR=true cleanup
31840         FAIL_ON_ERROR=true setup
31841 }
31842 run_test 900 "umount should not race with any mgc requeue thread"
31843
31844 # LUS-6253/LU-11185
31845 test_901() {
31846         local old
31847         local count
31848         local oldc
31849         local newc
31850         local olds
31851         local news
31852         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31853
31854         # some get_param have a bug to handle dot in param name
31855         cancel_lru_locks MGC
31856         old=$(mount -t lustre | wc -l)
31857         # 1 config+sptlrpc
31858         # 2 params
31859         # 3 nodemap
31860         # 4 IR
31861         old=$((old * 4))
31862         oldc=0
31863         count=0
31864         while [ $old -ne $oldc ]; do
31865                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31866                 sleep 1
31867                 ((count++))
31868                 if [ $count -ge $TIMEOUT ]; then
31869                         error "too large timeout"
31870                 fi
31871         done
31872         umount_client $MOUNT || error "umount failed"
31873         mount_client $MOUNT || error "mount failed"
31874         cancel_lru_locks MGC
31875         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31876
31877         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31878
31879         return 0
31880 }
31881 run_test 901 "don't leak a mgc lock on client umount"
31882
31883 # LU-13377
31884 test_902() {
31885         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31886                 skip "client does not have LU-13377 fix"
31887         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31888         $LCTL set_param fail_loc=0x1415
31889         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31890         cancel_lru_locks osc
31891         rm -f $DIR/$tfile
31892 }
31893 run_test 902 "test short write doesn't hang lustre"
31894
31895 # LU-14711
31896 test_903() {
31897         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31898         echo "blah" > $DIR/${tfile}-2
31899         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31900         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31901         $LCTL set_param fail_loc=0x417 fail_val=20
31902
31903         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31904         sleep 1 # To start the destroy
31905         wait_destroy_complete 150 || error "Destroy taking too long"
31906         cat $DIR/$tfile > /dev/null || error "Evicted"
31907 }
31908 run_test 903 "Test long page discard does not cause evictions"
31909
31910 test_904() {
31911         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31912         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31913                 grep -q project || skip "skip project quota not supported"
31914
31915         local testfile="$DIR/$tdir/$tfile"
31916         local xattr="trusted.projid"
31917         local projid
31918         local mdts=$(comma_list $(mdts_nodes))
31919         local saved=$(do_facet mds1 $LCTL get_param -n \
31920                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31921
31922         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31923         stack_trap "do_nodes $mdts $LCTL set_param \
31924                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31925
31926         mkdir -p $DIR/$tdir
31927         touch $testfile
31928         #hide projid xattr on server
31929         $LFS project -p 1 $testfile ||
31930                 error "set $testfile project id failed"
31931         getfattr -m - $testfile | grep $xattr &&
31932                 error "do not show trusted.projid when disabled on server"
31933         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31934         #should be hidden when projid is 0
31935         $LFS project -p 0 $testfile ||
31936                 error "set $testfile project id failed"
31937         getfattr -m - $testfile | grep $xattr &&
31938                 error "do not show trusted.projid with project ID 0"
31939
31940         #still can getxattr explicitly
31941         projid=$(getfattr -n $xattr $testfile |
31942                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31943         [ $projid == "0" ] ||
31944                 error "projid expected 0 not $projid"
31945
31946         #set the projid via setxattr
31947         setfattr -n $xattr -v "1000" $testfile ||
31948                 error "setattr failed with $?"
31949         projid=($($LFS project $testfile))
31950         [ ${projid[0]} == "1000" ] ||
31951                 error "projid expected 1000 not $projid"
31952
31953         #check the new projid via getxattr
31954         $LFS project -p 1001 $testfile ||
31955                 error "set $testfile project id failed"
31956         getfattr -m - $testfile | grep $xattr ||
31957                 error "should show trusted.projid when project ID != 0"
31958         projid=$(getfattr -n $xattr $testfile |
31959                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31960         [ $projid == "1001" ] ||
31961                 error "projid expected 1001 not $projid"
31962
31963         #try to set invalid projid
31964         setfattr -n $xattr -v "4294967295" $testfile &&
31965                 error "set invalid projid should fail"
31966
31967         #remove the xattr means setting projid to 0
31968         setfattr -x $xattr $testfile ||
31969                 error "setfattr failed with $?"
31970         projid=($($LFS project $testfile))
31971         [ ${projid[0]} == "0" ] ||
31972                 error "projid expected 0 not $projid"
31973
31974         #should be hidden when parent has inherit flag and same projid
31975         $LFS project -srp 1002 $DIR/$tdir ||
31976                 error "set $tdir project id failed"
31977         getfattr -m - $testfile | grep $xattr &&
31978                 error "do not show trusted.projid with inherit flag"
31979
31980         #still can getxattr explicitly
31981         projid=$(getfattr -n $xattr $testfile |
31982                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31983         [ $projid == "1002" ] ||
31984                 error "projid expected 1002 not $projid"
31985 }
31986 run_test 904 "virtual project ID xattr"
31987
31988 # LU-8582
31989 test_905() {
31990         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31991                 skip "need OST version >= 2.15.50.220 for fail_loc"
31992
31993         remote_ost_nodsh && skip "remote OST with nodsh"
31994         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31995
31996         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31997
31998         #define OBD_FAIL_OST_OPCODE 0x253
31999         # OST_LADVISE = 21
32000         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
32001         $LFS ladvise -a willread $DIR/$tfile &&
32002                 error "unexpected success of ladvise with fault injection"
32003         $LFS ladvise -a willread $DIR/$tfile |&
32004                 grep -q "Operation not supported"
32005         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
32006 }
32007 run_test 905 "bad or new opcode should not stuck client"
32008
32009 test_906() {
32010         grep -q io_uring_setup /proc/kallsyms ||
32011                 skip "Client OS does not support io_uring I/O engine"
32012         io_uring_probe || skip "kernel does not support io_uring fully"
32013         which fio || skip_env "no fio installed"
32014         fio --enghelp | grep -q io_uring ||
32015                 skip_env "fio does not support io_uring I/O engine"
32016
32017         local file=$DIR/$tfile
32018         local ioengine="io_uring"
32019         local numjobs=2
32020         local size=50M
32021
32022         fio --name=seqwrite --ioengine=$ioengine        \
32023                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32024                 --iodepth=64 --size=$size --filename=$file --rw=write ||
32025                 error "fio seqwrite $file failed"
32026
32027         fio --name=seqread --ioengine=$ioengine \
32028                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
32029                 --iodepth=64 --size=$size --filename=$file --rw=read ||
32030                 error "fio seqread $file failed"
32031
32032         rm -f $file || error "rm -f $file failed"
32033 }
32034 run_test 906 "Simple test for io_uring I/O engine via fio"
32035
32036 test_907() {
32037         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
32038
32039         # set stripe size to max rpc size
32040         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
32041         $LFS getstripe $DIR/$tfile
32042 #define OBD_FAIL_OST_EROFS               0x216
32043         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
32044
32045         local bs=$((max_pages * PAGE_SIZE / 16))
32046
32047         # write full one stripe and one block
32048         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
32049
32050         rm $DIR/$tfile || error "rm failed"
32051 }
32052 run_test 907 "write rpc error during unlink"
32053
32054
32055 complete_test $SECONDS
32056 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
32057 check_and_cleanup_lustre
32058 if [ "$I_MOUNTED" != "yes" ]; then
32059         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
32060 fi
32061 exit_status