Whamcloud - gitweb
LU-17468 lod: component add missed pattern info
[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 obdclass/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 obdclass/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_57a() {
9068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9069         # note test will not do anything if MDS is not local
9070         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9071                 skip_env "ldiskfs only test"
9072         fi
9073         remote_mds_nodsh && skip "remote MDS with nodsh"
9074
9075         local MNTDEV="osd*.*MDT*.mntdev"
9076         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
9077         [ -z "$DEV" ] && error "can't access $MNTDEV"
9078         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
9079                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
9080                         error "can't access $DEV"
9081                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
9082                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
9083                 rm $TMP/t57a.dump
9084         done
9085 }
9086 run_test 57a "verify MDS filesystem created with large inodes =="
9087
9088 test_57b() {
9089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9090         if [ "$mds1_FSTYPE" != ldiskfs ]; then
9091                 skip_env "ldiskfs only test"
9092         fi
9093         remote_mds_nodsh && skip "remote MDS with nodsh"
9094
9095         local dir=$DIR/$tdir
9096         local filecount=100
9097         local file1=$dir/f1
9098         local fileN=$dir/f$filecount
9099
9100         rm -rf $dir || error "removing $dir"
9101         test_mkdir -c1 $dir
9102         local mdtidx=$($LFS getstripe -m $dir)
9103         local mdtname=MDT$(printf %04x $mdtidx)
9104         local facet=mds$((mdtidx + 1))
9105
9106         echo "mcreating $filecount files"
9107         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
9108
9109         # verify that files do not have EAs yet
9110         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
9111                 error "$file1 has an EA"
9112         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
9113                 error "$fileN has an EA"
9114
9115         sync
9116         sleep 1
9117         df $dir  #make sure we get new statfs data
9118         local mdsfree=$(do_facet $facet \
9119                         lctl get_param -n osd*.*$mdtname.kbytesfree)
9120         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9121         local file
9122
9123         echo "opening files to create objects/EAs"
9124         for file in $(seq -f $dir/f%g 1 $filecount); do
9125                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
9126                         error "opening $file"
9127         done
9128
9129         # verify that files have EAs now
9130         $LFS getstripe -y $file1 | grep -q "l_ost_idx" ||
9131                 error "$file1 missing EA"
9132         $LFS getstripe -y $fileN | grep -q "l_ost_idx" ||
9133                 error "$fileN missing EA"
9134
9135         sleep 1  #make sure we get new statfs data
9136         df $dir
9137         local mdsfree2=$(do_facet $facet \
9138                          lctl get_param -n osd*.*$mdtname.kbytesfree)
9139         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
9140
9141         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
9142                 if [ "$mdsfree" != "$mdsfree2" ]; then
9143                         error "MDC before $mdcfree != after $mdcfree2"
9144                 else
9145                         echo "MDC before $mdcfree != after $mdcfree2"
9146                         echo "unable to confirm if MDS has large inodes"
9147                 fi
9148         fi
9149         rm -rf $dir
9150 }
9151 run_test 57b "default LOV EAs are stored inside large inodes ==="
9152
9153 test_58() {
9154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9155         [ -z "$(which wiretest 2>/dev/null)" ] &&
9156                         skip_env "could not find wiretest"
9157
9158         wiretest
9159 }
9160 run_test 58 "verify cross-platform wire constants =============="
9161
9162 test_59() {
9163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9164
9165         echo "touch 130 files"
9166         createmany -o $DIR/f59- 130
9167         echo "rm 130 files"
9168         unlinkmany $DIR/f59- 130
9169         sync
9170         # wait for commitment of removal
9171         wait_delete_completed
9172 }
9173 run_test 59 "verify cancellation of llog records async ========="
9174
9175 TEST60_HEAD="test_60 run $RANDOM"
9176 test_60a() {
9177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9178         remote_mgs_nodsh && skip "remote MGS with nodsh"
9179         do_facet mgs "! which run-llog.sh &> /dev/null" &&
9180                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
9181                         skip_env "missing subtest run-llog.sh"
9182
9183         log "$TEST60_HEAD - from kernel mode"
9184         do_facet mgs "$LCTL dk > /dev/null"
9185         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
9186         do_facet mgs $LCTL dk > $TMP/$tfile
9187
9188         # LU-6388: test llog_reader
9189         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
9190         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
9191         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
9192                         skip_env "missing llog_reader"
9193         local fstype=$(facet_fstype mgs)
9194         [ $fstype != ldiskfs -a $fstype != zfs ] &&
9195                 skip_env "Only for ldiskfs or zfs type mgs"
9196
9197         local mntpt=$(facet_mntpt mgs)
9198         local mgsdev=$(mgsdevname 1)
9199         local fid_list
9200         local fid
9201         local rec_list
9202         local rec
9203         local rec_type
9204         local obj_file
9205         local path
9206         local seq
9207         local oid
9208         local pass=true
9209
9210         #get fid and record list
9211         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
9212                 tail -n 4))
9213         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
9214                 tail -n 4))
9215         #remount mgs as ldiskfs or zfs type
9216         stop mgs || error "stop mgs failed"
9217         mount_fstype mgs || error "remount mgs failed"
9218         for ((i = 0; i < ${#fid_list[@]}; i++)); do
9219                 fid=${fid_list[i]}
9220                 rec=${rec_list[i]}
9221                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
9222                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
9223                 oid=$((16#$oid))
9224
9225                 case $fstype in
9226                         ldiskfs )
9227                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
9228                         zfs )
9229                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
9230                 esac
9231                 echo "obj_file is $obj_file"
9232                 do_facet mgs $llog_reader $obj_file
9233
9234                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
9235                         awk '{ print $3 }' | sed -e "s/^type=//g")
9236                 if [ $rec_type != $rec ]; then
9237                         echo "FAILED test_60a wrong record type $rec_type," \
9238                               "should be $rec"
9239                         pass=false
9240                         break
9241                 fi
9242
9243                 #check obj path if record type is LLOG_LOGID_MAGIC
9244                 if [ "$rec" == "1064553b" ]; then
9245                         path=$(do_facet mgs $llog_reader $obj_file |
9246                                 grep "path=" | awk '{ print $NF }' |
9247                                 sed -e "s/^path=//g")
9248                         if [ $obj_file != $mntpt/$path ]; then
9249                                 echo "FAILED test_60a wrong obj path" \
9250                                       "$montpt/$path, should be $obj_file"
9251                                 pass=false
9252                                 break
9253                         fi
9254                 fi
9255         done
9256         rm -f $TMP/$tfile
9257         #restart mgs before "error", otherwise it will block the next test
9258         stop mgs || error "stop mgs failed"
9259         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
9260         $pass || error "test failed, see FAILED test_60a messages for specifics"
9261 }
9262 run_test 60a "llog_test run from kernel module and test llog_reader"
9263
9264 test_60b() { # bug 6411
9265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9266
9267         dmesg > $DIR/$tfile
9268         LLOG_COUNT=$(do_facet mgs dmesg |
9269                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
9270                           /llog_[a-z]*.c:[0-9]/ {
9271                                 if (marker)
9272                                         from_marker++
9273                                 from_begin++
9274                           }
9275                           END {
9276                                 if (marker)
9277                                         print from_marker
9278                                 else
9279                                         print from_begin
9280                           }")
9281
9282         [[ $LLOG_COUNT -gt 120 ]] &&
9283                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
9284 }
9285 run_test 60b "limit repeated messages from CERROR/CWARN"
9286
9287 test_60c() {
9288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9289
9290         echo "create 5000 files"
9291         createmany -o $DIR/f60c- 5000
9292 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
9293         lctl set_param fail_loc=0x80000137
9294         unlinkmany $DIR/f60c- 5000
9295         lctl set_param fail_loc=0
9296 }
9297 run_test 60c "unlink file when mds full"
9298
9299 test_60d() {
9300         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9301
9302         SAVEPRINTK=$(lctl get_param -n printk)
9303         # verify "lctl mark" is even working"
9304         MESSAGE="test message ID $RANDOM $$"
9305         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9306         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
9307
9308         lctl set_param printk=0 || error "set lnet.printk failed"
9309         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
9310         MESSAGE="new test message ID $RANDOM $$"
9311         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
9312         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
9313         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
9314
9315         lctl set_param -n printk="$SAVEPRINTK"
9316 }
9317 run_test 60d "test printk console message masking"
9318
9319 test_60e() {
9320         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9321         remote_mds_nodsh && skip "remote MDS with nodsh"
9322
9323         touch $DIR/$tfile
9324 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
9325         do_facet mds1 lctl set_param fail_loc=0x15b
9326         rm $DIR/$tfile
9327 }
9328 run_test 60e "no space while new llog is being created"
9329
9330 test_60f() {
9331         local old_path=$($LCTL get_param -n debug_path)
9332
9333         stack_trap "$LCTL set_param debug_path=$old_path"
9334         stack_trap "rm -f $TMP/$tfile*"
9335         rm -f $TMP/$tfile* 2> /dev/null
9336         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9337         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9338         test_mkdir $DIR/$tdir
9339         # retry in case the open is cached and not released
9340         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9341                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9342                 sleep 0.1
9343         done
9344         ls $TMP/$tfile*
9345         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9346 }
9347 run_test 60f "change debug_path works"
9348
9349 test_60g() {
9350         local pid
9351         local i
9352
9353         test_mkdir -c $MDSCOUNT $DIR/$tdir
9354
9355         (
9356                 local index=0
9357                 while true; do
9358                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9359                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9360                                 2>/dev/null
9361                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9362                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9363                         index=$((index + 1))
9364                 done
9365         ) &
9366
9367         pid=$!
9368
9369         for i in {0..100}; do
9370                 # define OBD_FAIL_OSD_TXN_START    0x19a
9371                 local index=$((i % MDSCOUNT + 1))
9372
9373                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9374                         > /dev/null
9375                 sleep 0.01
9376         done
9377
9378         kill -9 $pid
9379
9380         for i in $(seq $MDSCOUNT); do
9381                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9382         done
9383
9384         mkdir $DIR/$tdir/new || error "mkdir failed"
9385         rmdir $DIR/$tdir/new || error "rmdir failed"
9386
9387         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9388                 -t namespace
9389         for i in $(seq $MDSCOUNT); do
9390                 wait_update_facet mds$i "$LCTL get_param -n \
9391                         mdd.$(facet_svc mds$i).lfsck_namespace |
9392                         awk '/^status/ { print \\\$2 }'" "completed"
9393         done
9394
9395         ls -R $DIR/$tdir
9396         rm -rf $DIR/$tdir || error "rmdir failed"
9397 }
9398 run_test 60g "transaction abort won't cause MDT hung"
9399
9400 test_60h() {
9401         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9402                 skip "Need MDS version at least 2.12.52"
9403         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9404
9405         local f
9406
9407         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9408         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9409         for fail_loc in 0x80000188 0x80000189; do
9410                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9411                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9412                         error "mkdir $dir-$fail_loc failed"
9413                 for i in {0..10}; do
9414                         # create may fail on missing stripe
9415                         echo $i > $DIR/$tdir-$fail_loc/$i
9416                 done
9417                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9418                         error "getdirstripe $tdir-$fail_loc failed"
9419                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9420                         error "migrate $tdir-$fail_loc failed"
9421                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9422                         error "getdirstripe $tdir-$fail_loc failed"
9423                 pushd $DIR/$tdir-$fail_loc
9424                 for f in *; do
9425                         echo $f | cmp $f - || error "$f data mismatch"
9426                 done
9427                 popd
9428                 rm -rf $DIR/$tdir-$fail_loc
9429         done
9430 }
9431 run_test 60h "striped directory with missing stripes can be accessed"
9432
9433 function t60i_load() {
9434         mkdir $DIR/$tdir
9435         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9436         $LCTL set_param fail_loc=0x131c fail_val=1
9437         for ((i=0; i<5000; i++)); do
9438                 touch $DIR/$tdir/f$i
9439         done
9440 }
9441
9442 test_60i() {
9443         changelog_register || error "changelog_register failed"
9444         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9445         changelog_users $SINGLEMDS | grep -q $cl_user ||
9446                 error "User $cl_user not found in changelog_users"
9447         changelog_chmask "ALL"
9448         t60i_load &
9449         local PID=$!
9450         for((i=0; i<100; i++)); do
9451                 changelog_dump >/dev/null ||
9452                         error "can't read changelog"
9453         done
9454         kill $PID
9455         wait $PID
9456         changelog_deregister || error "changelog_deregister failed"
9457         $LCTL set_param fail_loc=0
9458 }
9459 run_test 60i "llog: new record vs reader race"
9460
9461 test_60j() {
9462         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9463                 skip "need MDS version at least 2.15.50"
9464         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9465         remote_mds_nodsh && skip "remote MDS with nodsh"
9466         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9467
9468         changelog_users $SINGLEMDS | grep "^cl" &&
9469                 skip "active changelog user"
9470
9471         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9472
9473         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9474                 skip_env "missing llog_reader"
9475
9476         mkdir_on_mdt0 $DIR/$tdir
9477
9478         local f=$DIR/$tdir/$tfile
9479         local mdt_dev
9480         local tmpfile
9481         local plain
9482
9483         changelog_register || error "cannot register changelog user"
9484
9485         # set changelog_mask to ALL
9486         changelog_chmask "ALL"
9487         changelog_clear
9488
9489         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9490         unlinkmany ${f}- 100 || error "unlinkmany failed"
9491
9492         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9493         mdt_dev=$(facet_device $SINGLEMDS)
9494
9495         do_facet $SINGLEMDS sync
9496         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9497                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9498                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9499
9500         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9501
9502         # if $tmpfile is not on EXT3 filesystem for some reason
9503         [[ ${plain:0:1} == 'O' ]] ||
9504                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9505
9506         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9507                 $mdt_dev; stat -c %s $tmpfile")
9508         echo "Truncate llog from $size to $((size - size % 8192))"
9509         size=$((size - size % 8192))
9510         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9511         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9512                 grep -c 'in bitmap only')
9513         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9514
9515         size=$((size - 9000))
9516         echo "Corrupt llog in the middle at $size"
9517         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9518                 count=333 conv=notrunc
9519         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9520                 grep -c 'next chunk')
9521         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9522 }
9523 run_test 60j "llog_reader reports corruptions"
9524
9525 test_61a() {
9526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9527
9528         f="$DIR/f61"
9529         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9530         cancel_lru_locks osc
9531         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9532         sync
9533 }
9534 run_test 61a "mmap() writes don't make sync hang ================"
9535
9536 test_61b() {
9537         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9538 }
9539 run_test 61b "mmap() of unstriped file is successful"
9540
9541 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9542 # Though this test is irrelevant anymore, it helped to reveal some
9543 # other grant bugs (LU-4482), let's keep it.
9544 test_63a() {   # was test_63
9545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9546
9547         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9548
9549         for i in `seq 10` ; do
9550                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9551                 sleep 5
9552                 kill $!
9553                 sleep 1
9554         done
9555
9556         rm -f $DIR/f63 || true
9557 }
9558 run_test 63a "Verify oig_wait interruption does not crash ======="
9559
9560 # bug 2248 - async write errors didn't return to application on sync
9561 # bug 3677 - async write errors left page locked
9562 test_63b() {
9563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9564
9565         debugsave
9566         lctl set_param debug=-1
9567
9568         # ensure we have a grant to do async writes
9569         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9570         rm $DIR/$tfile
9571
9572         sync    # sync lest earlier test intercept the fail_loc
9573
9574         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9575         lctl set_param fail_loc=0x80000406
9576         $MULTIOP $DIR/$tfile Owy && \
9577                 error "sync didn't return ENOMEM"
9578         sync; sleep 2; sync     # do a real sync this time to flush page
9579         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9580                 error "locked page left in cache after async error" || true
9581         debugrestore
9582 }
9583 run_test 63b "async write errors should be returned to fsync ==="
9584
9585 test_64a () {
9586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9587
9588         lfs df $DIR
9589         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9590 }
9591 run_test 64a "verify filter grant calculations (in kernel) ====="
9592
9593 test_64b () {
9594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9595
9596         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9597 }
9598 run_test 64b "check out-of-space detection on client"
9599
9600 test_64c() {
9601         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9602 }
9603 run_test 64c "verify grant shrink"
9604
9605 import_param() {
9606         local tgt=$1
9607         local param=$2
9608
9609         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9610 }
9611
9612 # this does exactly what osc_request.c:osc_announce_cached() does in
9613 # order to calculate max amount of grants to ask from server
9614 want_grant() {
9615         local tgt=$1
9616
9617         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9618         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9619
9620         ((rpc_in_flight++));
9621         nrpages=$((nrpages * rpc_in_flight))
9622
9623         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9624
9625         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9626
9627         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9628         local undirty=$((nrpages * PAGE_SIZE))
9629
9630         local max_extent_pages
9631         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9632         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9633         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9634         local grant_extent_tax
9635         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9636
9637         undirty=$((undirty + nrextents * grant_extent_tax))
9638
9639         echo $undirty
9640 }
9641
9642 # this is size of unit for grant allocation. It should be equal to
9643 # what tgt_grant.c:tgt_grant_chunk() calculates
9644 grant_chunk() {
9645         local tgt=$1
9646         local max_brw_size
9647         local grant_extent_tax
9648
9649         max_brw_size=$(import_param $tgt max_brw_size)
9650
9651         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9652
9653         echo $(((max_brw_size + grant_extent_tax) * 2))
9654 }
9655
9656 test_64d() {
9657         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9658                 skip "OST < 2.10.55 doesn't limit grants enough"
9659
9660         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9661
9662         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9663                 skip "no grant_param connect flag"
9664
9665         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9666
9667         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9668         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9669
9670
9671         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9672         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9673
9674         $LFS setstripe $DIR/$tfile -i 0 -c 1
9675         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9676         ddpid=$!
9677
9678         while kill -0 $ddpid; do
9679                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9680
9681                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9682                         kill $ddpid
9683                         error "cur_grant $cur_grant > $max_cur_granted"
9684                 fi
9685
9686                 sleep 1
9687         done
9688 }
9689 run_test 64d "check grant limit exceed"
9690
9691 check_grants() {
9692         local tgt=$1
9693         local expected=$2
9694         local msg=$3
9695         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9696
9697         ((cur_grants == expected)) ||
9698                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9699 }
9700
9701 round_up_p2() {
9702         echo $((($1 + $2 - 1) & ~($2 - 1)))
9703 }
9704
9705 test_64e() {
9706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9707         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9708                 skip "Need OSS version at least 2.11.56"
9709
9710         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9711         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9712         $LCTL set_param debug=+cache
9713
9714         # Remount client to reset grant
9715         remount_client $MOUNT || error "failed to remount client"
9716         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9717
9718         local init_grants=$(import_param $osc_tgt initial_grant)
9719
9720         check_grants $osc_tgt $init_grants "init grants"
9721
9722         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9723         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9724         local gbs=$(import_param $osc_tgt grant_block_size)
9725
9726         # write random number of bytes from max_brw_size / 4 to max_brw_size
9727         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9728         # align for direct io
9729         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9730         # round to grant consumption unit
9731         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9732
9733         local grants=$((wb_round_up + extent_tax))
9734
9735         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9736         stack_trap "rm -f $DIR/$tfile"
9737
9738         # define OBD_FAIL_TGT_NO_GRANT 0x725
9739         # make the server not grant more back
9740         do_facet ost1 $LCTL set_param fail_loc=0x725
9741         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9742
9743         do_facet ost1 $LCTL set_param fail_loc=0
9744
9745         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9746
9747         rm -f $DIR/$tfile || error "rm failed"
9748
9749         # Remount client to reset grant
9750         remount_client $MOUNT || error "failed to remount client"
9751         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9752
9753         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9754
9755         # define OBD_FAIL_TGT_NO_GRANT 0x725
9756         # make the server not grant more back
9757         do_facet ost1 $LCTL set_param fail_loc=0x725
9758         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9759         do_facet ost1 $LCTL set_param fail_loc=0
9760
9761         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9762 }
9763 run_test 64e "check grant consumption (no grant allocation)"
9764
9765 test_64f() {
9766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9767
9768         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9769         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9770         $LCTL set_param debug=+cache
9771
9772         # Remount client to reset grant
9773         remount_client $MOUNT || error "failed to remount client"
9774         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9775
9776         local init_grants=$(import_param $osc_tgt initial_grant)
9777         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9778         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9779         local gbs=$(import_param $osc_tgt grant_block_size)
9780         local chunk=$(grant_chunk $osc_tgt)
9781
9782         # write random number of bytes from max_brw_size / 4 to max_brw_size
9783         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9784         # align for direct io
9785         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9786         # round to grant consumption unit
9787         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9788
9789         local grants=$((wb_round_up + extent_tax))
9790
9791         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9792         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9793                 error "error writing to $DIR/$tfile"
9794
9795         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9796                 "direct io with grant allocation"
9797
9798         rm -f $DIR/$tfile || error "rm failed"
9799
9800         # Remount client to reset grant
9801         remount_client $MOUNT || error "failed to remount client"
9802         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9803
9804         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9805
9806         # Testing that buffered IO consumes grant on the client
9807
9808         # Delay the RPC on the server so it's guaranteed to not complete even
9809         # if the RPC is sent from the client
9810         #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
9811         $LCTL set_param fail_loc=0x50a fail_val=3
9812         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 conv=notrunc ||
9813                 error "error writing to $DIR/$tfile with buffered IO"
9814
9815         check_grants $osc_tgt $((init_grants - grants)) \
9816                 "buffered io, not write rpc"
9817
9818         # Clear the fail loc and do a sync on the client
9819         $LCTL set_param fail_loc=0 fail_val=0
9820         sync
9821
9822         # RPC is now known to have sent
9823         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9824                 "buffered io, one RPC"
9825 }
9826 run_test 64f "check grant consumption (with grant allocation)"
9827
9828 test_64g() {
9829         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9830                 skip "Need MDS version at least 2.14.56"
9831
9832         local mdts=$(comma_list $(mdts_nodes))
9833
9834         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9835                         tr '\n' ' ')
9836         stack_trap "$LCTL set_param $old"
9837
9838         # generate dirty pages and increase dirty granted on MDT
9839         stack_trap "rm -f $DIR/$tfile-*"
9840         for (( i = 0; i < 10; i++)); do
9841                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9842                         error "can't set stripe"
9843                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9844                         error "can't dd"
9845                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9846                         $LFS getstripe $DIR/$tfile-$i
9847                         error "not DoM file"
9848                 }
9849         done
9850
9851         # flush dirty pages
9852         sync
9853
9854         # wait until grant shrink reset grant dirty on MDTs
9855         for ((i = 0; i < 120; i++)); do
9856                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9857                         awk '{sum=sum+$1} END {print sum}')
9858                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9859                 echo "$grant_dirty grants, $vm_dirty pages"
9860                 (( grant_dirty + vm_dirty == 0 )) && break
9861                 (( i == 3 )) && sync &&
9862                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9863                 sleep 1
9864         done
9865
9866         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9867                 awk '{sum=sum+$1} END {print sum}')
9868         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9869 }
9870 run_test 64g "grant shrink on MDT"
9871
9872 test_64h() {
9873         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9874                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9875
9876         local instance=$($LFS getname -i $DIR)
9877         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9878         local num_exps=$(do_facet ost1 \
9879             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9880         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9881         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9882         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9883
9884         # 10MiB is for file to be written, max_brw_size * 16 *
9885         # num_exps is space reserve so that tgt_grant_shrink() decided
9886         # to not shrink
9887         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9888         (( avail * 1024 < expect )) &&
9889                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9890
9891         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9892         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9893         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9894         $LCTL set_param osc.*OST0000*.grant_shrink=1
9895         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9896
9897         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9898         stack_trap "rm -f $DIR/$tfile"
9899         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9900
9901         # drop cache so that coming read would do rpc
9902         cancel_lru_locks osc
9903
9904         # shrink interval is set to 10, pause for 7 seconds so that
9905         # grant thread did not wake up yet but coming read entered
9906         # shrink mode for rpc (osc_should_shrink_grant())
9907         sleep 7
9908
9909         declare -a cur_grant_bytes
9910         declare -a tot_granted
9911         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9912         tot_granted[0]=$(do_facet ost1 \
9913             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9914
9915         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9916
9917         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9918         tot_granted[1]=$(do_facet ost1 \
9919             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9920
9921         # grant change should be equal on both sides
9922         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9923                 tot_granted[0] - tot_granted[1])) ||
9924                 error "grant change mismatch, "                                \
9925                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9926                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9927 }
9928 run_test 64h "grant shrink on read"
9929
9930 test_64i() {
9931         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9932                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9933
9934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9935         remote_ost_nodsh && skip "remote OSTs with nodsh"
9936
9937         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9938         stack_trap "rm -f $DIR/$tfile"
9939
9940         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9941
9942         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9943         local instance=$($LFS getname -i $DIR)
9944
9945         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9946         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9947
9948         # shrink grants and simulate rpc loss
9949         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9950         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9951         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9952
9953         fail ost1
9954
9955         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9956
9957         local testid=$(echo $TESTNAME | tr '_' ' ')
9958
9959         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9960                 grep "GRANT, real grant" &&
9961                 error "client has more grants then it owns" || true
9962 }
9963 run_test 64i "shrink on reconnect"
9964
9965 # bug 1414 - set/get directories' stripe info
9966 test_65a() {
9967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9968
9969         test_mkdir $DIR/$tdir
9970         touch $DIR/$tdir/f1
9971         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9972 }
9973 run_test 65a "directory with no stripe info"
9974
9975 test_65b() {
9976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9977
9978         test_mkdir $DIR/$tdir
9979         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9980
9981         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9982                                                 error "setstripe"
9983         touch $DIR/$tdir/f2
9984         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9985 }
9986 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9987
9988 test_65c() {
9989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9990         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9991
9992         test_mkdir $DIR/$tdir
9993         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9994
9995         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9996                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9997         touch $DIR/$tdir/f3
9998         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9999 }
10000 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
10001
10002 test_65d() {
10003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10004
10005         test_mkdir $DIR/$tdir
10006         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
10007         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10008
10009         if [[ $STRIPECOUNT -le 0 ]]; then
10010                 sc=1
10011         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
10012                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
10013                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
10014         else
10015                 sc=$(($STRIPECOUNT - 1))
10016         fi
10017         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
10018         touch $DIR/$tdir/f4 $DIR/$tdir/f5
10019         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
10020                 error "lverify failed"
10021 }
10022 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
10023
10024 test_65e() {
10025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10026
10027         # LU-16904 delete layout when root is set as PFL layout
10028         save_layout_restore_at_exit $MOUNT
10029         $LFS setstripe -d $MOUNT || error "setstripe failed"
10030
10031         test_mkdir $DIR/$tdir
10032
10033         $LFS setstripe $DIR/$tdir || error "setstripe"
10034         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10035                                         error "no stripe info failed"
10036         touch $DIR/$tdir/f6
10037         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
10038 }
10039 run_test 65e "directory setstripe defaults"
10040
10041 test_65f() {
10042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10043
10044         test_mkdir $DIR/${tdir}f
10045         $RUNAS $LFS setstripe $DIR/${tdir}f &&
10046                 error "setstripe succeeded" || true
10047 }
10048 run_test 65f "dir setstripe permission (should return error) ==="
10049
10050 test_65g() {
10051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10052
10053         # LU-16904 delete layout when root is set as PFL layout
10054         save_layout_restore_at_exit $MOUNT
10055         $LFS setstripe -d $MOUNT || error "setstripe failed"
10056
10057         test_mkdir $DIR/$tdir
10058         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10059
10060         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10061                 error "setstripe -S failed"
10062         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
10063         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
10064                 error "delete default stripe failed"
10065 }
10066 run_test 65g "directory setstripe -d"
10067
10068 test_65h() {
10069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10070
10071         test_mkdir $DIR/$tdir
10072         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
10073
10074         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
10075                 error "setstripe -S failed"
10076         test_mkdir $DIR/$tdir/dd1
10077         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
10078                 error "stripe info inherit failed"
10079 }
10080 run_test 65h "directory stripe info inherit ===================="
10081
10082 test_65i() {
10083         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10084
10085         save_layout_restore_at_exit $MOUNT
10086
10087         # bug6367: set non-default striping on root directory
10088         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
10089
10090         # bug12836: getstripe on -1 default directory striping
10091         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
10092
10093         # bug12836: getstripe -v on -1 default directory striping
10094         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
10095
10096         # bug12836: new find on -1 default directory striping
10097         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
10098 }
10099 run_test 65i "various tests to set root directory striping"
10100
10101 test_65j() { # bug6367
10102         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10103
10104         sync; sleep 1
10105
10106         # if we aren't already remounting for each test, do so for this test
10107         if [ "$I_MOUNTED" = "yes" ]; then
10108                 cleanup || error "failed to unmount"
10109                 setup
10110         fi
10111
10112         save_layout_restore_at_exit $MOUNT
10113
10114         $LFS setstripe -d $MOUNT || error "setstripe failed"
10115 }
10116 run_test 65j "set default striping on root directory (bug 6367)="
10117
10118 cleanup_65k() {
10119         rm -rf $DIR/$tdir
10120         wait_delete_completed
10121         do_facet $SINGLEMDS "lctl set_param -n \
10122                 osp.$ost*MDT0000.max_create_count=$max_count"
10123         do_facet $SINGLEMDS "lctl set_param -n \
10124                 osp.$ost*MDT0000.create_count=$count"
10125         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10126         echo $INACTIVE_OSC "is Activate"
10127
10128         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10129 }
10130
10131 test_65k() { # bug11679
10132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10133         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10134         remote_mds_nodsh && skip "remote MDS with nodsh"
10135
10136         local disable_precreate=true
10137         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
10138                 disable_precreate=false
10139
10140         echo "Check OST status: "
10141         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
10142                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
10143
10144         for OSC in $MDS_OSCS; do
10145                 echo $OSC "is active"
10146                 do_facet $SINGLEMDS lctl --device %$OSC activate
10147         done
10148
10149         for INACTIVE_OSC in $MDS_OSCS; do
10150                 local ost=$(osc_to_ost $INACTIVE_OSC)
10151                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
10152                                lov.*md*.target_obd |
10153                                awk -F: /$ost/'{ print $1 }' | head -n 1)
10154
10155                 mkdir -p $DIR/$tdir
10156                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
10157                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
10158
10159                 echo "Deactivate: " $INACTIVE_OSC
10160                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
10161
10162                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
10163                               osp.$ost*MDT0000.create_count")
10164                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
10165                                   osp.$ost*MDT0000.max_create_count")
10166                 $disable_precreate &&
10167                         do_facet $SINGLEMDS "lctl set_param -n \
10168                                 osp.$ost*MDT0000.max_create_count=0"
10169
10170                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
10171                         [ -f $DIR/$tdir/$idx ] && continue
10172                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
10173                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
10174                                 { cleanup_65k;
10175                                   error "setstripe $idx should succeed"; }
10176                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
10177                 done
10178                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
10179                 rmdir $DIR/$tdir
10180
10181                 do_facet $SINGLEMDS "lctl set_param -n \
10182                         osp.$ost*MDT0000.max_create_count=$max_count"
10183                 do_facet $SINGLEMDS "lctl set_param -n \
10184                         osp.$ost*MDT0000.create_count=$count"
10185                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
10186                 echo $INACTIVE_OSC "is Activate"
10187
10188                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
10189         done
10190 }
10191 run_test 65k "validate manual striping works properly with deactivated OSCs"
10192
10193 test_65l() { # bug 12836
10194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10195
10196         test_mkdir -p $DIR/$tdir/test_dir
10197         $LFS setstripe -c -1 $DIR/$tdir/test_dir
10198         $LFS find -mtime -1 $DIR/$tdir >/dev/null
10199 }
10200 run_test 65l "lfs find on -1 stripe dir ========================"
10201
10202 test_65m() {
10203         local layout=$(save_layout $MOUNT)
10204         $RUNAS $LFS setstripe -c 2 $MOUNT && {
10205                 restore_layout $MOUNT $layout
10206                 error "setstripe should fail by non-root users"
10207         }
10208         true
10209 }
10210 run_test 65m "normal user can't set filesystem default stripe"
10211
10212 test_65n() {
10213         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
10214         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
10215                 skip "Need MDS version at least 2.12.50"
10216         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
10217
10218         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
10219         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
10220         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
10221
10222         save_layout_restore_at_exit $MOUNT
10223
10224         # new subdirectory under root directory should not inherit
10225         # the default layout from root
10226         # LU-16904 check if the root is set as PFL layout
10227         local numcomp=$($LFS getstripe --component-count $MOUNT)
10228
10229         if [[ $numcomp -eq 0 ]]; then
10230                 local dir1=$MOUNT/$tdir-1
10231                 mkdir $dir1 || error "mkdir $dir1 failed"
10232                 ! getfattr -n trusted.lov $dir1 &> /dev/null ||
10233                         error "$dir1 shouldn't have LOV EA"
10234         fi
10235
10236         # delete the default layout on root directory
10237         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
10238
10239         local dir2=$MOUNT/$tdir-2
10240         mkdir $dir2 || error "mkdir $dir2 failed"
10241         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
10242                 error "$dir2 shouldn't have LOV EA"
10243
10244         # set a new striping pattern on root directory
10245         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10246         local new_def_stripe_size=$((def_stripe_size * 2))
10247         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
10248                 error "set stripe size on $MOUNT failed"
10249
10250         # new file created in $dir2 should inherit the new stripe size from
10251         # the filesystem default
10252         local file2=$dir2/$tfile-2
10253         touch $file2 || error "touch $file2 failed"
10254
10255         local file2_stripe_size=$($LFS getstripe -S $file2)
10256         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
10257         {
10258                 echo "file2_stripe_size: '$file2_stripe_size'"
10259                 echo "new_def_stripe_size: '$new_def_stripe_size'"
10260                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
10261         }
10262
10263         local dir3=$MOUNT/$tdir-3
10264         mkdir $dir3 || error "mkdir $dir3 failed"
10265         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
10266         # the root layout, which is the actual default layout that will be used
10267         # when new files are created in $dir3.
10268         local dir3_layout=$(get_layout_param $dir3)
10269         local root_dir_layout=$(get_layout_param $MOUNT)
10270         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
10271         {
10272                 echo "dir3_layout: '$dir3_layout'"
10273                 echo "root_dir_layout: '$root_dir_layout'"
10274                 error "$dir3 should show the default layout from $MOUNT"
10275         }
10276
10277         # set OST pool on root directory
10278         local pool=$TESTNAME
10279         pool_add $pool || error "add $pool failed"
10280         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10281                 error "add targets to $pool failed"
10282
10283         $LFS setstripe -p $pool $MOUNT ||
10284                 error "set OST pool on $MOUNT failed"
10285
10286         # new file created in $dir3 should inherit the pool from
10287         # the filesystem default
10288         local file3=$dir3/$tfile-3
10289         touch $file3 || error "touch $file3 failed"
10290
10291         local file3_pool=$($LFS getstripe -p $file3)
10292         [[ "$file3_pool" = "$pool" ]] ||
10293                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
10294
10295         local dir4=$MOUNT/$tdir-4
10296         mkdir $dir4 || error "mkdir $dir4 failed"
10297         local dir4_layout=$(get_layout_param $dir4)
10298         root_dir_layout=$(get_layout_param $MOUNT)
10299         echo "$LFS getstripe -d $dir4"
10300         $LFS getstripe -d $dir4
10301         echo "$LFS getstripe -d $MOUNT"
10302         $LFS getstripe -d $MOUNT
10303         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
10304         {
10305                 echo "dir4_layout: '$dir4_layout'"
10306                 echo "root_dir_layout: '$root_dir_layout'"
10307                 error "$dir4 should show the default layout from $MOUNT"
10308         }
10309
10310         # new file created in $dir4 should inherit the pool from
10311         # the filesystem default
10312         local file4=$dir4/$tfile-4
10313         touch $file4 || error "touch $file4 failed"
10314
10315         local file4_pool=$($LFS getstripe -p $file4)
10316         [[ "$file4_pool" = "$pool" ]] ||
10317                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
10318
10319         # new subdirectory under non-root directory should inherit
10320         # the default layout from its parent directory
10321         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
10322                 error "set directory layout on $dir4 failed"
10323
10324         local dir5=$dir4/$tdir-5
10325         mkdir $dir5 || error "mkdir $dir5 failed"
10326
10327         dir4_layout=$(get_layout_param $dir4)
10328         local dir5_layout=$(get_layout_param $dir5)
10329         [[ "$dir4_layout" = "$dir5_layout" ]] ||
10330         {
10331                 echo "dir4_layout: '$dir4_layout'"
10332                 echo "dir5_layout: '$dir5_layout'"
10333                 error "$dir5 should inherit the default layout from $dir4"
10334         }
10335
10336         # though subdir under ROOT doesn't inherit default layout, but
10337         # its sub dir/file should be created with default layout.
10338         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10339         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10340                 skip "Need MDS version at least 2.12.59"
10341
10342         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10343         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10344         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10345
10346         if [ $default_lmv_hash == "none" ]; then
10347                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10348         else
10349                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10350                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10351         fi
10352
10353         $LFS setdirstripe -D -c 2 $MOUNT ||
10354                 error "setdirstripe -D -c 2 failed"
10355         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10356         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10357         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10358
10359         # $dir4 layout includes pool
10360         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10361         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10362                 error "pool lost on setstripe"
10363         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10364         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10365                 error "pool lost on compound layout setstripe"
10366 }
10367 run_test 65n "don't inherit default layout from root for new subdirectories"
10368
10369 test_65o() {
10370         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10371                 skip "need MDS version at least 2.14.57"
10372
10373         # set OST pool on root directory
10374         local pool=$TESTNAME
10375
10376         pool_add $pool || error "add $pool failed"
10377         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10378                 error "add targets to $pool failed"
10379
10380         local dir1=$MOUNT/$tdir
10381
10382         mkdir $dir1 || error "mkdir $dir1 failed"
10383
10384         # set a new striping pattern on root directory
10385         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10386
10387         $LFS setstripe -p $pool $dir1 ||
10388                 error "set directory layout on $dir1 failed"
10389
10390         # $dir1 layout includes pool
10391         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10392         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10393                 error "pool lost on setstripe"
10394         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10395         $LFS getstripe $dir1
10396         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10397                 error "pool lost on compound layout setstripe"
10398
10399         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10400                 error "setdirstripe failed on sub-dir with inherited pool"
10401         $LFS getstripe $dir1/dir2
10402         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10403                 error "pool lost on compound layout setdirstripe"
10404
10405         $LFS setstripe -E -1 -c 1 $dir1
10406         $LFS getstripe -d $dir1
10407         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10408                 error "pool lost on setstripe"
10409 }
10410 run_test 65o "pool inheritance for mdt component"
10411
10412 test_65p () { # LU-16152
10413         local src_dir=$DIR/$tdir/src_dir
10414         local dst_dir=$DIR/$tdir/dst_dir
10415         local yaml_file=$DIR/$tdir/layout.yaml
10416         local border
10417
10418         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10419                 skip "Need at least version 2.15.51"
10420
10421         test_mkdir -p $src_dir
10422         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10423                 error "failed to setstripe"
10424         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10425                 error "failed to getstripe"
10426
10427         test_mkdir -p $dst_dir
10428         $LFS setstripe --yaml $yaml_file $dst_dir ||
10429                 error "failed to setstripe with yaml file"
10430         border=$($LFS getstripe -d $dst_dir |
10431                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10432                 error "failed to getstripe"
10433
10434         # 2048M is 0x80000000, or 2147483648
10435         (( $border == 2147483648 )) ||
10436                 error "failed to handle huge number in yaml layout"
10437 }
10438 run_test 65p "setstripe with yaml file and huge number"
10439
10440 test_65p () { # LU-16194
10441         local src_dir=$DIR/$tdir/src_dir
10442
10443         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10444                 skip "Need at least version 2.15.51"
10445
10446         test_mkdir -p $src_dir
10447         # 8E is 0x8000 0000 0000 0000, which is negative as s64
10448         $LFS setstripe -E 8E -c 4 -E EOF -c 8 $src_dir &&
10449                 error "should fail if extent start/end >=8E"
10450
10451         # EOF should work as before
10452         $LFS setstripe -E 8M -c 4 -E EOF -c 8 $src_dir ||
10453                 error "failed to setstripe normally"
10454 }
10455 run_test 65p "setstripe with >=8E offset should fail"
10456
10457 # bug 2543 - update blocks count on client
10458 test_66() {
10459         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10460
10461         local COUNT=${COUNT:-8}
10462         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10463         sync; sync_all_data; sync; sync_all_data
10464         cancel_lru_locks osc
10465         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10466         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10467 }
10468 run_test 66 "update inode blocks count on client ==============="
10469
10470 meminfo() {
10471         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10472 }
10473
10474 swap_used() {
10475         swapon -s | awk '($1 == "'$1'") { print $4 }'
10476 }
10477
10478 # bug5265, obdfilter oa2dentry return -ENOENT
10479 # #define OBD_FAIL_SRV_ENOENT 0x217
10480 test_69() {
10481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10482         remote_ost_nodsh && skip "remote OST with nodsh"
10483
10484         f="$DIR/$tfile"
10485         $LFS setstripe -c 1 -i 0 $f
10486         stack_trap "rm -f $f ${f}.2"
10487
10488         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10489
10490         do_facet ost1 lctl set_param fail_loc=0x217
10491         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10492         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10493
10494         do_facet ost1 lctl set_param fail_loc=0
10495         $DIRECTIO write $f 0 2 || error "write error"
10496
10497         cancel_lru_locks osc
10498         $DIRECTIO read $f 0 1 || error "read error"
10499
10500         do_facet ost1 lctl set_param fail_loc=0x217
10501         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10502
10503         do_facet ost1 lctl set_param fail_loc=0
10504 }
10505 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10506
10507 test_70a() {
10508         # Perform a really simple test of health write and health check
10509         (( $OST1_VERSION >= $(version_code 2.15.59) )) ||
10510                 skip "OSTs < 2.15.59 doesn't have enable_health_write"
10511
10512         local orig_value="$(do_facet ost1 $LCTL get_param -n enable_health_write)"
10513
10514         stack_trap "do_facet ost1 $LCTL set_param enable_health_write $orig_value"
10515
10516         # Test with health write off
10517         do_facet ost1 $LCTL set_param enable_health_write off ||
10518                 error "can't set enable_health_write off"
10519         do_facet ost1 $LCTL get_param enable_health_write ||
10520                 error "can't get enable_health_write"
10521
10522         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10523                 error "not healthy (1)"
10524
10525         # Test with health write on
10526         do_facet ost1 $LCTL set_param enable_health_write on ||
10527                 error "can't set enable_health_write on"
10528         do_facet ost1 $LCTL get_param enable_health_write ||
10529                 error "can't get enable_health_write"
10530
10531         [[ "$(do_facet ost1 $LCTL get_param health_check)" =~ "healthy" ]] ||
10532                 error "not healthy (2)"
10533 }
10534 run_test 70a "verify health_check, health_write don't explode (on OST)"
10535
10536 test_71() {
10537         test_mkdir $DIR/$tdir
10538         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10539         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10540 }
10541 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10542
10543 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10545         [ "$RUNAS_ID" = "$UID" ] &&
10546                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10547         # Check that testing environment is properly set up. Skip if not
10548         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10549                 skip_env "User $RUNAS_ID does not exist - skipping"
10550
10551         touch $DIR/$tfile
10552         chmod 777 $DIR/$tfile
10553         chmod ug+s $DIR/$tfile
10554         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10555                 error "$RUNAS dd $DIR/$tfile failed"
10556         # See if we are still setuid/sgid
10557         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10558                 error "S/gid is not dropped on write"
10559         # Now test that MDS is updated too
10560         cancel_lru_locks mdc
10561         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10562                 error "S/gid is not dropped on MDS"
10563         rm -f $DIR/$tfile
10564 }
10565 run_test 72a "Test that remove suid works properly (bug5695) ===="
10566
10567 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10568         local perm
10569
10570         [ "$RUNAS_ID" = "$UID" ] &&
10571                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10572         [ "$RUNAS_ID" -eq 0 ] &&
10573                 skip_env "RUNAS_ID = 0 -- skipping"
10574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10575         # Check that testing environment is properly set up. Skip if not
10576         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10577                 skip_env "User $RUNAS_ID does not exist - skipping"
10578
10579         touch $DIR/${tfile}-f{g,u}
10580         test_mkdir $DIR/${tfile}-dg
10581         test_mkdir $DIR/${tfile}-du
10582         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10583         chmod g+s $DIR/${tfile}-{f,d}g
10584         chmod u+s $DIR/${tfile}-{f,d}u
10585         for perm in 777 2777 4777; do
10586                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10587                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10588                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10589                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10590         done
10591         true
10592 }
10593 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10594
10595 # bug 3462 - multiple simultaneous MDC requests
10596 test_73() {
10597         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10598
10599         test_mkdir $DIR/d73-1
10600         test_mkdir $DIR/d73-2
10601         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10602         pid1=$!
10603
10604         lctl set_param fail_loc=0x80000129
10605         $MULTIOP $DIR/d73-1/f73-2 Oc &
10606         sleep 1
10607         lctl set_param fail_loc=0
10608
10609         $MULTIOP $DIR/d73-2/f73-3 Oc &
10610         pid3=$!
10611
10612         kill -USR1 $pid1
10613         wait $pid1 || return 1
10614
10615         sleep 25
10616
10617         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10618         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10619         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10620
10621         rm -rf $DIR/d73-*
10622 }
10623 run_test 73 "multiple MDC requests (should not deadlock)"
10624
10625 test_74a() { # bug 6149, 6184
10626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10627
10628         touch $DIR/f74a
10629         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10630         #
10631         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10632         # will spin in a tight reconnection loop
10633         $LCTL set_param fail_loc=0x8000030e
10634         # get any lock that won't be difficult - lookup works.
10635         ls $DIR/f74a
10636         $LCTL set_param fail_loc=0
10637         rm -f $DIR/f74a
10638         true
10639 }
10640 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10641
10642 test_74b() { # bug 13310
10643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10644
10645         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10646         #
10647         # very important to OR with CFS_FAIL_ONCE (0x80000000) -- otherwise it
10648         # will spin in a tight reconnection loop
10649         $LCTL set_param fail_loc=0x8000030e
10650         # get a "difficult" lock
10651         touch $DIR/f74b
10652         $LCTL set_param fail_loc=0
10653         rm -f $DIR/f74b
10654         true
10655 }
10656 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10657
10658 test_74c() {
10659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10660
10661         #define OBD_FAIL_LDLM_NEW_LOCK
10662         $LCTL set_param fail_loc=0x319
10663         touch $DIR/$tfile && error "touch successful"
10664         $LCTL set_param fail_loc=0
10665         true
10666 }
10667 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10668
10669 slab_lic=/sys/kernel/slab/lustre_inode_cache
10670 num_objects() {
10671         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10672         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10673                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10674 }
10675
10676 test_76a() { # Now for b=20433, added originally in b=1443
10677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10678
10679         cancel_lru_locks osc
10680         # there may be some slab objects cached per core
10681         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10682         local before=$(num_objects)
10683         local count=$((512 * cpus))
10684         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10685         local margin=$((count / 10))
10686         if [[ -f $slab_lic/aliases ]]; then
10687                 local aliases=$(cat $slab_lic/aliases)
10688                 (( aliases > 0 )) && margin=$((margin * aliases))
10689         fi
10690
10691         echo "before slab objects: $before"
10692         for i in $(seq $count); do
10693                 touch $DIR/$tfile
10694                 rm -f $DIR/$tfile
10695         done
10696         cancel_lru_locks osc
10697         local after=$(num_objects)
10698         echo "created: $count, after slab objects: $after"
10699         # shared slab counts are not very accurate, allow significant margin
10700         # the main goal is that the cache growth is not permanently > $count
10701         while (( after > before + margin )); do
10702                 sleep 1
10703                 after=$(num_objects)
10704                 wait=$((wait + 1))
10705                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10706                 if (( wait > 60 )); then
10707                         error "inode slab grew from $before+$margin to $after"
10708                 fi
10709         done
10710 }
10711 run_test 76a "confirm clients recycle inodes properly ===="
10712
10713 test_76b() {
10714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10715         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10716
10717         local count=512
10718         local before=$(num_objects)
10719
10720         for i in $(seq $count); do
10721                 mkdir $DIR/$tdir
10722                 rmdir $DIR/$tdir
10723         done
10724
10725         local after=$(num_objects)
10726         local wait=0
10727
10728         while (( after > before )); do
10729                 sleep 1
10730                 after=$(num_objects)
10731                 wait=$((wait + 1))
10732                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10733                 if (( wait > 60 )); then
10734                         error "inode slab grew from $before to $after"
10735                 fi
10736         done
10737
10738         echo "slab objects before: $before, after: $after"
10739 }
10740 run_test 76b "confirm clients recycle directory inodes properly ===="
10741
10742 export ORIG_CSUM=""
10743 set_checksums()
10744 {
10745         # Note: in sptlrpc modes which enable its own bulk checksum, the
10746         # original crc32_le bulk checksum will be automatically disabled,
10747         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10748         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10749         # In this case set_checksums() will not be no-op, because sptlrpc
10750         # bulk checksum will be enabled all through the test.
10751
10752         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10753         lctl set_param -n osc.*.checksums $1
10754         return 0
10755 }
10756
10757 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10758                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10759 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10760                              tr -d [] | head -n1)}
10761 set_checksum_type()
10762 {
10763         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10764         rc=$?
10765         log "set checksum type to $1, rc = $rc"
10766         return $rc
10767 }
10768
10769 get_osc_checksum_type()
10770 {
10771         # arugment 1: OST name, like OST0000
10772         ost=$1
10773         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10774                         sed 's/.*\[\(.*\)\].*/\1/g')
10775         rc=$?
10776         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10777         echo $checksum_type
10778 }
10779
10780 F77_TMP=$TMP/f77-temp
10781 F77SZ=8
10782 setup_f77() {
10783         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10784                 error "error writing to $F77_TMP"
10785 }
10786
10787 test_77a() { # bug 10889
10788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10789         $GSS && skip_env "could not run with gss"
10790
10791         [ ! -f $F77_TMP ] && setup_f77
10792         set_checksums 1
10793         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10794         set_checksums 0
10795         rm -f $DIR/$tfile
10796 }
10797 run_test 77a "normal checksum read/write operation"
10798
10799 test_77b() { # bug 10889
10800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10801         $GSS && skip_env "could not run with gss"
10802
10803         [ ! -f $F77_TMP ] && setup_f77
10804         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10805         $LCTL set_param fail_loc=0x80000409
10806         set_checksums 1
10807
10808         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10809                 error "dd error: $?"
10810         $LCTL set_param fail_loc=0
10811
10812         for algo in $CKSUM_TYPES; do
10813                 cancel_lru_locks osc
10814                 set_checksum_type $algo
10815                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10816                 $LCTL set_param fail_loc=0x80000408
10817                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10818                 $LCTL set_param fail_loc=0
10819         done
10820         set_checksums 0
10821         set_checksum_type $ORIG_CSUM_TYPE
10822         rm -f $DIR/$tfile
10823 }
10824 run_test 77b "checksum error on client write, read"
10825
10826 cleanup_77c() {
10827         trap 0
10828         set_checksums 0
10829         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10830         $check_ost &&
10831                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10832         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10833         $check_ost && [ -n "$ost_file_prefix" ] &&
10834                 do_facet ost1 rm -f ${ost_file_prefix}\*
10835 }
10836
10837 test_77c() {
10838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10839         $GSS && skip_env "could not run with gss"
10840         remote_ost_nodsh && skip "remote OST with nodsh"
10841
10842         local bad1
10843         local osc_file_prefix
10844         local osc_file
10845         local check_ost=false
10846         local ost_file_prefix
10847         local ost_file
10848         local orig_cksum
10849         local dump_cksum
10850         local fid
10851
10852         # ensure corruption will occur on first OSS/OST
10853         $LFS setstripe -i 0 $DIR/$tfile
10854
10855         [ ! -f $F77_TMP ] && setup_f77
10856         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10857                 error "dd write error: $?"
10858         fid=$($LFS path2fid $DIR/$tfile)
10859
10860         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10861         then
10862                 check_ost=true
10863                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10864                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10865         else
10866                 echo "OSS do not support bulk pages dump upon error"
10867         fi
10868
10869         osc_file_prefix=$($LCTL get_param -n debug_path)
10870         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10871
10872         trap cleanup_77c EXIT
10873
10874         set_checksums 1
10875         # enable bulk pages dump upon error on Client
10876         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10877         # enable bulk pages dump upon error on OSS
10878         $check_ost &&
10879                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10880
10881         # flush Client cache to allow next read to reach OSS
10882         cancel_lru_locks osc
10883
10884         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10885         $LCTL set_param fail_loc=0x80000408
10886         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10887         $LCTL set_param fail_loc=0
10888
10889         rm -f $DIR/$tfile
10890
10891         # check cksum dump on Client
10892         osc_file=$(ls ${osc_file_prefix}*)
10893         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10894         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10895         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10896         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10897         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10898                      cksum)
10899         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10900         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10901                 error "dump content does not match on Client"
10902
10903         $check_ost || skip "No need to check cksum dump on OSS"
10904
10905         # check cksum dump on OSS
10906         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10907         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10908         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10909         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10910         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10911                 error "dump content does not match on OSS"
10912
10913         cleanup_77c
10914 }
10915 run_test 77c "checksum error on client read with debug"
10916
10917 test_77d() { # bug 10889
10918         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10919         $GSS && skip_env "could not run with gss"
10920
10921         stack_trap "rm -f $DIR/$tfile"
10922         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10923         $LCTL set_param fail_loc=0x80000409
10924         set_checksums 1
10925         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10926                 error "direct write: rc=$?"
10927         $LCTL set_param fail_loc=0
10928         set_checksums 0
10929
10930         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10931         $LCTL set_param fail_loc=0x80000408
10932         set_checksums 1
10933         cancel_lru_locks osc
10934         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10935                 error "direct read: rc=$?"
10936         $LCTL set_param fail_loc=0
10937         set_checksums 0
10938 }
10939 run_test 77d "checksum error on OST direct write, read"
10940
10941 test_77f() { # bug 10889
10942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10943         $GSS && skip_env "could not run with gss"
10944
10945         set_checksums 1
10946         stack_trap "rm -f $DIR/$tfile"
10947         for algo in $CKSUM_TYPES; do
10948                 cancel_lru_locks osc
10949                 set_checksum_type $algo
10950                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10951                 $LCTL set_param fail_loc=0x409
10952                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10953                         error "direct write succeeded"
10954                 $LCTL set_param fail_loc=0
10955         done
10956         set_checksum_type $ORIG_CSUM_TYPE
10957         set_checksums 0
10958 }
10959 run_test 77f "repeat checksum error on write (expect error)"
10960
10961 test_77g() { # bug 10889
10962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10963         $GSS && skip_env "could not run with gss"
10964         remote_ost_nodsh && skip "remote OST with nodsh"
10965
10966         [ ! -f $F77_TMP ] && setup_f77
10967
10968         local file=$DIR/$tfile
10969         stack_trap "rm -f $file" EXIT
10970
10971         $LFS setstripe -c 1 -i 0 $file
10972         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10973         do_facet ost1 lctl set_param fail_loc=0x8000021a
10974         set_checksums 1
10975         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10976                 error "write error: rc=$?"
10977         do_facet ost1 lctl set_param fail_loc=0
10978         set_checksums 0
10979
10980         cancel_lru_locks osc
10981         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10982         do_facet ost1 lctl set_param fail_loc=0x8000021b
10983         set_checksums 1
10984         cmp $F77_TMP $file || error "file compare failed"
10985         do_facet ost1 lctl set_param fail_loc=0
10986         set_checksums 0
10987 }
10988 run_test 77g "checksum error on OST write, read"
10989
10990 test_77k() { # LU-10906
10991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10992         $GSS && skip_env "could not run with gss"
10993
10994         local cksum_param="osc.$FSNAME*.checksums"
10995         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10996         local checksum
10997         local i
10998
10999         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
11000         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
11001         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
11002
11003         for i in 0 1; do
11004                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
11005                         error "failed to set checksum=$i on MGS"
11006                 wait_update $HOSTNAME "$get_checksum" $i
11007                 #remount
11008                 echo "remount client, checksum should be $i"
11009                 remount_client $MOUNT || error "failed to remount client"
11010                 checksum=$(eval $get_checksum)
11011                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11012         done
11013         # remove persistent param to avoid races with checksum mountopt below
11014         do_facet mgs $LCTL set_param -P -d $cksum_param ||
11015                 error "failed to delete checksum on MGS"
11016
11017         for opt in "checksum" "nochecksum"; do
11018                 #remount with mount option
11019                 echo "remount client with option $opt, checksum should be $i"
11020                 umount_client $MOUNT || error "failed to umount client"
11021                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
11022                         error "failed to mount client with option '$opt'"
11023                 checksum=$(eval $get_checksum)
11024                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
11025                 i=$((i - 1))
11026         done
11027
11028         remount_client $MOUNT || error "failed to remount client"
11029 }
11030 run_test 77k "enable/disable checksum correctly"
11031
11032 test_77l() {
11033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11034         $GSS && skip_env "could not run with gss"
11035
11036         set_checksums 1
11037         stack_trap "set_checksums $ORIG_CSUM" EXIT
11038         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11039
11040         set_checksum_type invalid && error "unexpected success of invalid checksum type"
11041
11042         $LFS setstripe -c 1 -i 0 $DIR/$tfile
11043         for algo in $CKSUM_TYPES; do
11044                 set_checksum_type $algo || error "fail to set checksum type $algo"
11045                 osc_algo=$(get_osc_checksum_type OST0000)
11046                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
11047
11048                 # no locks, no reqs to let the connection idle
11049                 cancel_lru_locks osc
11050                 lru_resize_disable osc
11051                 wait_osc_import_state client ost1 IDLE
11052
11053                 # ensure ost1 is connected
11054                 stat $DIR/$tfile >/dev/null || error "can't stat"
11055                 wait_osc_import_state client ost1 FULL
11056
11057                 osc_algo=$(get_osc_checksum_type OST0000)
11058                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
11059         done
11060         return 0
11061 }
11062 run_test 77l "preferred checksum type is remembered after reconnected"
11063
11064 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
11065 rm -f $F77_TMP
11066 unset F77_TMP
11067
11068 test_77m() {
11069         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
11070                 skip "Need at least version 2.14.52"
11071         local param=checksum_speed
11072
11073         $LCTL get_param $param || error "reading $param failed"
11074
11075         csum_speeds=$($LCTL get_param -n $param)
11076
11077         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
11078                 error "known checksum types are missing"
11079 }
11080 run_test 77m "Verify checksum_speed is correctly read"
11081
11082 check_filefrag_77n() {
11083         local nr_ext=0
11084         local starts=()
11085         local ends=()
11086
11087         while read extidx a b start end rest; do
11088                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
11089                         nr_ext=$(( $nr_ext + 1 ))
11090                         starts+=( ${start%..} )
11091                         ends+=( ${end%:} )
11092                 fi
11093         done < <( filefrag -sv $1 )
11094
11095         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
11096         return 1
11097 }
11098
11099 test_77n() {
11100         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
11101
11102         touch $DIR/$tfile
11103         $TRUNCATE $DIR/$tfile 0
11104         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
11105         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
11106         check_filefrag_77n $DIR/$tfile ||
11107                 skip "$tfile blocks not contiguous around hole"
11108
11109         set_checksums 1
11110         stack_trap "set_checksums $ORIG_CSUM" EXIT
11111         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
11112         stack_trap "rm -f $DIR/$tfile"
11113
11114         for algo in $CKSUM_TYPES; do
11115                 if [[ "$algo" =~ ^t10 ]]; then
11116                         set_checksum_type $algo ||
11117                                 error "fail to set checksum type $algo"
11118                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
11119                                 error "fail to read $tfile with $algo"
11120                 fi
11121         done
11122         rm -f $DIR/$tfile
11123         return 0
11124 }
11125 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
11126
11127 test_77o() {
11128         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
11129                 skip "Need MDS version at least 2.14.55"
11130         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
11131                 skip "Need OST version at least 2.14.55"
11132         local ofd=obdfilter
11133         local mdt=mdt
11134
11135         # print OST checksum_type
11136         echo "$ofd.$FSNAME-*.checksum_type:"
11137         do_nodes $(comma_list $(osts_nodes)) \
11138                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
11139
11140         # print MDT checksum_type
11141         echo "$mdt.$FSNAME-*.checksum_type:"
11142         do_nodes $(comma_list $(mdts_nodes)) \
11143                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
11144
11145         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
11146                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
11147
11148         (( $o_count == $OSTCOUNT )) ||
11149                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
11150
11151         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
11152                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
11153
11154         (( $m_count == $MDSCOUNT )) ||
11155                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
11156 }
11157 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
11158
11159 cleanup_test_78() {
11160         trap 0
11161         rm -f $DIR/$tfile
11162 }
11163
11164 test_78() { # bug 10901
11165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11166         remote_ost || skip_env "local OST"
11167
11168         NSEQ=5
11169         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
11170         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
11171         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
11172         echo "MemTotal: $MEMTOTAL"
11173
11174         # reserve 256MB of memory for the kernel and other running processes,
11175         # and then take 1/2 of the remaining memory for the read/write buffers.
11176         if [ $MEMTOTAL -gt 512 ] ;then
11177                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
11178         else
11179                 # for those poor memory-starved high-end clusters...
11180                 MEMTOTAL=$((MEMTOTAL / 2))
11181         fi
11182         echo "Mem to use for directio: $MEMTOTAL"
11183
11184         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
11185         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
11186         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
11187         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
11188                 head -n1)
11189         echo "Smallest OST: $SMALLESTOST"
11190         [[ $SMALLESTOST -lt 10240 ]] &&
11191                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
11192
11193         trap cleanup_test_78 EXIT
11194
11195         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
11196                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
11197
11198         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
11199         echo "File size: $F78SIZE"
11200         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
11201         for i in $(seq 1 $NSEQ); do
11202                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
11203                 echo directIO rdwr round $i of $NSEQ
11204                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
11205         done
11206
11207         cleanup_test_78
11208 }
11209 run_test 78 "handle large O_DIRECT writes correctly ============"
11210
11211 test_79() { # bug 12743
11212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11213
11214         wait_delete_completed
11215
11216         BKTOTAL=$(calc_osc_kbytes kbytestotal)
11217         BKFREE=$(calc_osc_kbytes kbytesfree)
11218         BKAVAIL=$(calc_osc_kbytes kbytesavail)
11219
11220         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
11221         DFTOTAL=`echo $STRING | cut -d, -f1`
11222         DFUSED=`echo $STRING  | cut -d, -f2`
11223         DFAVAIL=`echo $STRING | cut -d, -f3`
11224         DFFREE=$(($DFTOTAL - $DFUSED))
11225
11226         ALLOWANCE=$((64 * $OSTCOUNT))
11227
11228         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
11229            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
11230                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
11231         fi
11232         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
11233            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
11234                 error "df free($DFFREE) mismatch OST free($BKFREE)"
11235         fi
11236         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
11237            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
11238                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
11239         fi
11240 }
11241 run_test 79 "df report consistency check ======================="
11242
11243 test_80() { # bug 10718
11244         remote_ost_nodsh && skip "remote OST with nodsh"
11245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11246
11247         # relax strong synchronous semantics for slow backends like ZFS
11248         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
11249                 local soc="obdfilter.*.sync_lock_cancel"
11250                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11251
11252                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
11253                 if [ -z "$save" ]; then
11254                         soc="obdfilter.*.sync_on_lock_cancel"
11255                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
11256                 fi
11257
11258                 if [ "$save" != "never" ]; then
11259                         local hosts=$(comma_list $(osts_nodes))
11260
11261                         do_nodes $hosts $LCTL set_param $soc=never
11262                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
11263                 fi
11264         fi
11265
11266         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
11267         sync; sleep 1; sync
11268         local before=$(date +%s)
11269         cancel_lru_locks osc
11270         local after=$(date +%s)
11271         local diff=$((after - before))
11272         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
11273
11274         rm -f $DIR/$tfile
11275 }
11276 run_test 80 "Page eviction is equally fast at high offsets too"
11277
11278 test_81a() { # LU-456
11279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11280         remote_ost_nodsh && skip "remote OST with nodsh"
11281
11282         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11283         # MUST OR with the CFS_FAIL_ONCE (0x80000000)
11284         do_facet ost1 lctl set_param fail_loc=0x80000228
11285
11286         # write should trigger a retry and success
11287         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11288         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11289         RC=$?
11290         if [ $RC -ne 0 ] ; then
11291                 error "write should success, but failed for $RC"
11292         fi
11293 }
11294 run_test 81a "OST should retry write when get -ENOSPC ==============="
11295
11296 test_81b() { # LU-456
11297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11298         remote_ost_nodsh && skip "remote OST with nodsh"
11299
11300         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
11301         # Don't OR with the CFS_FAIL_ONCE (0x80000000)
11302         do_facet ost1 lctl set_param fail_loc=0x228
11303
11304         # write should retry several times and return -ENOSPC finally
11305         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11306         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
11307         RC=$?
11308         ENOSPC=28
11309         if [ $RC -ne $ENOSPC ] ; then
11310                 error "dd should fail for -ENOSPC, but succeed."
11311         fi
11312 }
11313 run_test 81b "OST should return -ENOSPC when retry still fails ======="
11314
11315 test_99() {
11316         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
11317
11318         test_mkdir $DIR/$tdir.cvsroot
11319         chown $RUNAS_ID $DIR/$tdir.cvsroot
11320
11321         cd $TMP
11322         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
11323
11324         cd /etc/init.d
11325         # some versions of cvs import exit(1) when asked to import links or
11326         # files they can't read.  ignore those files.
11327         local toignore=$(find . -type l -printf '-I %f\n' -o \
11328                          ! -perm /4 -printf '-I %f\n')
11329         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
11330                 $tdir.reposname vtag rtag
11331
11332         cd $DIR
11333         test_mkdir $DIR/$tdir.reposname
11334         chown $RUNAS_ID $DIR/$tdir.reposname
11335         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
11336
11337         cd $DIR/$tdir.reposname
11338         $RUNAS touch foo99
11339         $RUNAS cvs add -m 'addmsg' foo99
11340         $RUNAS cvs update
11341         $RUNAS cvs commit -m 'nomsg' foo99
11342         rm -fr $DIR/$tdir.cvsroot
11343 }
11344 run_test 99 "cvs strange file/directory operations"
11345
11346 test_100() {
11347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11348         [[ "$NETTYPE" =~ tcp ]] ||
11349                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
11350         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
11351         remote_ost_nodsh && skip "remote OST with nodsh"
11352         remote_mds_nodsh && skip "remote MDS with nodsh"
11353         remote_servers || skip "useless for local single node setup"
11354
11355         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
11356                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
11357
11358                 rc=0
11359                 if (( ${LOCAL/*:/} >= 1024 )); then
11360                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
11361                         ss -tna
11362                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
11363                 fi
11364         done
11365         (( $rc == 0 )) || error "privileged port not found" )
11366 }
11367 run_test 100 "check local port using privileged port"
11368
11369 function get_named_value()
11370 {
11371     local tag=$1
11372
11373     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
11374 }
11375
11376 test_101a() {
11377         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11378
11379         local s
11380         local discard
11381         local nreads=10000
11382         local cache_limit=32
11383
11384         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11385         $LCTL set_param -n llite.*.read_ahead_stats=0
11386         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
11387                               awk '/^max_cached_mb/ { print $2 }')
11388         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
11389         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11390
11391         #
11392         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11393         #
11394         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11395         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11396
11397         discard=0
11398         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11399                    get_named_value 'read.but.discarded'); do
11400                         discard=$(($discard + $s))
11401         done
11402
11403         $LCTL get_param osc.*-osc*.rpc_stats
11404         $LCTL get_param llite.*.read_ahead_stats
11405
11406         # Discard is generally zero, but sometimes a few random reads line up
11407         # and trigger larger readahead, which is wasted & leads to discards.
11408         if [[ $(($discard)) -gt $nreads ]]; then
11409                 error "too many ($discard) discarded pages"
11410         fi
11411         rm -f $DIR/$tfile || true
11412 }
11413 run_test 101a "check read-ahead for random reads"
11414
11415 setup_test101bc() {
11416         test_mkdir $DIR/$tdir
11417         local ssize=$1
11418         local FILE_LENGTH=$2
11419         STRIPE_OFFSET=0
11420
11421         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11422
11423         local list=$(comma_list $(osts_nodes))
11424         set_osd_param $list '' read_cache_enable 0
11425         set_osd_param $list '' writethrough_cache_enable 0
11426
11427         trap cleanup_test101bc EXIT
11428         # prepare the read-ahead file
11429         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11430
11431         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11432                                 count=$FILE_SIZE_MB 2> /dev/null
11433
11434 }
11435
11436 cleanup_test101bc() {
11437         trap 0
11438         rm -rf $DIR/$tdir
11439         rm -f $DIR/$tfile
11440
11441         local list=$(comma_list $(osts_nodes))
11442         set_osd_param $list '' read_cache_enable 1
11443         set_osd_param $list '' writethrough_cache_enable 1
11444 }
11445
11446 ra_check_101() {
11447         local read_size=$1
11448         local stripe_size=$2
11449         local stride_length=$((stripe_size / read_size))
11450         local stride_width=$((stride_length * OSTCOUNT))
11451         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11452                                 (stride_width - stride_length) ))
11453         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11454                   get_named_value 'read.but.discarded' | calc_sum)
11455
11456         if [[ $discard -gt $discard_limit ]]; then
11457                 $LCTL get_param llite.*.read_ahead_stats
11458                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11459         else
11460                 echo "Read-ahead success for size ${read_size}"
11461         fi
11462 }
11463
11464 test_101b() {
11465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11466         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11467
11468         local STRIPE_SIZE=1048576
11469         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11470
11471         if [ $SLOW == "yes" ]; then
11472                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11473         else
11474                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11475         fi
11476
11477         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11478
11479         # prepare the read-ahead file
11480         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11481         cancel_lru_locks osc
11482         for BIDX in 2 4 8 16 32 64 128 256
11483         do
11484                 local BSIZE=$((BIDX*4096))
11485                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11486                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11487                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11488                 $LCTL set_param -n llite.*.read_ahead_stats=0
11489                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11490                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11491                 cancel_lru_locks osc
11492                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11493         done
11494         cleanup_test101bc
11495         true
11496 }
11497 run_test 101b "check stride-io mode read-ahead ================="
11498
11499 test_101c() {
11500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11501
11502         local STRIPE_SIZE=1048576
11503         local FILE_LENGTH=$((STRIPE_SIZE*100))
11504         local nreads=10000
11505         local rsize=65536
11506         local osc_rpc_stats
11507
11508         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11509
11510         cancel_lru_locks osc
11511         $LCTL set_param osc.*.rpc_stats=0
11512         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11513         $LCTL get_param osc.*.rpc_stats
11514         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11515                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11516                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11517                 local size
11518
11519                 if [ $lines -le 20 ]; then
11520                         echo "continue debug"
11521                         continue
11522                 fi
11523                 for size in 1 2 4 8; do
11524                         local rpc=$(echo "$stats" |
11525                                     awk '($1 == "'$size':") {print $2; exit; }')
11526                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11527                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11528                 done
11529                 echo "$osc_rpc_stats check passed!"
11530         done
11531         cleanup_test101bc
11532         true
11533 }
11534 run_test 101c "check stripe_size aligned read-ahead"
11535
11536 test_101d() {
11537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11538
11539         local file=$DIR/$tfile
11540         local sz_MB=${FILESIZE_101d:-80}
11541         local ra_MB=${READAHEAD_MB:-40}
11542
11543         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11544         [ $free_MB -lt $sz_MB ] &&
11545                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11546
11547         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11548         $LFS setstripe -c -1 $file || error "setstripe failed"
11549
11550         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11551         echo Cancel LRU locks on lustre client to flush the client cache
11552         cancel_lru_locks osc
11553
11554         echo Disable read-ahead
11555         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11556         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11557         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11558         $LCTL get_param -n llite.*.max_read_ahead_mb
11559
11560         echo "Reading the test file $file with read-ahead disabled"
11561         local sz_KB=$((sz_MB * 1024 / 4))
11562         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11563         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11564         # 83886080 bytes (84 MB, 80 MiB) copied, 16 s, 5.2 MB/s
11565         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11566                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11567
11568         echo "Cancel LRU locks on lustre client to flush the client cache"
11569         cancel_lru_locks osc
11570         echo Enable read-ahead with ${ra_MB}MB
11571         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11572
11573         echo "Reading the test file $file with read-ahead enabled"
11574         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11575                       sed -e '/records/d' -e 's/.* \([0-9][0-9\.]*\) *s.*/\1/')
11576
11577         echo "read-ahead disabled time read '$raOFF'"
11578         echo "read-ahead enabled time read '$raON'"
11579
11580         rm -f $file
11581         wait_delete_completed
11582
11583         # use awk for this check instead of bash because it handles decimals
11584         awk "{ exit !($raOFF < 0.5 || $raOFF > $raON) }" <<<"ignore_me" ||
11585                 error "readahead ${raON}s > no-readahead ${raOFF}s (${sz_MB}M)"
11586 }
11587 run_test 101d "file read with and without read-ahead enabled"
11588
11589 test_101e() {
11590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11591
11592         local file=$DIR/$tfile
11593         local size_KB=500  #KB
11594         local count=100
11595         local bsize=1024
11596
11597         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11598         local need_KB=$((count * size_KB))
11599         [[ $free_KB -le $need_KB ]] &&
11600                 skip_env "Need free space $need_KB, have $free_KB"
11601
11602         echo "Creating $count ${size_KB}K test files"
11603         for ((i = 0; i < $count; i++)); do
11604                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11605         done
11606
11607         echo "Cancel LRU locks on lustre client to flush the client cache"
11608         cancel_lru_locks $OSC
11609
11610         echo "Reset readahead stats"
11611         $LCTL set_param -n llite.*.read_ahead_stats=0
11612
11613         for ((i = 0; i < $count; i++)); do
11614                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11615         done
11616
11617         $LCTL get_param llite.*.max_cached_mb
11618         $LCTL get_param llite.*.read_ahead_stats
11619         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11620                      get_named_value 'misses' | calc_sum)
11621
11622         for ((i = 0; i < $count; i++)); do
11623                 rm -rf $file.$i 2>/dev/null
11624         done
11625
11626         #10000 means 20% reads are missing in readahead
11627         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11628 }
11629 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11630
11631 test_101f() {
11632         which iozone || skip_env "no iozone installed"
11633
11634         local old_debug=$($LCTL get_param debug)
11635         old_debug=${old_debug#*=}
11636         $LCTL set_param debug="reada mmap"
11637
11638         # create a test file
11639         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11640
11641         echo Cancel LRU locks on lustre client to flush the client cache
11642         cancel_lru_locks osc
11643
11644         echo Reset readahead stats
11645         $LCTL set_param -n llite.*.read_ahead_stats=0
11646
11647         echo mmap read the file with small block size
11648         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11649                 > /dev/null 2>&1
11650
11651         echo checking missing pages
11652         $LCTL get_param llite.*.read_ahead_stats
11653         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11654                         get_named_value 'misses' | calc_sum)
11655
11656         $LCTL set_param debug="$old_debug"
11657         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11658         rm -f $DIR/$tfile
11659 }
11660 run_test 101f "check mmap read performance"
11661
11662 test_101g_brw_size_test() {
11663         local mb=$1
11664         local pages=$((mb * 1048576 / PAGE_SIZE))
11665         local file=$DIR/$tfile
11666
11667         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11668                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11669         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11670                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11671                         return 2
11672         done
11673
11674         stack_trap "rm -f $file" EXIT
11675         $LCTL set_param -n osc.*.rpc_stats=0
11676
11677         # 10 RPCs should be enough for the test
11678         local count=10
11679         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11680                 { error "dd write ${mb} MB blocks failed"; return 3; }
11681         cancel_lru_locks osc
11682         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11683                 { error "dd write ${mb} MB blocks failed"; return 4; }
11684
11685         # calculate number of full-sized read and write RPCs
11686         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11687                 sed -n '/pages per rpc/,/^$/p' |
11688                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11689                 END { print reads,writes }'))
11690         # allow one extra full-sized read RPC for async readahead
11691         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11692                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11693         [[ ${rpcs[1]} == $count ]] ||
11694                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11695 }
11696
11697 test_101g() {
11698         remote_ost_nodsh && skip "remote OST with nodsh"
11699
11700         local rpcs
11701         local osts=$(get_facets OST)
11702         local list=$(comma_list $(osts_nodes))
11703         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11704         local brw_size="obdfilter.*.brw_size"
11705
11706         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11707
11708         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11709
11710         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11711                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11712                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11713            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11714                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11715                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11716
11717                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11718                         suffix="M"
11719
11720                 if [[ $orig_mb -lt 16 ]]; then
11721                         save_lustre_params $osts "$brw_size" > $p
11722                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11723                                 error "set 16MB RPC size failed"
11724
11725                         echo "remount client to enable new RPC size"
11726                         remount_client $MOUNT || error "remount_client failed"
11727                 fi
11728
11729                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11730                 # should be able to set brw_size=12, but no rpc_stats for that
11731                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11732         fi
11733
11734         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11735
11736         if [[ $orig_mb -lt 16 ]]; then
11737                 restore_lustre_params < $p
11738                 remount_client $MOUNT || error "remount_client restore failed"
11739         fi
11740
11741         rm -f $p $DIR/$tfile
11742 }
11743 run_test 101g "Big bulk(4/16 MiB) readahead"
11744
11745 test_101h() {
11746         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11747
11748         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11749                 error "dd 70M file failed"
11750         echo Cancel LRU locks on lustre client to flush the client cache
11751         cancel_lru_locks osc
11752
11753         echo "Reset readahead stats"
11754         $LCTL set_param -n llite.*.read_ahead_stats 0
11755
11756         echo "Read 10M of data but cross 64M bundary"
11757         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11758         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11759                      get_named_value 'misses' | calc_sum)
11760         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11761         rm -f $p $DIR/$tfile
11762 }
11763 run_test 101h "Readahead should cover current read window"
11764
11765 test_101i() {
11766         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11767                 error "dd 10M file failed"
11768
11769         local max_per_file_mb=$($LCTL get_param -n \
11770                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11771         cancel_lru_locks osc
11772         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11773         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11774                 error "set max_read_ahead_per_file_mb to 1 failed"
11775
11776         echo "Reset readahead stats"
11777         $LCTL set_param llite.*.read_ahead_stats=0
11778
11779         dd if=$DIR/$tfile of=/dev/null bs=2M
11780
11781         $LCTL get_param llite.*.read_ahead_stats
11782         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11783                      awk '/misses/ { print $2 }')
11784         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11785         rm -f $DIR/$tfile
11786 }
11787 run_test 101i "allow current readahead to exceed reservation"
11788
11789 test_101j() {
11790         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11791                 error "setstripe $DIR/$tfile failed"
11792         local file_size=$((1048576 * 16))
11793         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11794         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11795
11796         echo Disable read-ahead
11797         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11798
11799         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11800         for blk in $PAGE_SIZE 1048576 $file_size; do
11801                 cancel_lru_locks osc
11802                 echo "Reset readahead stats"
11803                 $LCTL set_param -n llite.*.read_ahead_stats=0
11804                 local count=$(($file_size / $blk))
11805                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11806                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11807                              get_named_value 'failed.to.fast.read' | calc_sum)
11808                 $LCTL get_param -n llite.*.read_ahead_stats
11809                 [ $miss -eq $count ] || error "expected $count got $miss"
11810         done
11811
11812         rm -f $p $DIR/$tfile
11813 }
11814 run_test 101j "A complete read block should be submitted when no RA"
11815
11816 test_readahead_base() {
11817         local file=$DIR/$tfile
11818         local size=$1
11819         local iosz
11820         local ramax
11821         local ranum
11822
11823         $LCTL set_param -n llite.*.read_ahead_stats=0
11824         # The first page is not accounted into readahead
11825         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11826         iosz=$(((size + 1048575) / 1048576 * 1048576))
11827         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11828
11829         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11830         fallocate -l $size $file || error "failed to fallocate $file"
11831         cancel_lru_locks osc
11832         $MULTIOP $file or${iosz}c || error "failed to read $file"
11833         $LCTL get_param -n llite.*.read_ahead_stats
11834         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11835                 awk '/readahead.pages/ { print $7 }' | calc_sum)
11836         (( $ranum <= $ramax )) ||
11837                 error "read-ahead pages is $ranum more than $ramax"
11838         rm -rf $file || error "failed to remove $file"
11839 }
11840
11841 test_101m()
11842 {
11843         local file=$DIR/$tfile
11844         local ramax
11845         local ranum
11846         local size
11847         local iosz
11848
11849         check_set_fallocate_or_skip
11850         stack_trap "rm -f $file" EXIT
11851
11852         test_readahead_base 4096
11853
11854         # file size: 16K = 16384
11855         test_readahead_base 16384
11856         test_readahead_base 16385
11857         test_readahead_base 16383
11858
11859         # file size: 1M + 1 = 1048576 + 1
11860         test_readahead_base 1048577
11861         # file size: 1M + 16K
11862         test_readahead_base $((1048576 + 16384))
11863
11864         # file size: stripe_size * (stripe_count - 1) + 16K
11865         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11866         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11867         # file size: stripe_size * stripe_count + 16K
11868         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11869         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11870         # file size: 2 * stripe_size * stripe_count + 16K
11871         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11872         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11873 }
11874 run_test 101m "read ahead for small file and last stripe of the file"
11875
11876 setup_test102() {
11877         test_mkdir $DIR/$tdir
11878         chown $RUNAS_ID $DIR/$tdir
11879         STRIPE_SIZE=65536
11880         STRIPE_OFFSET=1
11881         STRIPE_COUNT=$OSTCOUNT
11882         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11883
11884         trap cleanup_test102 EXIT
11885         cd $DIR
11886         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11887         cd $DIR/$tdir
11888         for num in 1 2 3 4; do
11889                 for count in $(seq 1 $STRIPE_COUNT); do
11890                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11891                                 local size=`expr $STRIPE_SIZE \* $num`
11892                                 local file=file"$num-$idx-$count"
11893                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11894                         done
11895                 done
11896         done
11897
11898         cd $DIR
11899         $1 tar cf $TMP/f102.tar $tdir --xattrs
11900 }
11901
11902 cleanup_test102() {
11903         trap 0
11904         rm -f $TMP/f102.tar
11905         rm -rf $DIR/d0.sanity/d102
11906 }
11907
11908 test_102a() {
11909         [ "$UID" != 0 ] && skip "must run as root"
11910         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11911                 skip_env "must have user_xattr"
11912
11913         [ -z "$(which setfattr 2>/dev/null)" ] &&
11914                 skip_env "could not find setfattr"
11915
11916         local testfile=$DIR/$tfile
11917
11918         touch $testfile
11919         echo "set/get xattr..."
11920         setfattr -n trusted.name1 -v value1 $testfile ||
11921                 error "setfattr -n trusted.name1=value1 $testfile failed"
11922         getfattr -n trusted.name1 $testfile 2> /dev/null |
11923           grep "trusted.name1=.value1" ||
11924                 error "$testfile missing trusted.name1=value1"
11925
11926         setfattr -n user.author1 -v author1 $testfile ||
11927                 error "setfattr -n user.author1=author1 $testfile failed"
11928         getfattr -n user.author1 $testfile 2> /dev/null |
11929           grep "user.author1=.author1" ||
11930                 error "$testfile missing trusted.author1=author1"
11931
11932         echo "listxattr..."
11933         setfattr -n trusted.name2 -v value2 $testfile ||
11934                 error "$testfile unable to set trusted.name2"
11935         setfattr -n trusted.name3 -v value3 $testfile ||
11936                 error "$testfile unable to set trusted.name3"
11937         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11938             grep "trusted.name" | wc -l) -eq 3 ] ||
11939                 error "$testfile missing 3 trusted.name xattrs"
11940
11941         setfattr -n user.author2 -v author2 $testfile ||
11942                 error "$testfile unable to set user.author2"
11943         setfattr -n user.author3 -v author3 $testfile ||
11944                 error "$testfile unable to set user.author3"
11945         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11946             grep "user.author" | wc -l) -eq 3 ] ||
11947                 error "$testfile missing 3 user.author xattrs"
11948
11949         echo "remove xattr..."
11950         setfattr -x trusted.name1 $testfile ||
11951                 error "$testfile error deleting trusted.name1"
11952         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11953                 error "$testfile did not delete trusted.name1 xattr"
11954
11955         setfattr -x user.author1 $testfile ||
11956                 error "$testfile error deleting user.author1"
11957         echo "set lustre special xattr ..."
11958         $LFS setstripe -c1 $testfile
11959         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11960                 awk -F "=" '/trusted.lov/ { print $2 }' )
11961         setfattr -n "trusted.lov" -v $lovea $testfile ||
11962                 error "$testfile doesn't ignore setting trusted.lov again"
11963         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11964                 error "$testfile allow setting invalid trusted.lov"
11965         rm -f $testfile
11966 }
11967 run_test 102a "user xattr test =================================="
11968
11969 check_102b_layout() {
11970         local layout="$*"
11971         local testfile=$DIR/$tfile
11972
11973         echo "test layout '$layout'"
11974         $LFS setstripe $layout $testfile || error "setstripe failed"
11975         $LFS getstripe -y $testfile
11976
11977         echo "get/set/list trusted.lov xattr ..." # b=10930
11978         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11979         [[ "$value" =~ "trusted.lov" ]] ||
11980                 error "can't get trusted.lov from $testfile"
11981         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11982                 error "getstripe failed"
11983
11984         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11985
11986         value=$(cut -d= -f2 <<<$value)
11987         # LU-13168: truncated xattr should fail if short lov_user_md header
11988         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11989                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11990         for len in $lens; do
11991                 echo "setfattr $len $testfile.2"
11992                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11993                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11994         done
11995         local stripe_size=$($LFS getstripe -S $testfile.2)
11996         local stripe_count=$($LFS getstripe -c $testfile.2)
11997         [[ $stripe_size -eq 65536 ]] ||
11998                 error "stripe size $stripe_size != 65536"
11999         [[ $stripe_count -eq $stripe_count_orig ]] ||
12000                 error "stripe count $stripe_count != $stripe_count_orig"
12001         rm $testfile $testfile.2
12002 }
12003
12004 test_102b() {
12005         [ -z "$(which setfattr 2>/dev/null)" ] &&
12006                 skip_env "could not find setfattr"
12007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12008
12009         # check plain layout
12010         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
12011
12012         # and also check composite layout
12013         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
12014
12015 }
12016 run_test 102b "getfattr/setfattr for trusted.lov EAs"
12017
12018 test_102c() {
12019         [ -z "$(which setfattr 2>/dev/null)" ] &&
12020                 skip_env "could not find setfattr"
12021         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12022
12023         # b10930: get/set/list lustre.lov xattr
12024         echo "get/set/list lustre.lov xattr ..."
12025         test_mkdir $DIR/$tdir
12026         chown $RUNAS_ID $DIR/$tdir
12027         local testfile=$DIR/$tdir/$tfile
12028         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
12029                 error "setstripe failed"
12030         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
12031                 error "getstripe failed"
12032         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
12033         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
12034
12035         local testfile2=${testfile}2
12036         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
12037                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
12038
12039         $RUNAS $MCREATE $testfile2
12040         $RUNAS setfattr -n lustre.lov -v $value $testfile2
12041         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
12042         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
12043         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
12044         [ $stripe_count -eq $STRIPECOUNT ] ||
12045                 error "stripe count $stripe_count != $STRIPECOUNT"
12046 }
12047 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
12048
12049 compare_stripe_info1() {
12050         local stripe_index_all_zero=true
12051
12052         for num in 1 2 3 4; do
12053                 for count in $(seq 1 $STRIPE_COUNT); do
12054                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
12055                                 local size=$((STRIPE_SIZE * num))
12056                                 local file=file"$num-$offset-$count"
12057                                 stripe_size=$($LFS getstripe -S $PWD/$file)
12058                                 [[ $stripe_size -ne $size ]] &&
12059                                     error "$file: size $stripe_size != $size"
12060                                 stripe_count=$($LFS getstripe -c $PWD/$file)
12061                                 # allow fewer stripes to be created, ORI-601
12062                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
12063                                     error "$file: count $stripe_count != $count"
12064                                 stripe_index=$($LFS getstripe -i $PWD/$file)
12065                                 [[ $stripe_index -ne 0 ]] &&
12066                                         stripe_index_all_zero=false
12067                         done
12068                 done
12069         done
12070         $stripe_index_all_zero &&
12071                 error "all files are being extracted starting from OST index 0"
12072         return 0
12073 }
12074
12075 have_xattrs_include() {
12076         tar --help | grep -q xattrs-include &&
12077                 echo --xattrs-include="lustre.*"
12078 }
12079
12080 test_102d() {
12081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12082         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12083
12084         XINC=$(have_xattrs_include)
12085         setup_test102
12086         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12087         cd $DIR/$tdir/$tdir
12088         compare_stripe_info1
12089 }
12090 run_test 102d "tar restore stripe info from tarfile,not keep osts"
12091
12092 test_102f() {
12093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12095
12096         XINC=$(have_xattrs_include)
12097         setup_test102
12098         test_mkdir $DIR/$tdir.restore
12099         cd $DIR
12100         tar cf - --xattrs $tdir | tar xf - \
12101                 -C $DIR/$tdir.restore --xattrs $XINC
12102         cd $DIR/$tdir.restore/$tdir
12103         compare_stripe_info1
12104 }
12105 run_test 102f "tar copy files, not keep osts"
12106
12107 grow_xattr() {
12108         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
12109                 skip "must have user_xattr"
12110         [ -z "$(which setfattr 2>/dev/null)" ] &&
12111                 skip_env "could not find setfattr"
12112         [ -z "$(which getfattr 2>/dev/null)" ] &&
12113                 skip_env "could not find getfattr"
12114
12115         local xsize=${1:-1024}  # in bytes
12116         local file=$DIR/$tfile
12117         local value="$(generate_string $xsize)"
12118         local xbig=trusted.big
12119         local toobig=$2
12120
12121         touch $file
12122         log "save $xbig on $file"
12123         if [ -z "$toobig" ]
12124         then
12125                 setfattr -n $xbig -v $value $file ||
12126                         error "saving $xbig on $file failed"
12127         else
12128                 setfattr -n $xbig -v $value $file &&
12129                         error "saving $xbig on $file succeeded"
12130                 return 0
12131         fi
12132
12133         local orig=$(get_xattr_value $xbig $file)
12134         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
12135
12136         local xsml=trusted.sml
12137         log "save $xsml on $file"
12138         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
12139
12140         local new=$(get_xattr_value $xbig $file)
12141         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
12142
12143         log "grow $xsml on $file"
12144         setfattr -n $xsml -v "$value" $file ||
12145                 error "growing $xsml on $file failed"
12146
12147         new=$(get_xattr_value $xbig $file)
12148         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
12149         log "$xbig still valid after growing $xsml"
12150
12151         rm -f $file
12152 }
12153
12154 test_102h() { # bug 15777
12155         grow_xattr 1024
12156 }
12157 run_test 102h "grow xattr from inside inode to external block"
12158
12159 test_102ha() {
12160         large_xattr_enabled || skip_env "ea_inode feature disabled"
12161
12162         echo "setting xattr of max xattr size: $(max_xattr_size)"
12163         grow_xattr $(max_xattr_size)
12164
12165         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
12166         echo "This should fail:"
12167         grow_xattr $(($(max_xattr_size) + 10)) 1
12168 }
12169 run_test 102ha "grow xattr from inside inode to external inode"
12170
12171 test_102i() { # bug 17038
12172         [ -z "$(which getfattr 2>/dev/null)" ] &&
12173                 skip "could not find getfattr"
12174
12175         touch $DIR/$tfile
12176         ln -s $DIR/$tfile $DIR/${tfile}link
12177         getfattr -n trusted.lov $DIR/$tfile ||
12178                 error "lgetxattr on $DIR/$tfile failed"
12179         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
12180                 grep -i "no such attr" ||
12181                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
12182         rm -f $DIR/$tfile $DIR/${tfile}link
12183 }
12184 run_test 102i "lgetxattr test on symbolic link ============"
12185
12186 test_102j() {
12187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12188         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12189
12190         XINC=$(have_xattrs_include)
12191         setup_test102 "$RUNAS"
12192         chown $RUNAS_ID $DIR/$tdir
12193         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
12194         cd $DIR/$tdir/$tdir
12195         compare_stripe_info1 "$RUNAS"
12196 }
12197 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
12198
12199 test_102k() {
12200         [ -z "$(which setfattr 2>/dev/null)" ] &&
12201                 skip "could not find setfattr"
12202
12203         touch $DIR/$tfile
12204         # b22187 just check that does not crash for regular file.
12205         setfattr -n trusted.lov $DIR/$tfile
12206         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
12207         local test_kdir=$DIR/$tdir
12208         test_mkdir $test_kdir
12209         local default_size=$($LFS getstripe -S $test_kdir)
12210         local default_count=$($LFS getstripe -c $test_kdir)
12211         local default_offset=$($LFS getstripe -i $test_kdir)
12212         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
12213                 error 'dir setstripe failed'
12214         setfattr -n trusted.lov $test_kdir
12215         local stripe_size=$($LFS getstripe -S $test_kdir)
12216         local stripe_count=$($LFS getstripe -c $test_kdir)
12217         local stripe_offset=$($LFS getstripe -i $test_kdir)
12218         [ $stripe_size -eq $default_size ] ||
12219                 error "stripe size $stripe_size != $default_size"
12220         [ $stripe_count -eq $default_count ] ||
12221                 error "stripe count $stripe_count != $default_count"
12222         [ $stripe_offset -eq $default_offset ] ||
12223                 error "stripe offset $stripe_offset != $default_offset"
12224         rm -rf $DIR/$tfile $test_kdir
12225 }
12226 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
12227
12228 test_102l() {
12229         [ -z "$(which getfattr 2>/dev/null)" ] &&
12230                 skip "could not find getfattr"
12231
12232         # LU-532 trusted. xattr is invisible to non-root
12233         local testfile=$DIR/$tfile
12234
12235         touch $testfile
12236
12237         echo "listxattr as user..."
12238         chown $RUNAS_ID $testfile
12239         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
12240             grep -q "trusted" &&
12241                 error "$testfile trusted xattrs are user visible"
12242
12243         return 0;
12244 }
12245 run_test 102l "listxattr size test =================================="
12246
12247 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
12248         local path=$DIR/$tfile
12249         touch $path
12250
12251         listxattr_size_check $path || error "listattr_size_check $path failed"
12252 }
12253 run_test 102m "Ensure listxattr fails on small bufffer ========"
12254
12255 cleanup_test102
12256
12257 getxattr() { # getxattr path name
12258         # Return the base64 encoding of the value of xattr name on path.
12259         local path=$1
12260         local name=$2
12261
12262         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
12263         # file: $path
12264         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12265         #
12266         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
12267
12268         getfattr --absolute-names --encoding=base64 --name=$name $path |
12269                 awk -F= -v name=$name '$1 == name {
12270                         print substr($0, index($0, "=") + 1);
12271         }'
12272 }
12273
12274 test_102n() { # LU-4101 mdt: protect internal xattrs
12275         [ -z "$(which setfattr 2>/dev/null)" ] &&
12276                 skip "could not find setfattr"
12277         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
12278         then
12279                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
12280         fi
12281
12282         local file0=$DIR/$tfile.0
12283         local file1=$DIR/$tfile.1
12284         local xattr0=$TMP/$tfile.0
12285         local xattr1=$TMP/$tfile.1
12286         local namelist="lov lma lmv link fid version som hsm"
12287         local name
12288         local value
12289
12290         rm -rf $file0 $file1 $xattr0 $xattr1
12291         touch $file0 $file1
12292
12293         # Get 'before' xattrs of $file1.
12294         getfattr --absolute-names --dump --match=- $file1 > $xattr0
12295
12296         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
12297                 namelist+=" lfsck_namespace"
12298         for name in $namelist; do
12299                 # Try to copy xattr from $file0 to $file1.
12300                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12301
12302                 setfattr --name=trusted.$name --value="$value" $file1 ||
12303                         error "setxattr 'trusted.$name' failed"
12304
12305                 # Try to set a garbage xattr.
12306                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12307
12308                 if [[ x$name == "xlov" ]]; then
12309                         setfattr --name=trusted.lov --value="$value" $file1 &&
12310                         error "setxattr invalid 'trusted.lov' success"
12311                 else
12312                         setfattr --name=trusted.$name --value="$value" $file1 ||
12313                                 error "setxattr invalid 'trusted.$name' failed"
12314                 fi
12315
12316                 # Try to remove the xattr from $file1. We don't care if this
12317                 # appears to succeed or fail, we just don't want there to be
12318                 # any changes or crashes.
12319                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12320         done
12321
12322         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
12323         then
12324                 name="lfsck_ns"
12325                 # Try to copy xattr from $file0 to $file1.
12326                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
12327
12328                 setfattr --name=trusted.$name --value="$value" $file1 ||
12329                         error "setxattr 'trusted.$name' failed"
12330
12331                 # Try to set a garbage xattr.
12332                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
12333
12334                 setfattr --name=trusted.$name --value="$value" $file1 ||
12335                         error "setxattr 'trusted.$name' failed"
12336
12337                 # Try to remove the xattr from $file1. We don't care if this
12338                 # appears to succeed or fail, we just don't want there to be
12339                 # any changes or crashes.
12340                 setfattr --remove=$trusted.$name $file1 2> /dev/null
12341         fi
12342
12343         # Get 'after' xattrs of file1.
12344         getfattr --absolute-names --dump --match=- $file1 > $xattr1
12345
12346         if ! diff $xattr0 $xattr1; then
12347                 error "before and after xattrs of '$file1' differ"
12348         fi
12349
12350         rm -rf $file0 $file1 $xattr0 $xattr1
12351
12352         return 0
12353 }
12354 run_test 102n "silently ignore setxattr on internal trusted xattrs"
12355
12356 test_102p() { # LU-4703 setxattr did not check ownership
12357         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
12358                 skip "MDS needs to be at least 2.5.56"
12359
12360         local testfile=$DIR/$tfile
12361
12362         touch $testfile
12363
12364         echo "setfacl as user..."
12365         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
12366         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
12367
12368         echo "setfattr as user..."
12369         setfacl -m "u:$RUNAS_ID:---" $testfile
12370         $RUNAS setfattr -x system.posix_acl_access $testfile
12371         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
12372 }
12373 run_test 102p "check setxattr(2) correctly fails without permission"
12374
12375 test_102q() {
12376         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12377                 skip "MDS needs to be at least 2.6.92"
12378
12379         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12380 }
12381 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12382
12383 test_102r() {
12384         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12385                 skip "MDS needs to be at least 2.6.93"
12386
12387         touch $DIR/$tfile || error "touch"
12388         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12389         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12390         rm $DIR/$tfile || error "rm"
12391
12392         #normal directory
12393         mkdir -p $DIR/$tdir || error "mkdir"
12394         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12395         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12396         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12397                 error "$testfile error deleting user.author1"
12398         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12399                 grep "user.$(basename $tdir)" &&
12400                 error "$tdir did not delete user.$(basename $tdir)"
12401         rmdir $DIR/$tdir || error "rmdir"
12402
12403         #striped directory
12404         test_mkdir $DIR/$tdir
12405         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12406         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12407         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12408                 error "$testfile error deleting user.author1"
12409         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12410                 grep "user.$(basename $tdir)" &&
12411                 error "$tdir did not delete user.$(basename $tdir)"
12412         rmdir $DIR/$tdir || error "rm striped dir"
12413 }
12414 run_test 102r "set EAs with empty values"
12415
12416 test_102s() {
12417         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12418                 skip "MDS needs to be at least 2.11.52"
12419
12420         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12421
12422         save_lustre_params client "llite.*.xattr_cache" > $save
12423
12424         for cache in 0 1; do
12425                 lctl set_param llite.*.xattr_cache=$cache
12426
12427                 rm -f $DIR/$tfile
12428                 touch $DIR/$tfile || error "touch"
12429                 for prefix in lustre security system trusted user; do
12430                         # Note getxattr() may fail with 'Operation not
12431                         # supported' or 'No such attribute' depending
12432                         # on prefix and cache.
12433                         getfattr -n $prefix.n102s $DIR/$tfile &&
12434                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12435                 done
12436         done
12437
12438         restore_lustre_params < $save
12439 }
12440 run_test 102s "getting nonexistent xattrs should fail"
12441
12442 test_102t() {
12443         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12444                 skip "MDS needs to be at least 2.11.52"
12445
12446         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12447
12448         save_lustre_params client "llite.*.xattr_cache" > $save
12449
12450         for cache in 0 1; do
12451                 lctl set_param llite.*.xattr_cache=$cache
12452
12453                 for buf_size in 0 256; do
12454                         rm -f $DIR/$tfile
12455                         touch $DIR/$tfile || error "touch"
12456                         setfattr -n user.multiop $DIR/$tfile
12457                         $MULTIOP $DIR/$tfile oa$buf_size ||
12458                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12459                 done
12460         done
12461
12462         restore_lustre_params < $save
12463 }
12464 run_test 102t "zero length xattr values handled correctly"
12465
12466 run_acl_subtest()
12467 {
12468         local test=$LUSTRE/tests/acl/$1.test
12469         local tmp=$(mktemp -t $1-XXXXXX).test
12470         local bin=$2
12471         local dmn=$3
12472         local grp=$4
12473         local nbd=$5
12474         export LANG=C
12475
12476
12477         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12478         local sedgroups="-e s/:users/:$grp/g"
12479         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12480
12481         sed $sedusers $sedgroups < $test > $tmp
12482         stack_trap "rm -f $tmp"
12483         [[ -s $tmp ]] || error "sed failed to create test script"
12484
12485         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12486         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12487 }
12488
12489 test_103a() {
12490         [ "$UID" != 0 ] && skip "must run as root"
12491         $GSS && skip_env "could not run under gss"
12492         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12493                 skip_env "must have acl enabled"
12494         which setfacl || skip_env "could not find setfacl"
12495         remote_mds_nodsh && skip "remote MDS with nodsh"
12496
12497         local mdts=$(comma_list $(mdts_nodes))
12498         local saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
12499
12500         [[ -z "$saved" ]] || do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE
12501         stack_trap "[[ -z \"$saved\" ]] || \
12502                     do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$saved" EXIT
12503
12504         ACLBIN=${ACLBIN:-"bin"}
12505         ACLDMN=${ACLDMN:-"daemon"}
12506         ACLGRP=${ACLGRP:-"users"}
12507         ACLNBD=${ACLNBD:-"nobody"}
12508
12509         if ! id $ACLBIN ||
12510            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12511                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12512                 ACLBIN=$USER0
12513                 if ! id $ACLBIN ; then
12514                         cat /etc/passwd
12515                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12516                 fi
12517         fi
12518         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12519            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12520                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12521                 ACLDMN=$USER1
12522                 if ! id $ACLDMN ; then
12523                         cat /etc/passwd
12524                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12525                 fi
12526         fi
12527         if ! getent group $ACLGRP; then
12528                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12529                 ACLGRP="$TSTUSR"
12530                 if ! getent group $ACLGRP; then
12531                         echo "cannot find group '$ACLGRP', adding it"
12532                         cat /etc/group
12533                         add_group 60000 $ACLGRP
12534                 fi
12535         fi
12536
12537         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12538         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12539         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12540
12541         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12542                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12543                 ACLGRP="$TSTUSR"
12544                 if ! getent group $ACLGRP; then
12545                         echo "cannot find group '$ACLGRP', adding it"
12546                         cat /etc/group
12547                         add_group 60000 $ACLGRP
12548                 fi
12549                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12550                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12551                         cat /etc/group
12552                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12553                 fi
12554         fi
12555
12556         gpasswd -a $ACLDMN $ACLBIN ||
12557                 error "setting client group failed"             # LU-5641
12558         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12559                 error "setting MDS group failed"                # LU-5641
12560
12561         declare -a identity_old
12562
12563         for ((num = 1; num <= $MDSCOUNT; num++)); do
12564                 switch_identity $num true || identity_old[$num]=$?
12565         done
12566
12567         SAVE_UMASK=$(umask)
12568         umask 0022
12569         mkdir -p $DIR/$tdir
12570         cd $DIR/$tdir
12571
12572         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12573         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12574         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12575         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12576         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12577         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12578         if ! id -u $ACLNBD ||
12579            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12580                 ACLNBD="nfsnobody"
12581                 if ! id -u $ACLNBD; then
12582                         ACLNBD=""
12583                 fi
12584         fi
12585         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12586                 add_group $(id -u $ACLNBD) $ACLNBD
12587                 if ! getent group $ACLNBD; then
12588                         ACLNBD=""
12589                 fi
12590         fi
12591         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12592            [[ -n "$ACLNBD" ]] && which setfattr; then
12593                 run_acl_subtest permissions_xattr \
12594                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12595         elif [[ -z "$ACLNBD" ]]; then
12596                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12597         else
12598                 echo "skip 'permission_xattr' test - missing setfattr command"
12599         fi
12600         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12601
12602         # inheritance test got from HP
12603         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12604         chmod +x make-tree || error "chmod +x failed"
12605         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12606         rm -f make-tree
12607
12608         echo "LU-974 ignore umask when acl is enabled..."
12609         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12610         if [ $MDSCOUNT -ge 2 ]; then
12611                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12612         fi
12613
12614         echo "LU-2561 newly created file is same size as directory..."
12615         if [ "$mds1_FSTYPE" != "zfs" ]; then
12616                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12617         else
12618                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12619         fi
12620
12621         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12622
12623         cd $SAVE_PWD
12624         umask $SAVE_UMASK
12625
12626         for ((num = 1; num <= $MDSCOUNT; num++)); do
12627                 if [[ "${identity_old[$num]}" == 1 ]]; then
12628                         switch_identity $num false || identity_old[$num]=$?
12629                 fi
12630         done
12631 }
12632 run_test 103a "acl test"
12633
12634 test_103b() {
12635         declare -a pids
12636         local U
12637
12638         stack_trap "rm -f $DIR/$tfile.*"
12639         for U in {0..511}; do
12640                 {
12641                 local O=$(printf "%04o" $U)
12642
12643                 umask $(printf "%04o" $((511 ^ $O)))
12644                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12645                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12646
12647                 (( $S == ($O & 0666) )) ||
12648                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12649
12650                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12651                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12652                 (( $S == ($O & 0666) )) ||
12653                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12654
12655                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12656                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12657                 (( $S == ($O & 0666) )) ||
12658                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12659                 rm -f $DIR/$tfile.[smp]$0
12660                 } &
12661                 local pid=$!
12662
12663                 # limit the concurrently running threads to 64. LU-11878
12664                 local idx=$((U % 64))
12665                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12666                 pids[idx]=$pid
12667         done
12668         wait
12669 }
12670 run_test 103b "umask lfs setstripe"
12671
12672 test_103c() {
12673         mkdir -p $DIR/$tdir
12674         cp -rp $DIR/$tdir $DIR/$tdir.bak
12675
12676         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12677                 error "$DIR/$tdir shouldn't contain default ACL"
12678         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12679                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12680         true
12681 }
12682 run_test 103c "'cp -rp' won't set empty acl"
12683
12684 test_103e() {
12685         local numacl
12686         local fileacl
12687         local saved_debug=$($LCTL get_param -n debug)
12688
12689         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12690                 skip "MDS needs to be at least 2.14.52"
12691
12692         large_xattr_enabled || skip_env "ea_inode feature disabled"
12693
12694         mkdir -p $DIR/$tdir
12695         # add big LOV EA to cause reply buffer overflow earlier
12696         $LFS setstripe -C 1000 $DIR/$tdir
12697         lctl set_param mdc.*-mdc*.stats=clear
12698
12699         $LCTL set_param debug=0
12700         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12701         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12702
12703         # add a large number of default ACLs (expect 8000+ for 2.13+)
12704         for U in {2..7000}; do
12705                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12706                         error "Able to add just $U default ACLs"
12707         done
12708         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12709         echo "$numacl default ACLs created"
12710
12711         stat $DIR/$tdir || error "Cannot stat directory"
12712         # check file creation
12713         touch $DIR/$tdir/$tfile ||
12714                 error "failed to create $tfile with $numacl default ACLs"
12715         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12716         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12717         echo "$fileacl ACLs were inherited"
12718         (( $fileacl == $numacl )) ||
12719                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12720         # check that new ACLs creation adds new ACLs to inherited ACLs
12721         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12722                 error "Cannot set new ACL"
12723         numacl=$((numacl + 1))
12724         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12725         (( $fileacl == $numacl )) ||
12726                 error "failed to add new ACL: $fileacl != $numacl as expected"
12727         # adds more ACLs to a file to reach their maximum at 8000+
12728         numacl=0
12729         for U in {20000..25000}; do
12730                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12731                 numacl=$((numacl + 1))
12732         done
12733         echo "Added $numacl more ACLs to the file"
12734         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12735         echo "Total $fileacl ACLs in file"
12736         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12737         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12738         rmdir $DIR/$tdir || error "Cannot remove directory"
12739 }
12740 run_test 103e "inheritance of big amount of default ACLs"
12741
12742 test_103f() {
12743         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12744                 skip "MDS needs to be at least 2.14.51"
12745
12746         large_xattr_enabled || skip_env "ea_inode feature disabled"
12747
12748         # enable changelog to consume more internal MDD buffers
12749         changelog_register
12750
12751         mkdir -p $DIR/$tdir
12752         # add big LOV EA
12753         $LFS setstripe -C 1000 $DIR/$tdir
12754         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12755         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12756         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12757         rmdir $DIR/$tdir || error "Cannot remove directory"
12758 }
12759 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12760
12761 test_104a() {
12762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12763
12764         touch $DIR/$tfile
12765         lfs df || error "lfs df failed"
12766         lfs df -ih || error "lfs df -ih failed"
12767         lfs df -h $DIR || error "lfs df -h $DIR failed"
12768         lfs df -i $DIR || error "lfs df -i $DIR failed"
12769         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12770         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12771
12772         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12773         lctl --device %$OSC deactivate
12774         lfs df || error "lfs df with deactivated OSC failed"
12775         lctl --device %$OSC activate
12776         # wait the osc back to normal
12777         wait_osc_import_ready client ost
12778
12779         lfs df || error "lfs df with reactivated OSC failed"
12780         rm -f $DIR/$tfile
12781 }
12782 run_test 104a "lfs df [-ih] [path] test ========================="
12783
12784 test_104b() {
12785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12786         [ $RUNAS_ID -eq $UID ] &&
12787                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12788
12789         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12790                         grep "Permission denied" | wc -l)))
12791         if [ $denied_cnt -ne 0 ]; then
12792                 error "lfs check servers test failed"
12793         fi
12794 }
12795 run_test 104b "$RUNAS lfs check servers test ===================="
12796
12797 #
12798 # Verify $1 is within range of $2.
12799 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12800 # $1 is <= 2% of $2. Else Fail.
12801 #
12802 value_in_range() {
12803         # Strip all units (M, G, T)
12804         actual=$(echo $1 | tr -d A-Z)
12805         expect=$(echo $2 | tr -d A-Z)
12806
12807         expect_lo=$(($expect * 98 / 100)) # 2% below
12808         expect_hi=$(($expect * 102 / 100)) # 2% above
12809
12810         # permit 2% drift above and below
12811         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12812 }
12813
12814 test_104c() {
12815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12816         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12817
12818         local ost_param="osd-zfs.$FSNAME-OST0000."
12819         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12820         local ofacets=$(get_facets OST)
12821         local mfacets=$(get_facets MDS)
12822         local saved_ost_blocks=
12823         local saved_mdt_blocks=
12824
12825         echo "Before recordsize change"
12826         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12827         df=($(df -h | grep "$MOUNT"$))
12828
12829         # For checking.
12830         echo "lfs output : ${lfs_df[*]}"
12831         echo "df  output : ${df[*]}"
12832
12833         for facet in ${ofacets//,/ }; do
12834                 if [ -z $saved_ost_blocks ]; then
12835                         saved_ost_blocks=$(do_facet $facet \
12836                                 lctl get_param -n $ost_param.blocksize)
12837                         echo "OST Blocksize: $saved_ost_blocks"
12838                 fi
12839                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12840                 do_facet $facet zfs set recordsize=32768 $ost
12841         done
12842
12843         # BS too small. Sufficient for functional testing.
12844         for facet in ${mfacets//,/ }; do
12845                 if [ -z $saved_mdt_blocks ]; then
12846                         saved_mdt_blocks=$(do_facet $facet \
12847                                 lctl get_param -n $mdt_param.blocksize)
12848                         echo "MDT Blocksize: $saved_mdt_blocks"
12849                 fi
12850                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12851                 do_facet $facet zfs set recordsize=32768 $mdt
12852         done
12853
12854         # Give new values chance to reflect change
12855         sleep 2
12856
12857         echo "After recordsize change"
12858         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12859         df_after=($(df -h | grep "$MOUNT"$))
12860
12861         # For checking.
12862         echo "lfs output : ${lfs_df_after[*]}"
12863         echo "df  output : ${df_after[*]}"
12864
12865         # Verify lfs df
12866         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12867                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12868         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12869                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12870         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12871                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12872
12873         # Verify df
12874         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12875                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12876         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12877                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12878         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12879                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12880
12881         # Restore MDT recordize back to original
12882         for facet in ${mfacets//,/ }; do
12883                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12884                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12885         done
12886
12887         # Restore OST recordize back to original
12888         for facet in ${ofacets//,/ }; do
12889                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12890                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12891         done
12892
12893         return 0
12894 }
12895 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12896
12897 test_104d() {
12898         (( $RUNAS_ID != $UID )) ||
12899                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12900
12901         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12902                 skip "lustre version doesn't support lctl dl with non-root"
12903
12904         # debugfs only allows root users to access files, so the
12905         # previous move of the "devices" file to debugfs broke
12906         # "lctl dl" for non-root users. The LU-9680 Netlink
12907         # interface again allows non-root users to list devices.
12908         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12909                 error "lctl dl doesn't work for non root"
12910
12911         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12912         [ "$ost_count" -eq $OSTCOUNT ]  ||
12913                 error "lctl dl reports wrong number of OST devices"
12914
12915         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12916         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12917                 error "lctl dl reports wrong number of MDT devices"
12918 }
12919 run_test 104d "$RUNAS lctl dl test"
12920
12921 test_105a() {
12922         # doesn't work on 2.4 kernels
12923         touch $DIR/$tfile
12924         if $(flock_is_enabled); then
12925                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12926         else
12927                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12928         fi
12929         rm -f $DIR/$tfile
12930 }
12931 run_test 105a "flock when mounted without -o flock test ========"
12932
12933 test_105b() {
12934         touch $DIR/$tfile
12935         if $(flock_is_enabled); then
12936                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12937         else
12938                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12939         fi
12940         rm -f $DIR/$tfile
12941 }
12942 run_test 105b "fcntl when mounted without -o flock test ========"
12943
12944 test_105c() {
12945         touch $DIR/$tfile
12946         if $(flock_is_enabled); then
12947                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12948         else
12949                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12950         fi
12951         rm -f $DIR/$tfile
12952 }
12953 run_test 105c "lockf when mounted without -o flock test"
12954
12955 test_105d() { # bug 15924
12956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12957
12958         test_mkdir $DIR/$tdir
12959         flock_is_enabled || skip_env "mount w/o flock enabled"
12960         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12961         $LCTL set_param fail_loc=0x80000315
12962         flocks_test 2 $DIR/$tdir
12963 }
12964 run_test 105d "flock race (should not freeze) ========"
12965
12966 test_105e() { # bug 22660 && 22040
12967         flock_is_enabled || skip_env "mount w/o flock enabled"
12968
12969         touch $DIR/$tfile
12970         flocks_test 3 $DIR/$tfile
12971 }
12972 run_test 105e "Two conflicting flocks from same process"
12973
12974 test_106() { #bug 10921
12975         test_mkdir $DIR/$tdir
12976         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12977         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12978 }
12979 run_test 106 "attempt exec of dir followed by chown of that dir"
12980
12981 test_107() {
12982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12983
12984         CDIR=`pwd`
12985         local file=core
12986
12987         cd $DIR
12988         rm -f $file
12989
12990         local save_pattern=$(sysctl -n kernel.core_pattern)
12991         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12992         sysctl -w kernel.core_pattern=$file
12993         sysctl -w kernel.core_uses_pid=0
12994
12995         ulimit -c unlimited
12996         sleep 60 &
12997         SLEEPPID=$!
12998
12999         sleep 1
13000
13001         kill -s 11 $SLEEPPID
13002         wait $SLEEPPID
13003         if [ -e $file ]; then
13004                 size=`stat -c%s $file`
13005                 [ $size -eq 0 ] && error "Fail to create core file $file"
13006         else
13007                 error "Fail to create core file $file"
13008         fi
13009         rm -f $file
13010         sysctl -w kernel.core_pattern=$save_pattern
13011         sysctl -w kernel.core_uses_pid=$save_uses_pid
13012         cd $CDIR
13013 }
13014 run_test 107 "Coredump on SIG"
13015
13016 test_110() {
13017         test_mkdir $DIR/$tdir
13018         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
13019         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
13020                 error "mkdir with 256 char should fail, but did not"
13021         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
13022                 error "create with 255 char failed"
13023         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
13024                 error "create with 256 char should fail, but did not"
13025
13026         ls -l $DIR/$tdir
13027         rm -rf $DIR/$tdir
13028 }
13029 run_test 110 "filename length checking"
13030
13031 test_116a() { # was previously test_116()
13032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13033         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13034         remote_mds_nodsh && skip "remote MDS with nodsh"
13035
13036         echo -n "Free space priority "
13037         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
13038                 head -n1
13039         declare -a AVAIL
13040         free_min_max
13041
13042         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
13043         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
13044         stack_trap simple_cleanup_common
13045
13046         # Check if we need to generate uneven OSTs
13047         test_mkdir -p $DIR/$tdir/OST${MINI}
13048         local FILL=$((MINV / 4))
13049         local DIFF=$((MAXV - MINV))
13050         local DIFF2=$((DIFF * 100 / MINV))
13051
13052         local threshold=$(do_facet $SINGLEMDS \
13053                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
13054         threshold=${threshold%%%}
13055         echo -n "Check for uneven OSTs: "
13056         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
13057
13058         if [[ $DIFF2 -gt $threshold ]]; then
13059                 echo "ok"
13060                 echo "Don't need to fill OST$MINI"
13061         else
13062                 # generate uneven OSTs. Write 2% over the QOS threshold value
13063                 echo "no"
13064                 DIFF=$((threshold - DIFF2 + 2))
13065                 DIFF2=$((MINV * DIFF / 100))
13066                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
13067                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
13068                         error "setstripe failed"
13069                 DIFF=$((DIFF2 / 2048))
13070                 i=0
13071                 while [ $i -lt $DIFF ]; do
13072                         i=$((i + 1))
13073                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
13074                                 bs=2M count=1 2>/dev/null
13075                         echo -n .
13076                 done
13077                 echo .
13078                 sync
13079                 sleep_maxage
13080                 free_min_max
13081         fi
13082
13083         DIFF=$((MAXV - MINV))
13084         DIFF2=$((DIFF * 100 / MINV))
13085         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
13086         if [ $DIFF2 -gt $threshold ]; then
13087                 echo "ok"
13088         else
13089                 skip "QOS imbalance criteria not met"
13090         fi
13091
13092         MINI1=$MINI
13093         MINV1=$MINV
13094         MAXI1=$MAXI
13095         MAXV1=$MAXV
13096
13097         # now fill using QOS
13098         $LFS setstripe -c 1 $DIR/$tdir
13099         FILL=$((FILL / 200))
13100         if [ $FILL -gt 600 ]; then
13101                 FILL=600
13102         fi
13103         echo "writing $FILL files to QOS-assigned OSTs"
13104         i=0
13105         while [ $i -lt $FILL ]; do
13106                 i=$((i + 1))
13107                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
13108                         count=1 2>/dev/null
13109                 echo -n .
13110         done
13111         echo "wrote $i 200k files"
13112         sync
13113         sleep_maxage
13114
13115         echo "Note: free space may not be updated, so measurements might be off"
13116         free_min_max
13117         DIFF2=$((MAXV - MINV))
13118         echo "free space delta: orig $DIFF final $DIFF2"
13119         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
13120         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
13121         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
13122         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
13123         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
13124         if [[ $DIFF -gt 0 ]]; then
13125                 FILL=$((DIFF2 * 100 / DIFF - 100))
13126                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
13127         fi
13128
13129         # Figure out which files were written where
13130         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13131                awk '/'$MINI1': / {print $2; exit}')
13132         echo $UUID
13133         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13134         echo "$MINC files created on smaller OST $MINI1"
13135         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
13136                awk '/'$MAXI1': / {print $2; exit}')
13137         echo $UUID
13138         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
13139         echo "$MAXC files created on larger OST $MAXI1"
13140         if [[ $MINC -gt 0 ]]; then
13141                 FILL=$((MAXC * 100 / MINC - 100))
13142                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
13143         fi
13144         [[ $MAXC -gt $MINC ]] ||
13145                 error_ignore LU-9 "stripe QOS didn't balance free space"
13146 }
13147 run_test 116a "stripe QOS: free space balance ==================="
13148
13149 test_116b() { # LU-2093
13150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13151         remote_mds_nodsh && skip "remote MDS with nodsh"
13152
13153 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
13154         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
13155                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
13156         [ -z "$old_rr" ] && skip "no QOS"
13157         do_facet $SINGLEMDS lctl set_param \
13158                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
13159         mkdir -p $DIR/$tdir
13160         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
13161         createmany -o $DIR/$tdir/f- 20 || error "can't create"
13162         do_facet $SINGLEMDS lctl set_param fail_loc=0
13163         rm -rf $DIR/$tdir
13164         do_facet $SINGLEMDS lctl set_param \
13165                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
13166 }
13167 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
13168
13169 test_117() # bug 10891
13170 {
13171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13172
13173         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
13174         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
13175         lctl set_param fail_loc=0x21e
13176         > $DIR/$tfile || error "truncate failed"
13177         lctl set_param fail_loc=0
13178         echo "Truncate succeeded."
13179         rm -f $DIR/$tfile
13180 }
13181 run_test 117 "verify osd extend =========="
13182
13183 NO_SLOW_RESENDCOUNT=4
13184 export OLD_RESENDCOUNT=""
13185 set_resend_count () {
13186         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
13187         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
13188         lctl set_param -n $PROC_RESENDCOUNT $1
13189         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
13190 }
13191
13192 # for reduce test_118* time (b=14842)
13193 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13194
13195 # Reset async IO behavior after error case
13196 reset_async() {
13197         FILE=$DIR/reset_async
13198
13199         # Ensure all OSCs are cleared
13200         $LFS setstripe -c -1 $FILE
13201         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
13202         sync
13203         rm $FILE
13204 }
13205
13206 test_118a() #bug 11710
13207 {
13208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13209
13210         reset_async
13211
13212         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13213         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13214         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13215
13216         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13217                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13218                 return 1;
13219         fi
13220         rm -f $DIR/$tfile
13221 }
13222 run_test 118a "verify O_SYNC works =========="
13223
13224 test_118b()
13225 {
13226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13227         remote_ost_nodsh && skip "remote OST with nodsh"
13228
13229         reset_async
13230
13231         #define OBD_FAIL_SRV_ENOENT 0x217
13232         set_nodes_failloc "$(osts_nodes)" 0x217
13233         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13234         RC=$?
13235         set_nodes_failloc "$(osts_nodes)" 0
13236         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13237         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13238                     grep -c writeback)
13239
13240         if [[ $RC -eq 0 ]]; then
13241                 error "Must return error due to dropped pages, rc=$RC"
13242                 return 1;
13243         fi
13244
13245         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13246                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13247                 return 1;
13248         fi
13249
13250         echo "Dirty pages not leaked on ENOENT"
13251
13252         # Due to the above error the OSC will issue all RPCs syncronously
13253         # until a subsequent RPC completes successfully without error.
13254         $MULTIOP $DIR/$tfile Ow4096yc
13255         rm -f $DIR/$tfile
13256
13257         return 0
13258 }
13259 run_test 118b "Reclaim dirty pages on fatal error =========="
13260
13261 test_118c()
13262 {
13263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13264
13265         # for 118c, restore the original resend count, LU-1940
13266         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
13267                                 set_resend_count $OLD_RESENDCOUNT
13268         remote_ost_nodsh && skip "remote OST with nodsh"
13269
13270         reset_async
13271
13272         #define OBD_FAIL_OST_EROFS               0x216
13273         set_nodes_failloc "$(osts_nodes)" 0x216
13274
13275         # multiop should block due to fsync until pages are written
13276         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13277         MULTIPID=$!
13278         sleep 1
13279
13280         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13281                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13282         fi
13283
13284         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13285                     grep -c writeback)
13286         if [[ $WRITEBACK -eq 0 ]]; then
13287                 error "No page in writeback, writeback=$WRITEBACK"
13288         fi
13289
13290         set_nodes_failloc "$(osts_nodes)" 0
13291         wait $MULTIPID
13292         RC=$?
13293         if [[ $RC -ne 0 ]]; then
13294                 error "Multiop fsync failed, rc=$RC"
13295         fi
13296
13297         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13298         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13299                     grep -c writeback)
13300         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13301                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13302         fi
13303
13304         rm -f $DIR/$tfile
13305         echo "Dirty pages flushed via fsync on EROFS"
13306         return 0
13307 }
13308 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
13309
13310 # continue to use small resend count to reduce test_118* time (b=14842)
13311 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
13312
13313 test_118d()
13314 {
13315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13316         remote_ost_nodsh && skip "remote OST with nodsh"
13317
13318         reset_async
13319
13320         #define OBD_FAIL_OST_BRW_PAUSE_BULK
13321         set_nodes_failloc "$(osts_nodes)" 0x214
13322         # multiop should block due to fsync until pages are written
13323         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13324         MULTIPID=$!
13325         sleep 1
13326
13327         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
13328                 error "Multiop failed to block on fsync, pid=$MULTIPID"
13329         fi
13330
13331         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13332                     grep -c writeback)
13333         if [[ $WRITEBACK -eq 0 ]]; then
13334                 error "No page in writeback, writeback=$WRITEBACK"
13335         fi
13336
13337         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
13338         set_nodes_failloc "$(osts_nodes)" 0
13339
13340         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13341         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13342                     grep -c writeback)
13343         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13344                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13345         fi
13346
13347         rm -f $DIR/$tfile
13348         echo "Dirty pages gaurenteed flushed via fsync"
13349         return 0
13350 }
13351 run_test 118d "Fsync validation inject a delay of the bulk =========="
13352
13353 test_118f() {
13354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13355
13356         reset_async
13357
13358         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
13359         lctl set_param fail_loc=0x8000040a
13360
13361         # Should simulate EINVAL error which is fatal
13362         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13363         RC=$?
13364         if [[ $RC -eq 0 ]]; then
13365                 error "Must return error due to dropped pages, rc=$RC"
13366         fi
13367
13368         lctl set_param fail_loc=0x0
13369
13370         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13371         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13372         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13373                     grep -c writeback)
13374         if [[ $LOCKED -ne 0 ]]; then
13375                 error "Locked pages remain in cache, locked=$LOCKED"
13376         fi
13377
13378         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13379                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13380         fi
13381
13382         rm -f $DIR/$tfile
13383         echo "No pages locked after fsync"
13384
13385         reset_async
13386         return 0
13387 }
13388 run_test 118f "Simulate unrecoverable OSC side error =========="
13389
13390 test_118g() {
13391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13392
13393         reset_async
13394
13395         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13396         lctl set_param fail_loc=0x406
13397
13398         # simulate local -ENOMEM
13399         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13400         RC=$?
13401
13402         lctl set_param fail_loc=0
13403         if [[ $RC -eq 0 ]]; then
13404                 error "Must return error due to dropped pages, rc=$RC"
13405         fi
13406
13407         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13408         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13409         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13410                         grep -c writeback)
13411         if [[ $LOCKED -ne 0 ]]; then
13412                 error "Locked pages remain in cache, locked=$LOCKED"
13413         fi
13414
13415         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13416                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13417         fi
13418
13419         rm -f $DIR/$tfile
13420         echo "No pages locked after fsync"
13421
13422         reset_async
13423         return 0
13424 }
13425 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13426
13427 test_118h() {
13428         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13429         remote_ost_nodsh && skip "remote OST with nodsh"
13430
13431         reset_async
13432
13433         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13434         set_nodes_failloc "$(osts_nodes)" 0x20e
13435         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13436         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13437         RC=$?
13438
13439         set_nodes_failloc "$(osts_nodes)" 0
13440         if [[ $RC -eq 0 ]]; then
13441                 error "Must return error due to dropped pages, rc=$RC"
13442         fi
13443
13444         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13445         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13446         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13447                     grep -c writeback)
13448         if [[ $LOCKED -ne 0 ]]; then
13449                 error "Locked pages remain in cache, locked=$LOCKED"
13450         fi
13451
13452         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13453                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13454         fi
13455
13456         rm -f $DIR/$tfile
13457         echo "No pages locked after fsync"
13458
13459         return 0
13460 }
13461 run_test 118h "Verify timeout in handling recoverables errors  =========="
13462
13463 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13464
13465 test_118i() {
13466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13467         remote_ost_nodsh && skip "remote OST with nodsh"
13468
13469         reset_async
13470
13471         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13472         set_nodes_failloc "$(osts_nodes)" 0x20e
13473
13474         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13475         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13476         PID=$!
13477         sleep 5
13478         set_nodes_failloc "$(osts_nodes)" 0
13479
13480         wait $PID
13481         RC=$?
13482         if [[ $RC -ne 0 ]]; then
13483                 error "got error, but should be not, rc=$RC"
13484         fi
13485
13486         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13487         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13488         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13489         if [[ $LOCKED -ne 0 ]]; then
13490                 error "Locked pages remain in cache, locked=$LOCKED"
13491         fi
13492
13493         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13494                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13495         fi
13496
13497         rm -f $DIR/$tfile
13498         echo "No pages locked after fsync"
13499
13500         return 0
13501 }
13502 run_test 118i "Fix error before timeout in recoverable error  =========="
13503
13504 [ "$SLOW" = "no" ] && set_resend_count 4
13505
13506 test_118j() {
13507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13508         remote_ost_nodsh && skip "remote OST with nodsh"
13509
13510         reset_async
13511
13512         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13513         set_nodes_failloc "$(osts_nodes)" 0x220
13514
13515         # return -EIO from OST
13516         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13517         RC=$?
13518         set_nodes_failloc "$(osts_nodes)" 0x0
13519         if [[ $RC -eq 0 ]]; then
13520                 error "Must return error due to dropped pages, rc=$RC"
13521         fi
13522
13523         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13524         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13525         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13526         if [[ $LOCKED -ne 0 ]]; then
13527                 error "Locked pages remain in cache, locked=$LOCKED"
13528         fi
13529
13530         # in recoverable error on OST we want resend and stay until it finished
13531         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13532                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13533         fi
13534
13535         rm -f $DIR/$tfile
13536         echo "No pages locked after fsync"
13537
13538         return 0
13539 }
13540 run_test 118j "Simulate unrecoverable OST side error =========="
13541
13542 test_118k()
13543 {
13544         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13545         remote_ost_nodsh && skip "remote OSTs with nodsh"
13546
13547         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13548         set_nodes_failloc "$(osts_nodes)" 0x20e
13549         test_mkdir $DIR/$tdir
13550
13551         for ((i=0;i<10;i++)); do
13552                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13553                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13554                 SLEEPPID=$!
13555                 sleep 0.500s
13556                 kill $SLEEPPID
13557                 wait $SLEEPPID
13558         done
13559
13560         set_nodes_failloc "$(osts_nodes)" 0
13561         rm -rf $DIR/$tdir
13562 }
13563 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13564
13565 test_118l() # LU-646
13566 {
13567         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13568
13569         test_mkdir $DIR/$tdir
13570         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13571         rm -rf $DIR/$tdir
13572 }
13573 run_test 118l "fsync dir"
13574
13575 test_118m() # LU-3066
13576 {
13577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13578
13579         test_mkdir $DIR/$tdir
13580         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13581         rm -rf $DIR/$tdir
13582 }
13583 run_test 118m "fdatasync dir ========="
13584
13585 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13586
13587 test_118n()
13588 {
13589         local begin
13590         local end
13591
13592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13593         remote_ost_nodsh && skip "remote OSTs with nodsh"
13594
13595         # Sleep to avoid a cached response.
13596         #define OBD_STATFS_CACHE_SECONDS 1
13597         sleep 2
13598
13599         # Inject a 10 second delay in the OST_STATFS handler.
13600         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13601         set_nodes_failloc "$(osts_nodes)" 0x242
13602
13603         begin=$SECONDS
13604         stat --file-system $MOUNT > /dev/null
13605         end=$SECONDS
13606
13607         set_nodes_failloc "$(osts_nodes)" 0
13608
13609         if ((end - begin > 20)); then
13610             error "statfs took $((end - begin)) seconds, expected 10"
13611         fi
13612 }
13613 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13614
13615 test_119a() # bug 11737
13616 {
13617         BSIZE=$((512 * 1024))
13618         directio write $DIR/$tfile 0 1 $BSIZE
13619         # We ask to read two blocks, which is more than a file size.
13620         # directio will indicate an error when requested and actual
13621         # sizes aren't equeal (a normal situation in this case) and
13622         # print actual read amount.
13623         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13624         if [ "$NOB" != "$BSIZE" ]; then
13625                 error "read $NOB bytes instead of $BSIZE"
13626         fi
13627         rm -f $DIR/$tfile
13628 }
13629 run_test 119a "Short directIO read must return actual read amount"
13630
13631 test_119b() # bug 11737
13632 {
13633         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13634
13635         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13636         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13637         sync
13638         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13639                 error "direct read failed"
13640         rm -f $DIR/$tfile
13641 }
13642 run_test 119b "Sparse directIO read must return actual read amount"
13643
13644 test_119c() # bug 13099
13645 {
13646         BSIZE=1048576
13647         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13648         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13649         rm -f $DIR/$tfile
13650 }
13651 run_test 119c "Testing for direct read hitting hole"
13652
13653 # Note: test 119d was removed, skipping 119d for new tests to avoid polluting
13654 # Maloo test history
13655
13656 test_119e()
13657 {
13658         (( $MDS1_VERSION >= $(version_code 2.15.58) )) ||
13659                 skip "Need server version at least 2.15.58"
13660         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13661
13662         local stripe_size=$((1024 * 1024)) #1 MiB
13663         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13664         local file_size=$((25 * stripe_size))
13665         local bsizes
13666
13667         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13668         stack_trap "rm -f $DIR/$tfile*"
13669
13670         # Just a bit bigger than the largest size in the test set below
13671         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13672                 error "buffered i/o to create file failed"
13673
13674         # trivial test of unaligned DIO
13675         dd if=$DIR/$tfile.1 bs=4095 of=$DIR/$tfile.2 count=4 \
13676                 iflag=direct oflag=direct ||
13677                 error "trivial unaligned dio failed"
13678
13679         # Test of disabling unaligned DIO support
13680         $LCTL set_param llite.*.unaligned_dio=0
13681         stack_trap "$LCTL set_param llite.*.unaligned_dio=1"
13682         echo "testing disabling unaligned DIO - 'invalid argument' expected:"
13683         dd if=$DIR/$tfile.1 bs=1024 of=$DIR/$tfile.2 count=4 \
13684                 iflag=direct oflag=direct &&
13685                 error "unaligned dio succeeded when disabled"
13686         $LCTL set_param llite.*.unaligned_dio=1
13687
13688         # Clean up before next part of test
13689         rm -f $DIR/$tfile.2
13690
13691         if zfs_or_rotational; then
13692                 # DIO on ZFS can take up to 2 seconds per IO
13693                 # rotational is better, but still slow.
13694                 # Limit testing on those media to larger sizes
13695                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13696                         $((stripe_size + 1024))"
13697         else
13698                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13699                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13700                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13701                         $((stripe_size - 1)) $stripe_size \
13702                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13703                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13704         fi
13705
13706         for bs in $bsizes; do
13707                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13708                 echo "Read/write with DIO at size $bs"
13709                 # Read and write with DIO from source to dest
13710                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 \
13711                         iflag=direct oflag=direct ||
13712                         error "dio failed"
13713
13714                 ls -la $DIR/$tfile.1 $DIR/$tfile.2
13715                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13716                         error "size incorrect, file copy read/write bsize: $bs"
13717                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13718                         error "files differ, bsize $bs"
13719                 rm -f $DIR/$tfile.2
13720         done
13721 }
13722 run_test 119e "Basic tests of dio read and write at various sizes"
13723
13724 test_119f()
13725 {
13726         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13727
13728         local stripe_size=$((1024 * 1024)) #1 MiB
13729         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13730         local file_size=$((25 * stripe_size))
13731         local bsizes
13732
13733         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13734         stack_trap "rm -f $DIR/$tfile*"
13735
13736         # Just a bit bigger than the largest size in the test set below
13737         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13738                 error "buffered i/o to create file failed"
13739
13740         if zfs_or_rotational; then
13741                 # DIO on ZFS can take up to 2 seconds per IO
13742                 # rotational is better, but still slow.
13743                 # Limit testing on those media to larger sizes
13744                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13745                         $((stripe_size + 1024))"
13746         else
13747                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13748                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13749                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13750                         $((stripe_size - 1)) $stripe_size \
13751                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13752                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13753         fi
13754
13755         for bs in $bsizes; do
13756                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13757                 # Read and write with DIO from source to dest in two
13758                 # threads - should give correct copy of file
13759
13760                 echo "bs: $bs"
13761                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13762                         oflag=direct conv=notrunc &
13763                 pid_dio1=$!
13764                 # Note block size is different here for a more interesting race
13765                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
13766                         iflag=direct oflag=direct conv=notrunc &
13767                 pid_dio2=$!
13768                 wait $pid_dio1
13769                 rc1=$?
13770                 wait $pid_dio2
13771                 rc2=$?
13772                 if (( rc1 != 0 )); then
13773                         error "dio copy 1 w/bsize $bs failed: $rc1"
13774                 fi
13775                 if (( rc2 != 0 )); then
13776                         error "dio copy 2 w/bsize $bs failed: $rc2"
13777                 fi
13778
13779
13780                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13781                         error "size incorrect, file copy read/write bsize: $bs"
13782                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13783                         error "files differ, bsize $bs"
13784                 rm -f $DIR/$tfile.2
13785         done
13786 }
13787 run_test 119f "dio vs dio race"
13788
13789 test_119g()
13790 {
13791         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13792
13793         local stripe_size=$((1024 * 1024)) #1 MiB
13794         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13795         local file_size=$((25 * stripe_size))
13796         local bsizes
13797
13798         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13799         stack_trap "rm -f $DIR/$tfile*"
13800
13801         # Just a bit bigger than the largest size in the test set below
13802         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13803                 error "buffered i/o to create file failed"
13804
13805         if zfs_or_rotational; then
13806                 # DIO on ZFS can take up to 2 seconds per IO
13807                 # rotational is better, but still slow.
13808                 # Limit testing on those media to larger sizes
13809                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13810                         $((stripe_size + 1024))"
13811         else
13812                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13813                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13814                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13815                         $((stripe_size - 1)) $stripe_size \
13816                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13817                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13818         fi
13819
13820         for bs in $bsizes; do
13821                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13822                 echo "bs: $bs"
13823                 dd if=$DIR/$tfile.1 bs=$bs of=$DIR/$tfile.2 iflag=direct \
13824                         oflag=direct conv=notrunc &
13825                 pid_dio1=$!
13826                 # Buffered I/O with similar but not the same block size
13827                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 &
13828                 pid_bio2=$!
13829                 wait $pid_dio1
13830                 rc1=$?
13831                 wait $pid_bio2
13832                 rc2=$?
13833                 if (( rc1 != 0 )); then
13834                         error "dio copy 1 w/bsize $bs failed: $rc1"
13835                 fi
13836                 if (( rc2 != 0 )); then
13837                         error "buffered copy 2 w/bsize $bs failed: $rc2"
13838                 fi
13839
13840                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13841                         error "size incorrect"
13842                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13843                         error "files differ, bsize $bs"
13844                 rm -f $DIR/$tfile.2
13845         done
13846 }
13847 run_test 119g "dio vs buffered I/O race"
13848
13849 test_119h()
13850 {
13851         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13852
13853         local stripe_size=$((1024 * 1024)) #1 MiB
13854         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13855         local file_size=$((25 * stripe_size))
13856         local bsizes
13857
13858         stack_trap "rm -f $DIR/$tfile.*"
13859
13860         if zfs_or_rotational; then
13861                 # DIO on ZFS can take up to 2 seconds per IO
13862                 # rotational is better, but still slow.
13863                 # Limit testing on those media to larger sizes
13864                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13865                         $((stripe_size + 1024))"
13866         else
13867                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13868                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13869                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13870                         $((stripe_size - 1)) $stripe_size \
13871                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13872                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13873         fi
13874
13875         for bs in $bsizes; do
13876                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13877                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13878                 echo "unaligned writes of blocksize: $bs"
13879                 # Write a file with unaligned DIO and regular DIO, and compare
13880                 # them
13881                 # with 'u', multiop randomly unaligns the io from the buffer
13882                 $MULTIOP $DIR/$tfile.1 \
13883                 oO_CREAT:O_RDWR:O_DIRECT:wu${bs}wu${bs}wu${bs}wu${bs}wu${bs} ||
13884                         error "multiop memory unaligned write failed, $bs"
13885                 $MULTIOP $DIR/$tfile.2 \
13886                 oO_CREAT:O_RDWR:O_DIRECT:w${bs}w${bs}w${bs}w${bs}w${bs} ||
13887                         error "multiop memory aligned write failed, $bs"
13888
13889                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13890                         error "files differ, bsize $bs"
13891                 rm -f $DIR/$tfile.*
13892         done
13893
13894         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13895         dd if=/dev/zero bs=$((stripe_size * 5)) of=$DIR/$tfile.1 count=5 ||
13896                 error "dd to create source file for read failed"
13897
13898         # Just a few quick tests to make sure unaligned DIO reads don't crash
13899         for bs in $bsizes; do
13900
13901                 echo "unaligned reads of blocksize: $bs"
13902                 # with 'u', multiop randomly unaligns the io from the buffer
13903                 $MULTIOP $DIR/$tfile.1 \
13904                 oO_CREAT:O_RDWR:O_DIRECT:ru${bs}ru${bs}ru${bs}ru${bs}ru${bs} ||
13905                         error "multiop memory unaligned read failed, $bs"
13906
13907         done
13908         rm -f $DIR/$tfile*
13909 }
13910 run_test 119h "basic tests of memory unaligned dio"
13911
13912 # aiocp with the '-a' option makes testing memory unaligned aio trivial
13913 test_119i()
13914 {
13915         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
13916         which aiocp || skip_env "no aiocp installed"
13917
13918         local stripe_size=$((1024 * 1024)) #1 MiB
13919         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
13920         local file_size=$((25 * stripe_size))
13921         local bsizes
13922
13923         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
13924         stack_trap "rm -f $DIR/$tfile.*"
13925
13926         # Just a bit bigger than the largest size in the test set below
13927         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
13928                 error "buffered i/o to create file failed"
13929
13930         if zfs_or_rotational; then
13931                 # DIO on ZFS can take up to 2 seconds per IO
13932                 # rotational is better, but still slow.
13933                 # Limit testing on those media to larger sizes
13934                 bsizes="$((stripe_size - PAGE_SIZE)) $stripe_size \
13935                         $((stripe_size + 1024))"
13936         else
13937                 bsizes="$((PAGE_SIZE / 4)) $((PAGE_SIZE - 1024)) \
13938                         $((PAGE_SIZE - 1)) $PAGE_SIZE $((PAGE_SIZE + 1024)) \
13939                         $((PAGE_SIZE * 3/2)) $((PAGE_SIZE * 4)) \
13940                         $((stripe_size - 1)) $stripe_size \
13941                         $((stripe_size + 1)) $((stripe_size * 3/2)) \
13942                         $((stripe_size * 4)) $((stripe_size * 4 + 1))"
13943         fi
13944
13945         # Do page aligned and NOT page aligned AIO
13946         for align in 8 512 $((PAGE_SIZE)); do
13947         # Deliberately includes a few aligned sizes
13948         for bs in $bsizes; do
13949                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
13950
13951                 echo "bs: $bs, align: $align, file_size $file_size"
13952                 aiocp -a $align -b $bs -s $file_size -f O_DIRECT \
13953                         $DIR/$tfile.1 $DIR/$tfile.2 ||
13954                         error "unaligned aio failed, bs: $bs, align: $align"
13955
13956                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
13957                         error "size incorrect"
13958                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
13959                         error "files differ"
13960                 rm -f $DIR/$tfile.2
13961         done
13962         done
13963 }
13964 run_test 119i "test unaligned aio at varying sizes"
13965
13966 test_120a() {
13967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13968         remote_mds_nodsh && skip "remote MDS with nodsh"
13969         test_mkdir -i0 -c1 $DIR/$tdir
13970         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13971                 skip_env "no early lock cancel on server"
13972
13973         lru_resize_disable mdc
13974         lru_resize_disable osc
13975         cancel_lru_locks mdc
13976         # asynchronous object destroy at MDT could cause bl ast to client
13977         cancel_lru_locks osc
13978
13979         stat $DIR/$tdir > /dev/null
13980         can1=$(do_facet mds1 \
13981                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13982                awk '/ldlm_cancel/ {print $2}')
13983         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13984                awk '/ldlm_bl_callback/ {print $2}')
13985         test_mkdir -i0 -c1 $DIR/$tdir/d1
13986         can2=$(do_facet mds1 \
13987                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13988                awk '/ldlm_cancel/ {print $2}')
13989         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13990                awk '/ldlm_bl_callback/ {print $2}')
13991         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13992         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13993         lru_resize_enable mdc
13994         lru_resize_enable osc
13995 }
13996 run_test 120a "Early Lock Cancel: mkdir test"
13997
13998 test_120b() {
13999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14000         remote_mds_nodsh && skip "remote MDS with nodsh"
14001         test_mkdir $DIR/$tdir
14002         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14003                 skip_env "no early lock cancel on server"
14004
14005         lru_resize_disable mdc
14006         lru_resize_disable osc
14007         cancel_lru_locks mdc
14008         stat $DIR/$tdir > /dev/null
14009         can1=$(do_facet $SINGLEMDS \
14010                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14011                awk '/ldlm_cancel/ {print $2}')
14012         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14013                awk '/ldlm_bl_callback/ {print $2}')
14014         touch $DIR/$tdir/f1
14015         can2=$(do_facet $SINGLEMDS \
14016                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14017                awk '/ldlm_cancel/ {print $2}')
14018         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14019                awk '/ldlm_bl_callback/ {print $2}')
14020         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14021         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14022         lru_resize_enable mdc
14023         lru_resize_enable osc
14024 }
14025 run_test 120b "Early Lock Cancel: create test"
14026
14027 test_120c() {
14028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14029         remote_mds_nodsh && skip "remote MDS with nodsh"
14030         test_mkdir -i0 -c1 $DIR/$tdir
14031         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14032                 skip "no early lock cancel on server"
14033
14034         lru_resize_disable mdc
14035         lru_resize_disable osc
14036         test_mkdir -i0 -c1 $DIR/$tdir/d1
14037         test_mkdir -i0 -c1 $DIR/$tdir/d2
14038         touch $DIR/$tdir/d1/f1
14039         cancel_lru_locks mdc
14040         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
14041         can1=$(do_facet mds1 \
14042                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14043                awk '/ldlm_cancel/ {print $2}')
14044         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14045                awk '/ldlm_bl_callback/ {print $2}')
14046         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14047         can2=$(do_facet mds1 \
14048                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14049                awk '/ldlm_cancel/ {print $2}')
14050         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14051                awk '/ldlm_bl_callback/ {print $2}')
14052         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14053         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14054         lru_resize_enable mdc
14055         lru_resize_enable osc
14056 }
14057 run_test 120c "Early Lock Cancel: link test"
14058
14059 test_120d() {
14060         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14061         remote_mds_nodsh && skip "remote MDS with nodsh"
14062         test_mkdir -i0 -c1 $DIR/$tdir
14063         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14064                 skip_env "no early lock cancel on server"
14065
14066         lru_resize_disable mdc
14067         lru_resize_disable osc
14068         touch $DIR/$tdir
14069         cancel_lru_locks mdc
14070         stat $DIR/$tdir > /dev/null
14071         can1=$(do_facet mds1 \
14072                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14073                awk '/ldlm_cancel/ {print $2}')
14074         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14075                awk '/ldlm_bl_callback/ {print $2}')
14076         chmod a+x $DIR/$tdir
14077         can2=$(do_facet mds1 \
14078                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14079                awk '/ldlm_cancel/ {print $2}')
14080         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14081                awk '/ldlm_bl_callback/ {print $2}')
14082         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14083         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14084         lru_resize_enable mdc
14085         lru_resize_enable osc
14086 }
14087 run_test 120d "Early Lock Cancel: setattr test"
14088
14089 test_120e() {
14090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14091         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14092                 skip_env "no early lock cancel on server"
14093         remote_mds_nodsh && skip "remote MDS with nodsh"
14094
14095         local dlmtrace_set=false
14096
14097         test_mkdir -i0 -c1 $DIR/$tdir
14098         lru_resize_disable mdc
14099         lru_resize_disable osc
14100         ! $LCTL get_param debug | grep -q dlmtrace &&
14101                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
14102         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
14103         cancel_lru_locks mdc
14104         cancel_lru_locks osc
14105         dd if=$DIR/$tdir/f1 of=/dev/null
14106         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
14107         # XXX client can not do early lock cancel of OST lock
14108         # during unlink (LU-4206), so cancel osc lock now.
14109         sleep 2
14110         cancel_lru_locks osc
14111         can1=$(do_facet mds1 \
14112                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14113                awk '/ldlm_cancel/ {print $2}')
14114         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14115                awk '/ldlm_bl_callback/ {print $2}')
14116         unlink $DIR/$tdir/f1
14117         sleep 5
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 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
14124                 $LCTL dk $TMP/cancel.debug.txt
14125         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
14126                 $LCTL dk $TMP/blocking.debug.txt
14127         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
14128         lru_resize_enable mdc
14129         lru_resize_enable osc
14130 }
14131 run_test 120e "Early Lock Cancel: unlink test"
14132
14133 test_120f() {
14134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14135         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14136                 skip_env "no early lock cancel on server"
14137         remote_mds_nodsh && skip "remote MDS with nodsh"
14138
14139         test_mkdir -i0 -c1 $DIR/$tdir
14140         lru_resize_disable mdc
14141         lru_resize_disable osc
14142         test_mkdir -i0 -c1 $DIR/$tdir/d1
14143         test_mkdir -i0 -c1 $DIR/$tdir/d2
14144         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
14145         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
14146         cancel_lru_locks mdc
14147         cancel_lru_locks osc
14148         dd if=$DIR/$tdir/d1/f1 of=/dev/null
14149         dd if=$DIR/$tdir/d2/f2 of=/dev/null
14150         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
14151         # XXX client can not do early lock cancel of OST lock
14152         # during rename (LU-4206), so cancel osc lock now.
14153         sleep 2
14154         cancel_lru_locks osc
14155         can1=$(do_facet mds1 \
14156                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14157                awk '/ldlm_cancel/ {print $2}')
14158         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14159                awk '/ldlm_bl_callback/ {print $2}')
14160         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
14161         sleep 5
14162         can2=$(do_facet mds1 \
14163                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14164                awk '/ldlm_cancel/ {print $2}')
14165         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14166                awk '/ldlm_bl_callback/ {print $2}')
14167         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
14168         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
14169         lru_resize_enable mdc
14170         lru_resize_enable osc
14171 }
14172 run_test 120f "Early Lock Cancel: rename test"
14173
14174 test_120g() {
14175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14176         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
14177                 skip_env "no early lock cancel on server"
14178         remote_mds_nodsh && skip "remote MDS with nodsh"
14179
14180         lru_resize_disable mdc
14181         lru_resize_disable osc
14182         count=10000
14183         echo create $count files
14184         test_mkdir $DIR/$tdir
14185         cancel_lru_locks mdc
14186         cancel_lru_locks osc
14187         t0=$(date +%s)
14188
14189         can0=$(do_facet $SINGLEMDS \
14190                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14191                awk '/ldlm_cancel/ {print $2}')
14192         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14193                awk '/ldlm_bl_callback/ {print $2}')
14194         createmany -o $DIR/$tdir/f $count
14195         sync
14196         can1=$(do_facet $SINGLEMDS \
14197                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14198                awk '/ldlm_cancel/ {print $2}')
14199         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14200                awk '/ldlm_bl_callback/ {print $2}')
14201         t1=$(date +%s)
14202         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
14203         echo rm $count files
14204         rm -r $DIR/$tdir
14205         sync
14206         can2=$(do_facet $SINGLEMDS \
14207                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
14208                awk '/ldlm_cancel/ {print $2}')
14209         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
14210                awk '/ldlm_bl_callback/ {print $2}')
14211         t2=$(date +%s)
14212         echo total: $count removes in $((t2-t1))
14213         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
14214         sleep 2
14215         # wait for commitment of removal
14216         lru_resize_enable mdc
14217         lru_resize_enable osc
14218 }
14219 run_test 120g "Early Lock Cancel: performance test"
14220
14221 test_121() { #bug #10589
14222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14223
14224         rm -rf $DIR/$tfile
14225         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
14226 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
14227         lctl set_param fail_loc=0x310
14228         cancel_lru_locks osc > /dev/null
14229         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
14230         lctl set_param fail_loc=0
14231         [[ $reads -eq $writes ]] ||
14232                 error "read $reads blocks, must be $writes blocks"
14233 }
14234 run_test 121 "read cancel race ========="
14235
14236 test_123a_base() { # was test 123, statahead(bug 11401)
14237         local lsx="$1"
14238
14239         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
14240
14241         SLOWOK=0
14242         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
14243                 log "testing UP system. Performance may be lower than expected."
14244                 SLOWOK=1
14245         fi
14246         running_in_vm && SLOWOK=1
14247
14248         $LCTL set_param mdc.*.batch_stats=0
14249
14250         rm -rf $DIR/$tdir
14251         test_mkdir $DIR/$tdir
14252         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
14253         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
14254         MULT=10
14255         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
14256                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
14257
14258                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
14259                 lctl set_param -n llite.*.statahead_max 0
14260                 lctl get_param llite.*.statahead_max
14261                 cancel_lru_locks mdc
14262                 cancel_lru_locks osc
14263                 stime=$(date +%s)
14264                 time $lsx $DIR/$tdir | wc -l
14265                 etime=$(date +%s)
14266                 delta=$((etime - stime))
14267                 log "$lsx $i files without statahead: $delta sec"
14268                 lctl set_param llite.*.statahead_max=$max
14269
14270                 swrong=$(lctl get_param -n llite.*.statahead_stats |
14271                          awk '/statahead.wrong:/ { print $NF }')
14272                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
14273                 cancel_lru_locks mdc
14274                 cancel_lru_locks osc
14275                 stime=$(date +%s)
14276                 time $lsx $DIR/$tdir | wc -l
14277                 etime=$(date +%s)
14278                 delta_sa=$((etime - stime))
14279                 log "$lsx $i files with statahead: $delta_sa sec"
14280                 lctl get_param -n llite.*.statahead_stats
14281                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
14282                          awk '/statahead.wrong:/ { print $NF }')
14283
14284                 [[ $swrong -lt $ewrong ]] &&
14285                         log "statahead was stopped, maybe too many locks held!"
14286                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
14287
14288                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
14289                         max=$(lctl get_param -n llite.*.statahead_max |
14290                                 head -n 1)
14291                         lctl set_param -n llite.*.statahead_max 0
14292                         lctl get_param llite.*.statahead_max
14293                         cancel_lru_locks mdc
14294                         cancel_lru_locks osc
14295                         stime=$(date +%s)
14296                         time $lsx $DIR/$tdir | wc -l
14297                         etime=$(date +%s)
14298                         delta=$((etime - stime))
14299                         log "$lsx $i files again without statahead: $delta sec"
14300                         lctl set_param llite.*.statahead_max=$max
14301                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
14302                                 if [ $SLOWOK -eq 0 ]; then
14303                                         error "$lsx $i files is slower with statahead!"
14304                                 else
14305                                         log "$lsx $i files is slower with statahead!"
14306                                 fi
14307                                 break
14308                         fi
14309                 fi
14310
14311                 [ $delta -gt 20 ] && break
14312                 [ $delta -gt 8 ] && MULT=$((50 / delta))
14313                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
14314         done
14315         log "$lsx done"
14316
14317         stime=$(date +%s)
14318         rm -r $DIR/$tdir
14319         sync
14320         etime=$(date +%s)
14321         delta=$((etime - stime))
14322         log "rm -r $DIR/$tdir/: $delta seconds"
14323         log "rm done"
14324         lctl get_param -n llite.*.statahead_stats
14325         $LCTL get_param mdc.*.batch_stats
14326 }
14327
14328 test_123aa() {
14329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14330
14331         test_123a_base "ls -l"
14332 }
14333 run_test 123aa "verify statahead work"
14334
14335 test_123ab() {
14336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14337
14338         statx_supported || skip_env "Test must be statx() syscall supported"
14339
14340         test_123a_base "$STATX -l"
14341 }
14342 run_test 123ab "verify statahead work by using statx"
14343
14344 test_123ac() {
14345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14346
14347         statx_supported || skip_env "Test must be statx() syscall supported"
14348
14349         local rpcs_before
14350         local rpcs_after
14351         local agl_before
14352         local agl_after
14353
14354         cancel_lru_locks $OSC
14355         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14356         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
14357                      awk '/agl.total:/ { print $NF }')
14358         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
14359         test_123a_base "$STATX --cached=always -D"
14360         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
14361                     awk '/agl.total:/ { print $NF }')
14362         [ $agl_before -eq $agl_after ] ||
14363                 error "Should not trigger AGL thread - $agl_before:$agl_after"
14364         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
14365         [ $rpcs_after -eq $rpcs_before ] ||
14366                 error "$STATX should not send glimpse RPCs to $OSC"
14367 }
14368 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
14369
14370 test_batch_statahead() {
14371         local max=$1
14372         local batch_max=$2
14373         local num=10000
14374         local batch_rpcs
14375         local unbatch_rpcs
14376         local hit_total
14377
14378         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
14379         $LCTL set_param mdc.*.batch_stats=0
14380         $LCTL set_param llite.*.statahead_max=$max
14381         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14382         # Verify that batched statahead is faster than one without statahead
14383         test_123a_base "ls -l"
14384
14385         stack_trap "rm -rf $DIR/$tdir" EXIT
14386         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
14387         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
14388
14389         # unbatched statahead
14390         $LCTL set_param llite.*.statahead_batch_max=0
14391         $LCTL set_param llite.*.statahead_stats=clear
14392         $LCTL set_param mdc.*.stats=clear
14393         cancel_lru_locks mdc
14394         cancel_lru_locks osc
14395         time ls -l $DIR/$tdir | wc -l
14396         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
14397         wait_update_facet client "pgrep ll_sa" "" 35 ||
14398                 error "ll_sa thread is still running"
14399         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14400                     awk '/hit.total:/ { print $NF }')
14401         # hit ratio should be larger than 75% (7500).
14402         (( $hit_total > 7500 )) ||
14403                 error "unbatched statahead hit count ($hit_total) is too low"
14404
14405         # batched statahead
14406         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14407         $LCTL set_param llite.*.statahead_stats=clear
14408         $LCTL set_param mdc.*.batch_stats=clear
14409         $LCTL set_param mdc.*.stats=clear
14410         cancel_lru_locks mdc
14411         cancel_lru_locks osc
14412         time ls -l $DIR/$tdir | wc -l
14413         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
14414         # wait for statahead thread to quit and update statahead stats
14415         wait_update_facet client "pgrep ll_sa" "" 35 ||
14416                 error "ll_sa thread is still running"
14417         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
14418                     awk '/hit.total:/ { print $NF }')
14419         # hit ratio should be larger than 75% (7500).
14420         (( $hit_total > 7500 )) ||
14421                 error "batched statahead hit count ($hit_total) is too low"
14422
14423         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
14424         (( $unbatch_rpcs > $batch_rpcs )) ||
14425                 error "batched statahead does not reduce RPC count"
14426         $LCTL get_param mdc.*.batch_stats
14427 }
14428
14429 test_123ad() {
14430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14431
14432         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
14433                 skip "Need server version at least 2.15.53"
14434
14435         local max
14436         local batch_max
14437
14438         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14439         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14440
14441         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14442         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14443
14444         test_batch_statahead 32 32
14445         test_batch_statahead 2048 256
14446 }
14447 run_test 123ad "Verify batching statahead works correctly"
14448
14449 test_123b () { # statahead(bug 15027)
14450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14451
14452         test_mkdir $DIR/$tdir
14453         createmany -o $DIR/$tdir/$tfile-%d 1000
14454
14455         cancel_lru_locks mdc
14456         cancel_lru_locks osc
14457
14458 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
14459         lctl set_param fail_loc=0x80000803
14460         ls -lR $DIR/$tdir > /dev/null
14461         log "ls done"
14462         lctl set_param fail_loc=0x0
14463         lctl get_param -n llite.*.statahead_stats
14464         rm -r $DIR/$tdir
14465         sync
14466
14467 }
14468 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
14469
14470 test_123c() {
14471         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
14472
14473         test_mkdir -i 0 -c 1 $DIR/$tdir.0
14474         test_mkdir -i 1 -c 1 $DIR/$tdir.1
14475         touch $DIR/$tdir.1/{1..3}
14476         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
14477
14478         remount_client $MOUNT
14479
14480         $MULTIOP $DIR/$tdir.0 Q
14481
14482         # let statahead to complete
14483         ls -l $DIR/$tdir.0 > /dev/null
14484
14485         testid=$(echo $TESTNAME | tr '_' ' ')
14486         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
14487                 error "statahead warning" || true
14488 }
14489 run_test 123c "Can not initialize inode warning on DNE statahead"
14490
14491 test_123d() {
14492         local num=100
14493         local swrong
14494         local ewrong
14495
14496         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
14497         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
14498                 error "setdirstripe $DIR/$tdir failed"
14499         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
14500         remount_client $MOUNT
14501         $LCTL get_param llite.*.statahead_max
14502         $LCTL set_param llite.*.statahead_stats=0 ||
14503                 error "clear statahead_stats failed"
14504         swrong=$(lctl get_param -n llite.*.statahead_stats |
14505                  awk '/statahead.wrong:/ { print $NF }')
14506         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
14507         # wait for statahead thread finished to update hit/miss stats.
14508         sleep 1
14509         $LCTL get_param -n llite.*.statahead_stats
14510         ewrong=$(lctl get_param -n llite.*.statahead_stats |
14511                  awk '/statahead.wrong:/ { print $NF }')
14512         (( $swrong == $ewrong )) ||
14513                 log "statahead was stopped, maybe too many locks held!"
14514 }
14515 run_test 123d "Statahead on striped directories works correctly"
14516
14517 test_123e() {
14518         local max
14519         local batch_max
14520         local dir=$DIR/$tdir
14521
14522         mkdir $dir || error "mkdir $dir failed"
14523         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
14524         stack_trap "rm -rf $dir"
14525
14526         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
14527
14528         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14529         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14530         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
14531         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
14532
14533         $LCTL set_param llite.*.statahead_max=2048
14534         $LCTL set_param llite.*.statahead_batch_max=1024
14535
14536         ls -l $dir
14537         $LCTL get_param mdc.*.batch_stats
14538         $LCTL get_param llite.*.statahead_*
14539 }
14540 run_test 123e "statahead with large wide striping"
14541
14542 test_123f() {
14543         local max
14544         local batch_max
14545         local dir=$DIR/$tdir
14546
14547         mkdir $dir || error "mkdir $dir failed"
14548         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
14549         stack_trap "rm -rf $dir"
14550
14551         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
14552
14553         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14554         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14555
14556         $LCTL set_param llite.*.statahead_max=64
14557         $LCTL set_param llite.*.statahead_batch_max=64
14558
14559         ls -l $dir
14560         lctl get_param mdc.*.batch_stats
14561         lctl get_param llite.*.statahead_*
14562
14563         $LCTL set_param llite.*.statahead_max=$max
14564         $LCTL set_param llite.*.statahead_batch_max=$batch_max
14565 }
14566 run_test 123f "Retry mechanism with large wide striping files"
14567
14568 test_123g() {
14569         local dir=$DIR/$tdir
14570         local num=1000
14571
14572         mkdir $dir || error "failed to mkdir $dir"
14573         createmany -o $dir/$tfile $num || error "failed creatmany files"
14574         cancel_lru_locks mdc
14575         cancel_lru_locks osc
14576
14577         $LCTL set_param llite.*.statahead_stats=clear
14578         $LCTL set_param mdc.*.batch_stats=clear
14579         aheadmany -c stat -s 0 -e $num -b $tfile -d $dir ||
14580                 error "aheadmany $dir with $tfile failed"
14581         wait_update_facet client "pgrep ll_sa" "" 35 ||
14582                 error "ll_sa thread is still running"
14583         $LCTL get_param -n llite.*.statahead_stats
14584         $LCTL get_param -n mdc.*.batch_stats
14585
14586         local count
14587
14588         count=$($LCTL get_param -n llite.*.statahead_stats |
14589                 awk '/hit.total:/ {print $2}')
14590         echo "Hit total: $count"
14591         # Hit ratio should be >= 75%
14592         (( $count > num * 75 / 100 )) ||
14593                 error "hit total $count is be > 75% of $num"
14594 }
14595 run_test 123g "Test for stat-ahead advise"
14596
14597 test_123h_base() {
14598         local dir=$DIR/$tdir
14599         local cmd="touch $dir/$tfile.{$1}"
14600         local fcnt=$2
14601
14602         stack_trap "rm -rf $dir"
14603         mkdir -p $dir || error "failed to mkdir $dir"
14604         eval $cmd
14605
14606         cancel_lru_locks mdc
14607         $LCTL set_param llite.*.statahead_stats=clear
14608         $LCTL set_param mdc.*.batch_stats=0
14609         $LCTL set_param llite.*.statahead_max=1024
14610         $LCTL set_param llite.*.statahead_batch_max=1024
14611         lctl get_param -n llite.*.statahead_stats
14612         du -a $dir > /dev/null
14613         echo "Wait statahead thread (ll_sa_xxx) to exit..."
14614         wait_update_facet client "pgrep ll_sa" "" 35 ||
14615                 error "ll_sa statahead thread does not quit in 35s"
14616         $LCTL get_param -n llite.*.statahead_stats
14617         $LCTL get_param -n mdc.*.batch_stats
14618
14619         local count=$($LCTL get_param -n llite.*.statahead_stats |
14620                         awk '/fname.total:/ {print $2}')
14621
14622         [ $count == 1 ] || error "File name pattern statahead not trigger"
14623         count=$($LCTL get_param -n llite.*.statahead_stats |
14624                 awk '/hit.total:/ {print $2}')
14625         # Hit ratio should be >= 75%
14626         (( $count > fcnt * 75 / 100 )) ||
14627                 error "hit total is too low: $count"
14628         rm -rf $dir || error "rm -rf $dir failed"
14629 }
14630
14631 test_123h() {
14632         local max
14633         local batch_max
14634         local enabled
14635
14636         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14637         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14638         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14639         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14640         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14641         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14642
14643         $LCTL set_param llite.*.enable_statahead_fname=1
14644
14645         echo "Scan a directory with number regularized fname"
14646         test_123h_base "0..10000" 10000
14647
14648         echo "Scan a directory with zeroed padding number regularized fname"
14649         test_123h_base "000000..010000" 10000
14650 }
14651 run_test 123h "Verify statahead work with the fname pattern via du"
14652
14653 test_123i_base() {
14654         local fmt=$1
14655         local iocmd=$2
14656         local dir=$DIR/$tdir
14657         local cmd="createmany -m $fmt"
14658
14659         echo "Command:"
14660         echo "- $cmd"
14661         echo "- $iocmd"
14662         stack_trap "unlinkmany $fmt"
14663         mkdir -p $dir || error "failed to mkdir $dir"
14664         eval $cmd
14665
14666         cancel_lru_locks mdc
14667         $LCTL set_param llite.*.statahead_stats=clear
14668         $LCTL set_param mdc.*.batch_stats=0
14669
14670         echo "statahead_stats (Pre):"
14671         lctl get_param -n llite.*.statahead_stats
14672         eval $iocmd || error "$iocmd failed"
14673         echo "statahead_stats (Post):"
14674         $LCTL get_param -n llite.*.statahead_stats
14675         $LCTL get_param -n mdc.*.batch_stats
14676
14677         echo "Wait the statahead thread (ll_sa_xxx) to exit ..."
14678         wait_update_facet client "pgrep ll_sa" "" 35 ||
14679                 error "ll_sa statahead thread does not quit in 35s"
14680         $LCTL get_param -n llite.*.statahead_stats
14681         $LCTL get_param -n mdc.*.batch_stats
14682
14683         local count=$($LCTL get_param -n llite.*.statahead_stats |
14684                         awk '/fname.total:/ {print $2}')
14685
14686         [ $count == 1 ] || error "File name pattern statahead not trigger"
14687         count=$($LCTL get_param -n llite.*.statahead_stats |
14688                 awk '/hit.total:/ {print $2}')
14689         # Hit ratio should be >= 75%
14690         (( $count > 750 )) || error "hit total is too low: $count"
14691 }
14692
14693 test_123i() {
14694         local dir=$DIR/$tdir
14695         local cnt=1000
14696         local max
14697         local batch_max
14698         local enabled
14699         local min
14700
14701         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
14702         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
14703         min=$($LCTL get_param -n llite.*.statahead_min | head -n 1)
14704         enabled=$($LCTL get_param -n llite.*.enable_statahead_fname | head -n 1)
14705         stack_trap "$LCTL set_param llite.*.statahead_max=$max"
14706         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max"
14707         stack_trap "$LCTL set_param llite.*.statahead_min=$min"
14708         stack_trap "$LCTL set_param llite.*.enable_statahead_fname=$enabled"
14709         $LCTL set_param llite.*.statahead_max=1024
14710         $LCTL set_param llite.*.statahead_batch_max=32
14711         $LCTL set_param llite.*.statahead_min=64
14712         $LCTL set_param llite.*.enable_statahead_fname=1
14713
14714         test_123i_base "$dir/$tfile.%06d $cnt" "ls $dir/* > /dev/null"
14715         test_123i_base "$dir/$tfile $cnt" \
14716                 "aheadmany -c stat -N -s 0 -e $cnt -b $tfile -d $dir"
14717 }
14718 run_test 123i "Verify statahead work with the fname indexing pattern"
14719
14720 test_124a() {
14721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14722         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14723                 skip_env "no lru resize on server"
14724
14725         local NR=2000
14726
14727         test_mkdir $DIR/$tdir
14728
14729         log "create $NR files at $DIR/$tdir"
14730         createmany -o $DIR/$tdir/f $NR ||
14731                 error "failed to create $NR files in $DIR/$tdir"
14732
14733         cancel_lru_locks mdc
14734         ls -l $DIR/$tdir > /dev/null
14735
14736         local NSDIR=""
14737         local LRU_SIZE=0
14738         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
14739                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
14740                 LRU_SIZE=$($LCTL get_param -n $PARAM)
14741                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
14742                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
14743                         log "NSDIR=$NSDIR"
14744                         log "NS=$(basename $NSDIR)"
14745                         break
14746                 fi
14747         done
14748
14749         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
14750                 skip "Not enough cached locks created!"
14751         fi
14752         log "LRU=$LRU_SIZE"
14753
14754         local SLEEP=30
14755
14756         # We know that lru resize allows one client to hold $LIMIT locks
14757         # for 10h. After that locks begin to be killed by client.
14758         local MAX_HRS=10
14759         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
14760         log "LIMIT=$LIMIT"
14761         if [ $LIMIT -lt $LRU_SIZE ]; then
14762                 skip "Limit is too small $LIMIT"
14763         fi
14764
14765         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
14766         # killing locks. Some time was spent for creating locks. This means
14767         # that up to the moment of sleep finish we must have killed some of
14768         # them (10-100 locks). This depends on how fast ther were created.
14769         # Many of them were touched in almost the same moment and thus will
14770         # be killed in groups.
14771         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
14772
14773         # Use $LRU_SIZE_B here to take into account real number of locks
14774         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
14775         local LRU_SIZE_B=$LRU_SIZE
14776         log "LVF=$LVF"
14777         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
14778         log "OLD_LVF=$OLD_LVF"
14779         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
14780
14781         # Let's make sure that we really have some margin. Client checks
14782         # cached locks every 10 sec.
14783         SLEEP=$((SLEEP+20))
14784         log "Sleep ${SLEEP} sec"
14785         local SEC=0
14786         while ((SEC<$SLEEP)); do
14787                 echo -n "..."
14788                 sleep 5
14789                 SEC=$((SEC+5))
14790                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
14791                 echo -n "$LRU_SIZE"
14792         done
14793         echo ""
14794         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
14795         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
14796
14797         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
14798                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
14799                 unlinkmany $DIR/$tdir/f $NR
14800                 return
14801         }
14802
14803         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
14804         log "unlink $NR files at $DIR/$tdir"
14805         unlinkmany $DIR/$tdir/f $NR
14806 }
14807 run_test 124a "lru resize ======================================="
14808
14809 get_max_pool_limit()
14810 {
14811         local limit=$($LCTL get_param \
14812                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
14813         local max=0
14814         for l in $limit; do
14815                 if [[ $l -gt $max ]]; then
14816                         max=$l
14817                 fi
14818         done
14819         echo $max
14820 }
14821
14822 test_124b() {
14823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14824         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14825                 skip_env "no lru resize on server"
14826
14827         LIMIT=$(get_max_pool_limit)
14828
14829         NR=$(($(default_lru_size)*20))
14830         if [[ $NR -gt $LIMIT ]]; then
14831                 log "Limit lock number by $LIMIT locks"
14832                 NR=$LIMIT
14833         fi
14834
14835         IFree=$(mdsrate_inodes_available)
14836         if [ $IFree -lt $NR ]; then
14837                 log "Limit lock number by $IFree inodes"
14838                 NR=$IFree
14839         fi
14840
14841         lru_resize_disable mdc
14842         test_mkdir -p $DIR/$tdir/disable_lru_resize
14843
14844         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
14845         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
14846         cancel_lru_locks mdc
14847         stime=`date +%s`
14848         PID=""
14849         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14850         PID="$PID $!"
14851         sleep 2
14852         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14853         PID="$PID $!"
14854         sleep 2
14855         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14856         PID="$PID $!"
14857         wait $PID
14858         etime=`date +%s`
14859         nolruresize_delta=$((etime-stime))
14860         log "ls -la time: $nolruresize_delta seconds"
14861         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14862         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14863
14864         lru_resize_enable mdc
14865         test_mkdir -p $DIR/$tdir/enable_lru_resize
14866
14867         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14868         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14869         cancel_lru_locks mdc
14870         stime=`date +%s`
14871         PID=""
14872         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14873         PID="$PID $!"
14874         sleep 2
14875         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14876         PID="$PID $!"
14877         sleep 2
14878         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14879         PID="$PID $!"
14880         wait $PID
14881         etime=`date +%s`
14882         lruresize_delta=$((etime-stime))
14883         log "ls -la time: $lruresize_delta seconds"
14884         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14885
14886         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14887                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14888         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14889                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14890         else
14891                 log "lru resize performs the same with no lru resize"
14892         fi
14893         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14894 }
14895 run_test 124b "lru resize (performance test) ======================="
14896
14897 test_124c() {
14898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14899         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14900                 skip_env "no lru resize on server"
14901
14902         # cache ununsed locks on client
14903         local nr=100
14904         cancel_lru_locks mdc
14905         test_mkdir $DIR/$tdir
14906         createmany -o $DIR/$tdir/f $nr ||
14907                 error "failed to create $nr files in $DIR/$tdir"
14908         ls -l $DIR/$tdir > /dev/null
14909
14910         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14911         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14912         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14913         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14914         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14915
14916         # set lru_max_age to 1 sec
14917         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14918         echo "sleep $((recalc_p * 2)) seconds..."
14919         sleep $((recalc_p * 2))
14920
14921         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14922         # restore lru_max_age
14923         $LCTL set_param -n $nsdir.lru_max_age $max_age
14924         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14925         unlinkmany $DIR/$tdir/f $nr
14926 }
14927 run_test 124c "LRUR cancel very aged locks"
14928
14929 test_124d() {
14930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14931         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14932                 skip_env "no lru resize on server"
14933
14934         # cache ununsed locks on client
14935         local nr=100
14936
14937         lru_resize_disable mdc
14938         stack_trap "lru_resize_enable mdc" EXIT
14939
14940         cancel_lru_locks mdc
14941
14942         # asynchronous object destroy at MDT could cause bl ast to client
14943         test_mkdir $DIR/$tdir
14944         createmany -o $DIR/$tdir/f $nr ||
14945                 error "failed to create $nr files in $DIR/$tdir"
14946         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14947
14948         ls -l $DIR/$tdir > /dev/null
14949
14950         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14951         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14952         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14953         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14954
14955         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14956
14957         # set lru_max_age to 1 sec
14958         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14959         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14960
14961         echo "sleep $((recalc_p * 2)) seconds..."
14962         sleep $((recalc_p * 2))
14963
14964         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14965
14966         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14967 }
14968 run_test 124d "cancel very aged locks if lru-resize disabled"
14969
14970 test_125() { # 13358
14971         $LCTL get_param -n llite.*.client_type | grep -q local ||
14972                 skip "must run as local client"
14973         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14974                 skip_env "must have acl enabled"
14975         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14976         id $USER0 || skip_env "missing user $USER0"
14977
14978         test_mkdir $DIR/$tdir
14979         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14980         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14981                 error "setfacl $DIR/$tdir failed"
14982         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14983 }
14984 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14985
14986 test_126() { # bug 12829/13455
14987         $GSS && skip_env "must run as gss disabled"
14988         $LCTL get_param -n llite.*.client_type | grep -q local ||
14989                 skip "must run as local client"
14990         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14991
14992         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14993         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14994         rm -f $DIR/$tfile
14995         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14996 }
14997 run_test 126 "check that the fsgid provided by the client is taken into account"
14998
14999 test_127a() { # bug 15521
15000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15001         local name count samp unit min max sum sumsq
15002         local tmpfile=$TMP/$tfile.tmp
15003
15004         # enable stats header if it is disabled
15005         $LCTL set_param enable_stats_header=1
15006
15007         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
15008         echo "stats before reset"
15009         stack_trap "rm -f $tmpfile"
15010         local now=$(date +%s)
15011
15012         $LCTL get_param osc.*.stats | tee $tmpfile
15013
15014         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15015         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15016         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15017         local uptime=$(awk '{ print $1 }' /proc/uptime)
15018
15019         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15020         (( ${snapshot_time%\.*} >= $now - 5 &&
15021            ${snapshot_time%\.*} <= $now + 5 )) ||
15022                 error "snapshot_time=$snapshot_time != now=$now"
15023         # elapsed _should_ be from mount, but at least less than uptime
15024         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
15025                 error "elapsed=$elapsed > uptime=$uptime"
15026         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15027            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15028                 error "elapsed=$elapsed != $snapshot_time - $start_time"
15029
15030         $LCTL set_param osc.*.stats=0
15031         local reset=$(date +%s)
15032         local fsize=$((2048 * 1024))
15033
15034         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
15035         cancel_lru_locks osc
15036         dd if=$DIR/$tfile of=/dev/null bs=$fsize
15037
15038         now=$(date +%s)
15039         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
15040         while read name count samp unit min max sum sumsq; do
15041                 [[ "$samp" == "samples" ]] || continue
15042
15043                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15044                 [ ! $min ] && error "Missing min value for $name proc entry"
15045                 eval $name=$count || error "Wrong proc format"
15046
15047                 case $name in
15048                 read_bytes|write_bytes)
15049                         [[ "$unit" =~ "bytes" ]] ||
15050                                 error "unit is not 'bytes': $unit"
15051                         (( $min >= 4096 )) || error "min is too small: $min"
15052                         (( $min <= $fsize )) || error "min is too big: $min"
15053                         (( $max >= 4096 )) || error "max is too small: $max"
15054                         (( $max <= $fsize )) || error "max is too big: $max"
15055                         (( $sum == $fsize )) || error "sum is wrong: $sum"
15056                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
15057                                 error "sumsquare is too small: $sumsq"
15058                         (( $sumsq <= $fsize * $fsize )) ||
15059                                 error "sumsquare is too big: $sumsq"
15060                         ;;
15061                 ost_read|ost_write)
15062                         [[ "$unit" =~ "usec" ]] ||
15063                                 error "unit is not 'usec': $unit"
15064                         ;;
15065                 *)      ;;
15066                 esac
15067         done < $tmpfile
15068
15069         #check that we actually got some stats
15070         [ "$read_bytes" ] || error "Missing read_bytes stats"
15071         [ "$write_bytes" ] || error "Missing write_bytes stats"
15072         [ "$read_bytes" != 0 ] || error "no read done"
15073         [ "$write_bytes" != 0 ] || error "no write done"
15074
15075         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
15076         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
15077         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
15078
15079         # snapshot_time should match POSIX epoch time, allow some delta for VMs
15080         (( ${snapshot_time%\.*} >= $now - 5 &&
15081            ${snapshot_time%\.*} <= $now + 5 )) ||
15082                 error "reset snapshot_time=$snapshot_time != now=$now"
15083         # elapsed should be from time of stats reset
15084         (( ${elapsed%\.*} >= $now - $reset - 2 &&
15085            ${elapsed%\.*} <= $now - $reset + 2 )) ||
15086                 error "reset elapsed=$elapsed > $now - $reset"
15087         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
15088            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
15089                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
15090 }
15091 run_test 127a "verify the client stats are sane"
15092
15093 test_127b() { # bug LU-333
15094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15095         local name count samp unit min max sum sumsq
15096
15097         echo "stats before reset"
15098         $LCTL get_param llite.*.stats
15099         $LCTL set_param llite.*.stats=0
15100
15101         # perform 2 reads and writes so MAX is different from SUM.
15102         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15103         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
15104         cancel_lru_locks osc
15105         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15106         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
15107
15108         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
15109         stack_trap "rm -f $TMP/$tfile.tmp"
15110         while read name count samp unit min max sum sumsq; do
15111                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
15112                 eval $name=$count || error "Wrong proc format"
15113
15114                 case $name in
15115                 read_bytes|write_bytes)
15116                         [[ "$unit" =~ "bytes" ]] ||
15117                                 error "unit is not 'bytes': $unit"
15118                         (( $count == 2 )) || error "count is not 2: $count"
15119                         (( $min == $PAGE_SIZE )) ||
15120                                 error "min is not $PAGE_SIZE: $min"
15121                         (( $max == $PAGE_SIZE )) ||
15122                                 error "max is not $PAGE_SIZE: $max"
15123                         (( $sum == $PAGE_SIZE * 2 )) ||
15124                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
15125                         ;;
15126                 read|write)
15127                         [[ "$unit" =~ "usec" ]] ||
15128                                 error "unit is not 'usec': $unit"
15129                         ;;
15130                 *)      ;;
15131                 esac
15132         done < $TMP/$tfile.tmp
15133
15134         #check that we actually got some stats
15135         [ "$read_bytes" ] || error "Missing read_bytes stats"
15136         [ "$write_bytes" ] || error "Missing write_bytes stats"
15137         [ "$read_bytes" != 0 ] || error "no read done"
15138         [ "$write_bytes" != 0 ] || error "no write done"
15139 }
15140 run_test 127b "verify the llite client stats are sane"
15141
15142 test_127c() { # LU-12394
15143         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
15144         local size
15145         local bsize
15146         local reads
15147         local writes
15148         local count
15149
15150         $LCTL set_param llite.*.extents_stats=1
15151         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
15152
15153         # Use two stripes so there is enough space in default config
15154         $LFS setstripe -c 2 $DIR/$tfile
15155
15156         # Extent stats start at 0-4K and go in power of two buckets
15157         # LL_HIST_START = 12 --> 2^12 = 4K
15158         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
15159         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
15160         # small configs
15161         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
15162                 do
15163                 # Write and read, 2x each, second time at a non-zero offset
15164                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
15165                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
15166                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
15167                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
15168                 rm -f $DIR/$tfile
15169         done
15170
15171         $LCTL get_param llite.*.extents_stats
15172
15173         count=2
15174         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
15175                 do
15176                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
15177                                 grep -m 1 $bsize)
15178                 reads=$(echo $bucket | awk '{print $5}')
15179                 writes=$(echo $bucket | awk '{print $9}')
15180                 [ "$reads" -eq $count ] ||
15181                         error "$reads reads in < $bsize bucket, expect $count"
15182                 [ "$writes" -eq $count ] ||
15183                         error "$writes writes in < $bsize bucket, expect $count"
15184         done
15185
15186         # Test mmap write and read
15187         $LCTL set_param llite.*.extents_stats=c
15188         size=512
15189         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
15190         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
15191         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
15192
15193         $LCTL get_param llite.*.extents_stats
15194
15195         count=$(((size*1024) / PAGE_SIZE))
15196
15197         bsize=$((2 * PAGE_SIZE / 1024))K
15198
15199         bucket=$($LCTL get_param -n llite.*.extents_stats |
15200                         grep -m 1 $bsize)
15201         reads=$(echo $bucket | awk '{print $5}')
15202         writes=$(echo $bucket | awk '{print $9}')
15203         # mmap writes fault in the page first, creating an additonal read
15204         [ "$reads" -eq $((2 * count)) ] ||
15205                 error "$reads reads in < $bsize bucket, expect $count"
15206         [ "$writes" -eq $count ] ||
15207                 error "$writes writes in < $bsize bucket, expect $count"
15208 }
15209 run_test 127c "test llite extent stats with regular & mmap i/o"
15210
15211 test_128() { # bug 15212
15212         touch $DIR/$tfile
15213         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
15214                 find $DIR/$tfile
15215                 find $DIR/$tfile
15216         EOF
15217
15218         result=$(grep error $TMP/$tfile.log)
15219         rm -f $DIR/$tfile $TMP/$tfile.log
15220         [ -z "$result" ] ||
15221                 error "consecutive find's under interactive lfs failed"
15222 }
15223 run_test 128 "interactive lfs for 2 consecutive find's"
15224
15225 set_dir_limits () {
15226         local mntdev
15227         local canondev
15228         local node
15229
15230         local ldproc=/proc/fs/ldiskfs
15231         local facets=$(get_facets MDS)
15232
15233         for facet in ${facets//,/ }; do
15234                 canondev=$(ldiskfs_canon \
15235                            *.$(convert_facet2label $facet).mntdev $facet)
15236                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
15237                         ldproc=/sys/fs/ldiskfs
15238                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
15239                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
15240         done
15241 }
15242
15243 check_mds_dmesg() {
15244         local facets=$(get_facets MDS)
15245         for facet in ${facets//,/ }; do
15246                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
15247         done
15248         return 1
15249 }
15250
15251 test_129() {
15252         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15253         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
15254                 skip "Need MDS version with at least 2.5.56"
15255         if [ "$mds1_FSTYPE" != ldiskfs ]; then
15256                 skip_env "ldiskfs only test"
15257         fi
15258         remote_mds_nodsh && skip "remote MDS with nodsh"
15259
15260         local ENOSPC=28
15261         local has_warning=false
15262
15263         rm -rf $DIR/$tdir
15264         mkdir -p $DIR/$tdir
15265
15266         # block size of mds1
15267         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
15268         set_dir_limits $maxsize $((maxsize * 6 / 8))
15269         stack_trap "set_dir_limits 0 0"
15270         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
15271         local dirsize=$(stat -c%s "$DIR/$tdir")
15272         local nfiles=0
15273         while (( $dirsize <= $maxsize )); do
15274                 $MCREATE $DIR/$tdir/file_base_$nfiles
15275                 rc=$?
15276                 # check two errors:
15277                 # ENOSPC for ext4 max_dir_size, which has been used since
15278                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
15279                 if (( rc == ENOSPC )); then
15280                         set_dir_limits 0 0
15281                         echo "rc=$rc returned as expected after $nfiles files"
15282
15283                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
15284                                 error "create failed w/o dir size limit"
15285
15286                         # messages may be rate limited if test is run repeatedly
15287                         check_mds_dmesg '"is approaching max"' ||
15288                                 echo "warning message should be output"
15289                         check_mds_dmesg '"has reached max"' ||
15290                                 echo "reached message should be output"
15291
15292                         dirsize=$(stat -c%s "$DIR/$tdir")
15293
15294                         [[ $dirsize -ge $maxsize ]] && return 0
15295                         error "dirsize $dirsize < $maxsize after $nfiles files"
15296                 elif (( rc != 0 )); then
15297                         break
15298                 fi
15299                 nfiles=$((nfiles + 1))
15300                 dirsize=$(stat -c%s "$DIR/$tdir")
15301         done
15302
15303         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
15304 }
15305 run_test 129 "test directory size limit ========================"
15306
15307 OLDIFS="$IFS"
15308 cleanup_130() {
15309         trap 0
15310         IFS="$OLDIFS"
15311         rm -f $DIR/$tfile
15312 }
15313
15314 test_130a() {
15315         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
15316         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
15317
15318         trap cleanup_130 EXIT RETURN
15319
15320         local fm_file=$DIR/$tfile
15321         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
15322         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
15323                 error "dd failed for $fm_file"
15324
15325         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
15326         filefrag -ves $fm_file
15327         local rc=$?
15328         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15329                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15330         (( $rc == 0 )) || error "filefrag $fm_file failed"
15331
15332         filefrag_op=$(filefrag -ve -k $fm_file |
15333                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15334         local lun=$($LFS getstripe -i $fm_file)
15335
15336         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
15337         IFS=$'\n'
15338         local tot_len=0
15339         for line in $filefrag_op; do
15340                 local frag_lun=$(echo $line | cut -d: -f5)
15341                 local ext_len=$(echo $line | cut -d: -f4)
15342
15343                 if (( $frag_lun != $lun )); then
15344                         error "FIEMAP on 1-stripe file($fm_file) failed"
15345                         return
15346                 fi
15347                 (( tot_len += ext_len ))
15348         done
15349
15350         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
15351                 error "FIEMAP on 1-stripe file($fm_file) failed"
15352                 return
15353         fi
15354
15355         echo "FIEMAP on single striped file succeeded"
15356 }
15357 run_test 130a "FIEMAP (1-stripe file)"
15358
15359 test_130b() {
15360         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15361
15362         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15363         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15364         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15365                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15366
15367         trap cleanup_130 EXIT RETURN
15368
15369         local fm_file=$DIR/$tfile
15370         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15371                 error "setstripe on $fm_file"
15372
15373         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
15374                 error "dd failed on $fm_file"
15375
15376         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15377         filefrag_op=$(filefrag -ve -k $fm_file |
15378                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15379
15380         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15381                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15382
15383         IFS=$'\n'
15384         local tot_len=0
15385         local num_luns=1
15386
15387         for line in $filefrag_op; do
15388                 local frag_lun=$(echo $line | cut -d: -f5 |
15389                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15390                 local ext_len=$(echo $line | cut -d: -f4)
15391                 if (( $frag_lun != $last_lun )); then
15392                         if (( tot_len != 1024 )); then
15393                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15394                                 return
15395                         else
15396                                 (( num_luns += 1 ))
15397                                 tot_len=0
15398                         fi
15399                 fi
15400                 (( tot_len += ext_len ))
15401                 last_lun=$frag_lun
15402         done
15403         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
15404                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15405                 return
15406         fi
15407
15408         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
15409 }
15410 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
15411
15412 test_130c() {
15413         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15414
15415         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15416         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15417         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15418                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15419
15420         trap cleanup_130 EXIT RETURN
15421
15422         local fm_file=$DIR/$tfile
15423         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
15424
15425         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
15426                 error "dd failed on $fm_file"
15427
15428         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15429         filefrag_op=$(filefrag -ve -k $fm_file |
15430                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15431
15432         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15433                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15434
15435         IFS=$'\n'
15436         local tot_len=0
15437         local num_luns=1
15438         for line in $filefrag_op; do
15439                 local frag_lun=$(echo $line | cut -d: -f5 |
15440                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15441                 local ext_len=$(echo $line | cut -d: -f4)
15442                 if (( $frag_lun != $last_lun )); then
15443                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
15444                         if (( logical != 512 )); then
15445                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
15446                                 return
15447                         fi
15448                         if (( tot_len != 512 )); then
15449                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15450                                 return
15451                         else
15452                                 (( num_luns += 1 ))
15453                                 tot_len=0
15454                         fi
15455                 fi
15456                 (( tot_len += ext_len ))
15457                 last_lun=$frag_lun
15458         done
15459         if (( num_luns != 2 || tot_len != 512 )); then
15460                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15461                 return
15462         fi
15463
15464         echo "FIEMAP on 2-stripe file with hole succeeded"
15465 }
15466 run_test 130c "FIEMAP (2-stripe file with hole)"
15467
15468 test_130d() {
15469         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
15470
15471         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15472         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15473         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15474                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15475
15476         trap cleanup_130 EXIT RETURN
15477
15478         local fm_file=$DIR/$tfile
15479         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
15480                         error "setstripe on $fm_file"
15481
15482         local actual_stripe_count=$($LFS getstripe -c $fm_file)
15483         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
15484                 error "dd failed on $fm_file"
15485
15486         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15487         filefrag_op=$(filefrag -ve -k $fm_file |
15488                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15489
15490         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
15491                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15492
15493         IFS=$'\n'
15494         local tot_len=0
15495         local num_luns=1
15496         for line in $filefrag_op; do
15497                 local frag_lun=$(echo $line | cut -d: -f5 |
15498                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
15499                 local ext_len=$(echo $line | cut -d: -f4)
15500                 if (( $frag_lun != $last_lun )); then
15501                         if (( tot_len != 1024 )); then
15502                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
15503                                 return
15504                         else
15505                                 (( num_luns += 1 ))
15506                                 local tot_len=0
15507                         fi
15508                 fi
15509                 (( tot_len += ext_len ))
15510                 last_lun=$frag_lun
15511         done
15512         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
15513                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
15514                 return
15515         fi
15516
15517         echo "FIEMAP on N-stripe file succeeded"
15518 }
15519 run_test 130d "FIEMAP (N-stripe file)"
15520
15521 test_130e() {
15522         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
15523
15524         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15525         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15526         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15527                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15528
15529         trap cleanup_130 EXIT RETURN
15530
15531         local fm_file=$DIR/$tfile
15532         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
15533         stack_trap "rm -f $fm_file"
15534
15535         local num_blks=512
15536         local expected_len=$(( (num_blks / 2) * 64 ))
15537         for ((i = 0; i < $num_blks; i++)); do
15538                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
15539                         conv=notrunc > /dev/null 2>&1
15540         done
15541
15542         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15543         filefrag_op=$(filefrag -ve -k $fm_file |
15544                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
15545
15546         local last_lun=$(echo $filefrag_op | cut -d: -f5)
15547
15548         IFS=$'\n'
15549         local tot_len=0
15550         local num_luns=1
15551         for line in $filefrag_op; do
15552                 local frag_lun=$(echo $line | cut -d: -f5)
15553                 local ext_len=$(echo $line | cut -d: -f4)
15554                 if (( $frag_lun != $last_lun )); then
15555                         if (( tot_len != $expected_len )); then
15556                                 error "OST$last_lun $tot_len != $expected_len"
15557                         else
15558                                 (( num_luns += 1 ))
15559                                 tot_len=0
15560                         fi
15561                 fi
15562                 (( tot_len += ext_len ))
15563                 last_lun=$frag_lun
15564         done
15565         if (( num_luns != 2 || tot_len != $expected_len )); then
15566                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
15567         fi
15568
15569         echo "FIEMAP with continuation calls succeeded"
15570 }
15571 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
15572
15573 test_130f() {
15574         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15575         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15576         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15577                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15578
15579         local fm_file=$DIR/$tfile
15580         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
15581                 error "multiop create with lov_delay_create on $fm_file"
15582
15583         filefrag -ves $fm_file || error "filefrag $fm_file failed"
15584         filefrag_extents=$(filefrag -vek $fm_file |
15585                            awk '/extents? found/ { print $2 }')
15586         if (( $filefrag_extents != 0 )); then
15587                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
15588         fi
15589
15590         rm -f $fm_file
15591 }
15592 run_test 130f "FIEMAP (unstriped file)"
15593
15594 test_130g() {
15595         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
15596                 skip "Need MDS version with at least 2.12.53 for overstriping"
15597         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
15598         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
15599         [[ "$ost1_FSTYPE" != "zfs" ]] ||
15600                 skip "LU-1941: FIEMAP unimplemented on ZFS"
15601
15602         local file=$DIR/$tfile
15603         local nr=$((OSTCOUNT * 100))
15604
15605         $LFS setstripe -C $nr -S1M $file ||
15606                 error "failed to setstripe -C $nr $file"
15607
15608         stack_trap "rm -f $file"
15609         dd if=/dev/zero of=$file count=$nr bs=1M
15610         sync
15611         nr=$($LFS getstripe -c $file)
15612
15613         local extents=$(filefrag -v $file |
15614                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
15615
15616         echo "filefrag list $extents extents in file with stripecount $nr"
15617         if (( extents < nr )); then
15618                 $LFS getstripe $file
15619                 filefrag -v $file
15620                 error "filefrag printed $extents < $nr extents"
15621         fi
15622 }
15623 run_test 130g "FIEMAP (overstripe file)"
15624
15625 # Test for writev/readv
15626 test_131a() {
15627         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
15628                 error "writev test failed"
15629         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
15630                 error "readv failed"
15631         rm -f $DIR/$tfile
15632 }
15633 run_test 131a "test iov's crossing stripe boundary for writev/readv"
15634
15635 test_131b() {
15636         local fsize=$((524288 + 1048576 + 1572864))
15637         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
15638                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15639                         error "append writev test failed"
15640
15641         ((fsize += 1572864 + 1048576))
15642         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
15643                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
15644                         error "append writev test failed"
15645         rm -f $DIR/$tfile
15646 }
15647 run_test 131b "test append writev"
15648
15649 test_131c() {
15650         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
15651         error "NOT PASS"
15652 }
15653 run_test 131c "test read/write on file w/o objects"
15654
15655 test_131d() {
15656         rwv -f $DIR/$tfile -w -n 1 1572864
15657         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
15658         if [ "$NOB" != 1572864 ]; then
15659                 error "Short read filed: read $NOB bytes instead of 1572864"
15660         fi
15661         rm -f $DIR/$tfile
15662 }
15663 run_test 131d "test short read"
15664
15665 test_131e() {
15666         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
15667         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
15668         error "read hitting hole failed"
15669         rm -f $DIR/$tfile
15670 }
15671 run_test 131e "test read hitting hole"
15672
15673 check_stats() {
15674         local facet=$1
15675         local op=$2
15676         local want=${3:-0}
15677         local res
15678
15679         # open             11 samples [usecs] 468 4793 13658 35791898
15680         case $facet in
15681         mds*) res=($(do_facet $facet \
15682                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
15683                  ;;
15684         ost*) res=($(do_facet $facet \
15685                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
15686                  ;;
15687         *) error "Wrong facet '$facet'" ;;
15688         esac
15689         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
15690         # if $want is zero, it means any stat increment is ok.
15691         if (( $want > 0 )); then
15692                 local count=${res[1]}
15693
15694                 if (( $count != $want )); then
15695                         if [[ $facet =~ "mds" ]]; then
15696                                 do_nodes $(comma_list $(mdts_nodes)) \
15697                                         $LCTL get_param mdt.*.md_stats
15698                         else
15699                                 do_nodes $(comma_list $(osts-nodes)) \
15700                                         $LCTL get_param obdfilter.*.stats
15701                         fi
15702                         error "The $op counter on $facet is $count, not $want"
15703                 fi
15704         fi
15705 }
15706
15707 test_133a() {
15708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15709         remote_ost_nodsh && skip "remote OST with nodsh"
15710         remote_mds_nodsh && skip "remote MDS with nodsh"
15711         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15712                 skip_env "MDS doesn't support rename stats"
15713
15714         local testdir=$DIR/${tdir}/stats_testdir
15715
15716         mkdir -p $DIR/${tdir}
15717
15718         # clear stats.
15719         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15720         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15721
15722         # verify mdt stats first.
15723         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15724         check_stats $SINGLEMDS "mkdir" 1
15725
15726         # clear "open" from "lfs mkdir" above
15727         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15728         touch ${testdir}/${tfile} || error "touch failed"
15729         check_stats $SINGLEMDS "open" 1
15730         check_stats $SINGLEMDS "close" 1
15731         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
15732                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
15733                 check_stats $SINGLEMDS "mknod" 2
15734         }
15735         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
15736         check_stats $SINGLEMDS "unlink" 1
15737         rm -f ${testdir}/${tfile} || error "file remove failed"
15738         check_stats $SINGLEMDS "unlink" 2
15739
15740         # remove working dir and check mdt stats again.
15741         rmdir ${testdir} || error "rmdir failed"
15742         check_stats $SINGLEMDS "rmdir" 1
15743
15744         local testdir1=$DIR/${tdir}/stats_testdir1
15745         mkdir_on_mdt0 -p ${testdir}
15746         mkdir_on_mdt0 -p ${testdir1}
15747         touch ${testdir1}/test1
15748         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
15749         check_stats $SINGLEMDS "crossdir_rename" 1
15750
15751         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
15752         check_stats $SINGLEMDS "samedir_rename" 1
15753
15754         rm -rf $DIR/${tdir}
15755 }
15756 run_test 133a "Verifying MDT stats ========================================"
15757
15758 test_133b() {
15759         local res
15760
15761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15762         remote_ost_nodsh && skip "remote OST with nodsh"
15763         remote_mds_nodsh && skip "remote MDS with nodsh"
15764
15765         local testdir=$DIR/${tdir}/stats_testdir
15766
15767         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
15768         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
15769         touch ${testdir}/${tfile} || error "touch failed"
15770         cancel_lru_locks mdc
15771
15772         # clear stats.
15773         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15774         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15775
15776         # extra mdt stats verification.
15777         chmod 444 ${testdir}/${tfile} || error "chmod failed"
15778         check_stats $SINGLEMDS "setattr" 1
15779         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15780         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
15781         then            # LU-1740
15782                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
15783                 check_stats $SINGLEMDS "getattr" 1
15784         fi
15785         rm -rf $DIR/${tdir}
15786
15787         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
15788         # so the check below is not reliable
15789         [ $MDSCOUNT -eq 1 ] || return 0
15790
15791         # Sleep to avoid a cached response.
15792         #define OBD_STATFS_CACHE_SECONDS 1
15793         sleep 2
15794         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15795         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15796         $LFS df || error "lfs failed"
15797         check_stats $SINGLEMDS "statfs" 1
15798
15799         # check aggregated statfs (LU-10018)
15800         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
15801                 return 0
15802         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
15803                 return 0
15804         sleep 2
15805         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15806         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
15807         df $DIR
15808         check_stats $SINGLEMDS "statfs" 1
15809
15810         # We want to check that the client didn't send OST_STATFS to
15811         # ost1 but the MDT also uses OST_STATFS for precreate. So some
15812         # extra care is needed here.
15813         if remote_mds; then
15814                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
15815                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
15816
15817                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
15818                 [ "$res" ] && error "OST got STATFS"
15819         fi
15820
15821         return 0
15822 }
15823 run_test 133b "Verifying extra MDT stats =================================="
15824
15825 test_133c() {
15826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15827         remote_ost_nodsh && skip "remote OST with nodsh"
15828         remote_mds_nodsh && skip "remote MDS with nodsh"
15829
15830         local testdir=$DIR/$tdir/stats_testdir
15831
15832         test_mkdir -p $testdir
15833
15834         # verify obdfilter stats.
15835         $LFS setstripe -c 1 -i 0 $testdir/$tfile
15836         sync
15837         cancel_lru_locks osc
15838         wait_delete_completed
15839
15840         # clear stats.
15841         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
15842         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
15843
15844         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
15845                 error "dd failed"
15846         sync
15847         cancel_lru_locks osc
15848         check_stats ost1 "write" 1
15849
15850         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
15851         check_stats ost1 "read" 1
15852
15853         > $testdir/$tfile || error "truncate failed"
15854         check_stats ost1 "punch" 1
15855
15856         rm -f $testdir/$tfile || error "file remove failed"
15857         wait_delete_completed
15858         check_stats ost1 "destroy" 1
15859
15860         rm -rf $DIR/$tdir
15861 }
15862 run_test 133c "Verifying OST stats ========================================"
15863
15864 order_2() {
15865         local value=$1
15866         local orig=$value
15867         local order=1
15868
15869         while [ $value -ge 2 ]; do
15870                 order=$((order*2))
15871                 value=$((value/2))
15872         done
15873
15874         if [ $orig -gt $order ]; then
15875                 order=$((order*2))
15876         fi
15877         echo $order
15878 }
15879
15880 size_in_KMGT() {
15881     local value=$1
15882     local size=('K' 'M' 'G' 'T');
15883     local i=0
15884     local size_string=$value
15885
15886     while [ $value -ge 1024 ]; do
15887         if [ $i -gt 3 ]; then
15888             #T is the biggest unit we get here, if that is bigger,
15889             #just return XXXT
15890             size_string=${value}T
15891             break
15892         fi
15893         value=$((value >> 10))
15894         if [ $value -lt 1024 ]; then
15895             size_string=${value}${size[$i]}
15896             break
15897         fi
15898         i=$((i + 1))
15899     done
15900
15901     echo $size_string
15902 }
15903
15904 get_rename_size() {
15905         local size=$1
15906         local context=${2:-.}
15907         local sample=$(do_facet $SINGLEMDS $LCTL \
15908                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15909                 grep -A1 $context |
15910                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15911         echo $sample
15912 }
15913
15914 test_133d() {
15915         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15916         remote_ost_nodsh && skip "remote OST with nodsh"
15917         remote_mds_nodsh && skip "remote MDS with nodsh"
15918         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15919                 skip_env "MDS doesn't support rename stats"
15920
15921         local testdir1=$DIR/${tdir}/stats_testdir1
15922         local testdir2=$DIR/${tdir}/stats_testdir2
15923         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15924
15925         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15926
15927         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15928         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15929
15930         createmany -o $testdir1/test 512 || error "createmany failed"
15931
15932         # check samedir rename size
15933         mv ${testdir1}/test0 ${testdir1}/test_0
15934
15935         local testdir1_size=$(ls -l $DIR/${tdir} |
15936                 awk '/stats_testdir1/ {print $5}')
15937         local testdir2_size=$(ls -l $DIR/${tdir} |
15938                 awk '/stats_testdir2/ {print $5}')
15939
15940         testdir1_size=$(order_2 $testdir1_size)
15941         testdir2_size=$(order_2 $testdir2_size)
15942
15943         testdir1_size=$(size_in_KMGT $testdir1_size)
15944         testdir2_size=$(size_in_KMGT $testdir2_size)
15945
15946         echo "source rename dir size: ${testdir1_size}"
15947         echo "target rename dir size: ${testdir2_size}"
15948
15949         local cmd="do_facet $SINGLEMDS $LCTL "
15950         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15951
15952         eval $cmd || error "$cmd failed"
15953         local samedir=$($cmd | grep 'same_dir')
15954         local same_sample=$(get_rename_size $testdir1_size)
15955         [ -z "$samedir" ] && error "samedir_rename_size count error"
15956         [[ $same_sample -eq 1 ]] ||
15957                 error "samedir_rename_size error $same_sample"
15958         echo "Check same dir rename stats success"
15959
15960         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15961
15962         # check crossdir rename size
15963         mv ${testdir1}/test_0 ${testdir2}/test_0
15964
15965         testdir1_size=$(ls -l $DIR/${tdir} |
15966                 awk '/stats_testdir1/ {print $5}')
15967         testdir2_size=$(ls -l $DIR/${tdir} |
15968                 awk '/stats_testdir2/ {print $5}')
15969
15970         testdir1_size=$(order_2 $testdir1_size)
15971         testdir2_size=$(order_2 $testdir2_size)
15972
15973         testdir1_size=$(size_in_KMGT $testdir1_size)
15974         testdir2_size=$(size_in_KMGT $testdir2_size)
15975
15976         echo "source rename dir size: ${testdir1_size}"
15977         echo "target rename dir size: ${testdir2_size}"
15978
15979         eval $cmd || error "$cmd failed"
15980         local crossdir=$($cmd | grep 'crossdir')
15981         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15982         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15983         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15984         [[ $src_sample -eq 1 ]] ||
15985                 error "crossdir_rename_size error $src_sample"
15986         [[ $tgt_sample -eq 1 ]] ||
15987                 error "crossdir_rename_size error $tgt_sample"
15988         echo "Check cross dir rename stats success"
15989         rm -rf $DIR/${tdir}
15990 }
15991 run_test 133d "Verifying rename_stats ========================================"
15992
15993 test_133e() {
15994         remote_mds_nodsh && skip "remote MDS with nodsh"
15995         remote_ost_nodsh && skip "remote OST with nodsh"
15996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15997
15998         local testdir=$DIR/${tdir}/stats_testdir
15999         local ctr f0 f1 bs=32768 count=42 sum
16000
16001         mkdir -p ${testdir} || error "mkdir failed"
16002
16003         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
16004
16005         for ctr in {write,read}_bytes; do
16006                 sync
16007                 cancel_lru_locks osc
16008
16009                 do_facet ost1 $LCTL set_param -n \
16010                         "obdfilter.*.exports.clear=clear"
16011
16012                 if [ $ctr = write_bytes ]; then
16013                         f0=/dev/zero
16014                         f1=${testdir}/${tfile}
16015                 else
16016                         f0=${testdir}/${tfile}
16017                         f1=/dev/null
16018                 fi
16019
16020                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
16021                         error "dd failed"
16022                 sync
16023                 cancel_lru_locks osc
16024
16025                 sum=$(do_facet ost1 $LCTL get_param \
16026                         "obdfilter.*.exports.*.stats" |
16027                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
16028                                 $1 == ctr { sum += $7 }
16029                                 END { printf("%0.0f", sum) }')
16030
16031                 if ((sum != bs * count)); then
16032                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
16033                 fi
16034         done
16035
16036         rm -rf $DIR/${tdir}
16037 }
16038 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
16039
16040 test_133f() {
16041         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
16042                 skip "too old lustre for get_param -R ($facet_ver)"
16043
16044         # verifying readability.
16045         $LCTL get_param -R '*' &> /dev/null
16046
16047         # Verifing writability with badarea_io.
16048         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16049         local skipped_params='force_lbug|changelog_mask|daemon_file'
16050         $LCTL list_param -FR '*' | grep '=' | tr -d = |
16051                 egrep -v "$skipped_params" |
16052                 xargs -n 1 find $proc_dirs -name |
16053                 xargs -n 1 badarea_io ||
16054                 error "client badarea_io failed"
16055
16056         # remount the FS in case writes/reads /proc break the FS
16057         cleanup || error "failed to unmount"
16058         setup || error "failed to setup"
16059 }
16060 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
16061
16062 test_133g() {
16063         remote_mds_nodsh && skip "remote MDS with nodsh"
16064         remote_ost_nodsh && skip "remote OST with nodsh"
16065
16066         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
16067         local proc_dirs_str=$(eval echo $proc_dirs)
16068         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
16069         local facet
16070         for facet in mds1 ost1; do
16071                 local facet_ver=$(lustre_version_code $facet)
16072                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
16073                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
16074                 else
16075                         log "$facet: too old lustre for get_param -R"
16076                 fi
16077                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
16078                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
16079                                 tr -d = | egrep -v $skipped_params |
16080                                 xargs -n 1 find $proc_dirs_str -name |
16081                                 xargs -n 1 badarea_io" ||
16082                                         error "$facet badarea_io failed"
16083                 else
16084                         skip_noexit "$facet: too old lustre for get_param -R"
16085                 fi
16086         done
16087
16088         # remount the FS in case writes/reads /proc break the FS
16089         cleanup || error "failed to unmount"
16090         setup || error "failed to setup"
16091 }
16092 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
16093
16094 test_133h() {
16095         remote_mds_nodsh && skip "remote MDS with nodsh"
16096         remote_ost_nodsh && skip "remote OST with nodsh"
16097         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
16098                 skip "Need MDS version at least 2.9.54"
16099
16100         local facet
16101         for facet in client mds1 ost1; do
16102                 # Get the list of files that are missing the terminating newline
16103                 local plist=$(do_facet $facet
16104                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
16105                 local ent
16106                 for ent in $plist; do
16107                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
16108                                 awk -v FS='\v' -v RS='\v\v' \
16109                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
16110                                         print FILENAME}'" 2>/dev/null)
16111                         [ -z $missing ] || {
16112                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
16113                                 error "file does not end with newline: $facet-$ent"
16114                         }
16115                 done
16116         done
16117 }
16118 run_test 133h "Proc files should end with newlines"
16119
16120 test_134a() {
16121         remote_mds_nodsh && skip "remote MDS with nodsh"
16122         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16123                 skip "Need MDS version at least 2.7.54"
16124
16125         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16126         cancel_lru_locks mdc
16127
16128         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
16129         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16130         [ $unused -eq 0 ] || error "$unused locks are not cleared"
16131
16132         local nr=1000
16133         createmany -o $DIR/$tdir/f $nr ||
16134                 error "failed to create $nr files in $DIR/$tdir"
16135         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
16136
16137         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
16138         do_facet mds1 $LCTL set_param fail_loc=0x327
16139         do_facet mds1 $LCTL set_param fail_val=500
16140         touch $DIR/$tdir/m
16141
16142         echo "sleep 10 seconds ..."
16143         sleep 10
16144         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
16145
16146         do_facet mds1 $LCTL set_param fail_loc=0
16147         do_facet mds1 $LCTL set_param fail_val=0
16148         [ $lck_cnt -lt $unused ] ||
16149                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
16150
16151         rm $DIR/$tdir/m
16152         unlinkmany $DIR/$tdir/f $nr
16153 }
16154 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
16155
16156 test_134b() {
16157         remote_mds_nodsh && skip "remote MDS with nodsh"
16158         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
16159                 skip "Need MDS version at least 2.7.54"
16160
16161         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
16162         cancel_lru_locks mdc
16163
16164         local low_wm=$(do_facet mds1 $LCTL get_param -n \
16165                         ldlm.lock_reclaim_threshold_mb)
16166         # disable reclaim temporarily
16167         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
16168
16169         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
16170         do_facet mds1 $LCTL set_param fail_loc=0x328
16171         do_facet mds1 $LCTL set_param fail_val=500
16172
16173         $LCTL set_param debug=+trace
16174
16175         local nr=600
16176         createmany -o $DIR/$tdir/f $nr &
16177         local create_pid=$!
16178
16179         echo "Sleep $TIMEOUT seconds ..."
16180         sleep $TIMEOUT
16181         if ! ps -p $create_pid  > /dev/null 2>&1; then
16182                 do_facet mds1 $LCTL set_param fail_loc=0
16183                 do_facet mds1 $LCTL set_param fail_val=0
16184                 do_facet mds1 $LCTL set_param \
16185                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
16186                 error "createmany finished incorrectly!"
16187         fi
16188         do_facet mds1 $LCTL set_param fail_loc=0
16189         do_facet mds1 $LCTL set_param fail_val=0
16190         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
16191         wait $create_pid || return 1
16192
16193         unlinkmany $DIR/$tdir/f $nr
16194 }
16195 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
16196
16197 test_135() {
16198         remote_mds_nodsh && skip "remote MDS with nodsh"
16199         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16200                 skip "Need MDS version at least 2.13.50"
16201         local fname
16202
16203         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16204
16205 #define OBD_FAIL_PLAIN_RECORDS 0x1319
16206         #set only one record at plain llog
16207         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
16208
16209         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16210
16211         #fill already existed plain llog each 64767
16212         #wrapping whole catalog
16213         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16214
16215         createmany -o $DIR/$tdir/$tfile_ 64700
16216         for (( i = 0; i < 64700; i = i + 2 ))
16217         do
16218                 rm $DIR/$tdir/$tfile_$i &
16219                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16220                 local pid=$!
16221                 wait $pid
16222         done
16223
16224         #waiting osp synchronization
16225         wait_delete_completed
16226 }
16227 run_test 135 "Race catalog processing"
16228
16229 test_136() {
16230         remote_mds_nodsh && skip "remote MDS with nodsh"
16231         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
16232                 skip "Need MDS version at least 2.13.50"
16233         local fname
16234
16235         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
16236         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
16237         #set only one record at plain llog
16238 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
16239         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
16240
16241         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
16242
16243         #fill already existed 2 plain llogs each 64767
16244         #wrapping whole catalog
16245         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
16246         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
16247         wait_delete_completed
16248
16249         createmany -o $DIR/$tdir/$tfile_ 10
16250         sleep 25
16251
16252         do_facet $SINGLEMDS $LCTL set_param fail_val=3
16253         for (( i = 0; i < 10; i = i + 3 ))
16254         do
16255                 rm $DIR/$tdir/$tfile_$i &
16256                 rm $DIR/$tdir/$tfile_$((i + 1)) &
16257                 local pid=$!
16258                 wait $pid
16259                 sleep 7
16260                 rm $DIR/$tdir/$tfile_$((i + 2)) &
16261         done
16262
16263         #waiting osp synchronization
16264         wait_delete_completed
16265 }
16266 run_test 136 "Race catalog processing 2"
16267
16268 test_140() { #bug-17379
16269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16270
16271         test_mkdir $DIR/$tdir
16272         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
16273         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
16274
16275         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
16276         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
16277         local i=0
16278         while i=$((i + 1)); do
16279                 test_mkdir $i
16280                 cd $i || error "Changing to $i"
16281                 ln -s ../stat stat || error "Creating stat symlink"
16282                 # Read the symlink until ELOOP present,
16283                 # not LBUGing the system is considered success,
16284                 # we didn't overrun the stack.
16285                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
16286                 if [ $ret -ne 0 ]; then
16287                         if [ $ret -eq 40 ]; then
16288                                 break  # -ELOOP
16289                         else
16290                                 error "Open stat symlink"
16291                                         return
16292                         fi
16293                 fi
16294         done
16295         i=$((i - 1))
16296         echo "The symlink depth = $i"
16297         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
16298                 error "Invalid symlink depth"
16299
16300         # Test recursive symlink
16301         ln -s symlink_self symlink_self
16302         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
16303         echo "open symlink_self returns $ret"
16304         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
16305 }
16306 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
16307
16308 test_150a() {
16309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16310
16311         local TF="$TMP/$tfile"
16312
16313         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16314         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16315         cp $TF $DIR/$tfile
16316         cancel_lru_locks $OSC
16317         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
16318         remount_client $MOUNT
16319         df -P $MOUNT
16320         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
16321
16322         $TRUNCATE $TF 6000
16323         $TRUNCATE $DIR/$tfile 6000
16324         cancel_lru_locks $OSC
16325         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
16326
16327         echo "12345" >>$TF
16328         echo "12345" >>$DIR/$tfile
16329         cancel_lru_locks $OSC
16330         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
16331
16332         echo "12345" >>$TF
16333         echo "12345" >>$DIR/$tfile
16334         cancel_lru_locks $OSC
16335         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
16336 }
16337 run_test 150a "truncate/append tests"
16338
16339 test_150b() {
16340         check_set_fallocate_or_skip
16341         local out
16342
16343         touch $DIR/$tfile
16344         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16345         out=$(check_fallocate $DIR/$tfile 2>&1) ||
16346                 skip_eopnotsupp "$out|check_fallocate failed"
16347 }
16348 run_test 150b "Verify fallocate (prealloc) functionality"
16349
16350 test_150bb() {
16351         check_set_fallocate_or_skip
16352
16353         touch $DIR/$tfile
16354         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16355         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
16356         > $DIR/$tfile
16357         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16358         # precomputed md5sum for 20MB of zeroes
16359         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
16360         local sum=($(md5sum $DIR/$tfile))
16361
16362         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
16363
16364         check_set_fallocate 1
16365
16366         > $DIR/$tfile
16367         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
16368         sum=($(md5sum $DIR/$tfile))
16369
16370         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
16371 }
16372 run_test 150bb "Verify fallocate modes both zero space"
16373
16374 test_150c() {
16375         check_set_fallocate_or_skip
16376         local striping="-c2"
16377
16378         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16379         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
16380         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
16381         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16382         local want=$((OSTCOUNT * 1048576))
16383
16384         # Must allocate all requested space, not more than 5% extra
16385         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16386                 error "bytes $bytes is not $want"
16387
16388         rm -f $DIR/$tfile
16389
16390         echo "verify fallocate on PFL file"
16391
16392         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16393
16394         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
16395                 error "Create $DIR/$tfile failed"
16396         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
16397         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
16398         want=$((512 * 1048576))
16399
16400         # Must allocate all requested space, not more than 5% extra
16401         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16402                 error "bytes $bytes is not $want"
16403 }
16404 run_test 150c "Verify fallocate Size and Blocks"
16405
16406 test_150d() {
16407         check_set_fallocate_or_skip
16408         local striping="-c2"
16409
16410         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
16411
16412         stack_trap "rm -f $DIR/$tdir; wait_delete_completed"
16413         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
16414                 error "setstripe failed"
16415         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
16416         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
16417         local want=$((OSTCOUNT * 1048576))
16418
16419         # Must allocate all requested space, not more than 5% extra
16420         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
16421                 error "bytes $bytes is not $want"
16422 }
16423 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
16424
16425 test_150e() {
16426         check_set_fallocate_or_skip
16427
16428         echo "df before:"
16429         $LFS df
16430         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16431         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16432                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16433
16434         # Find OST with Minimum Size
16435         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16436                        sort -un | head -1)
16437
16438         # Get 100MB per OST of the available space to reduce run time
16439         # else 60% of the available space if we are running SLOW tests
16440         if [ $SLOW == "no" ]; then
16441                 local space=$((1024 * 100 * OSTCOUNT))
16442         else
16443                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
16444         fi
16445
16446         fallocate -l${space}k $DIR/$tfile ||
16447                 error "fallocate ${space}k $DIR/$tfile failed"
16448         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
16449
16450         # get size immediately after fallocate. This should be correctly
16451         # updated
16452         local size=$(stat -c '%s' $DIR/$tfile)
16453         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
16454
16455         # Sleep for a while for statfs to get updated. And not pull from cache.
16456         sleep 2
16457
16458         echo "df after fallocate:"
16459         $LFS df
16460
16461         (( size / 1024 == space )) || error "size $size != requested $space"
16462         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
16463                 error "used $used < space $space"
16464
16465         rm $DIR/$tfile || error "rm failed"
16466         sync
16467         wait_delete_completed
16468
16469         echo "df after unlink:"
16470         $LFS df
16471 }
16472 run_test 150e "Verify 60% of available OST space consumed by fallocate"
16473
16474 test_150f() {
16475         local size
16476         local blocks
16477         local want_size_before=20480 # in bytes
16478         local want_blocks_before=40 # 512 sized blocks
16479         local want_blocks_after=24  # 512 sized blocks
16480         local length=$(((want_blocks_before - want_blocks_after) * 512))
16481
16482         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16483                 skip "need at least 2.14.0 for fallocate punch"
16484
16485         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16486                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16487         fi
16488
16489         check_set_fallocate_or_skip
16490         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16491
16492         [[ "x$DOM" == "xyes" ]] &&
16493                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
16494
16495         echo "Verify fallocate punch: Range within the file range"
16496         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16497                 error "dd failed for bs 4096 and count 5"
16498
16499         # Call fallocate with punch range which is within the file range
16500         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
16501                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
16502         # client must see changes immediately after fallocate
16503         size=$(stat -c '%s' $DIR/$tfile)
16504         blocks=$(stat -c '%b' $DIR/$tfile)
16505
16506         # Verify punch worked.
16507         (( blocks == want_blocks_after )) ||
16508                 error "punch failed: blocks $blocks != $want_blocks_after"
16509
16510         (( size == want_size_before )) ||
16511                 error "punch failed: size $size != $want_size_before"
16512
16513         # Verify there is hole in file
16514         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
16515         # precomputed md5sum
16516         local expect="4a9a834a2db02452929c0a348273b4aa"
16517
16518         cksum=($(md5sum $DIR/$tfile))
16519         [[ "${cksum[0]}" == "$expect" ]] ||
16520                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16521
16522         # Start second sub-case for fallocate punch.
16523         echo "Verify fallocate punch: Range overlapping and less than blocksize"
16524         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
16525                 error "dd failed for bs 4096 and count 5"
16526
16527         # Punch range less than block size will have no change in block count
16528         want_blocks_after=40  # 512 sized blocks
16529
16530         # Punch overlaps two blocks and less than blocksize
16531         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
16532                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
16533         size=$(stat -c '%s' $DIR/$tfile)
16534         blocks=$(stat -c '%b' $DIR/$tfile)
16535
16536         # Verify punch worked.
16537         (( blocks == want_blocks_after )) ||
16538                 error "punch failed: blocks $blocks != $want_blocks_after"
16539
16540         (( size == want_size_before )) ||
16541                 error "punch failed: size $size != $want_size_before"
16542
16543         # Verify if range is really zero'ed out. We expect Zeros.
16544         # precomputed md5sum
16545         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
16546         cksum=($(md5sum $DIR/$tfile))
16547         [[ "${cksum[0]}" == "$expect" ]] ||
16548                 error "unexpected MD5SUM after punch: ${cksum[0]}"
16549 }
16550 run_test 150f "Verify fallocate punch functionality"
16551
16552 test_150g() {
16553         local space
16554         local size
16555         local blocks
16556         local blocks_after
16557         local size_after
16558         local BS=4096 # Block size in bytes
16559
16560         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
16561                 skip "need at least 2.14.0 for fallocate punch"
16562
16563         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
16564                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
16565         fi
16566
16567         check_set_fallocate_or_skip
16568         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
16569
16570         if [[ "x$DOM" == "xyes" ]]; then
16571                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
16572                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
16573         else
16574                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
16575                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
16576         fi
16577
16578         # Get 100MB per OST of the available space to reduce run time
16579         # else 60% of the available space if we are running SLOW tests
16580         if [ $SLOW == "no" ]; then
16581                 space=$((1024 * 100 * OSTCOUNT))
16582         else
16583                 # Find OST with Minimum Size
16584                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
16585                         sort -un | head -1)
16586                 echo "min size OST: $space"
16587                 space=$(((space * 60)/100 * OSTCOUNT))
16588         fi
16589         # space in 1k units, round to 4k blocks
16590         local blkcount=$((space * 1024 / $BS))
16591
16592         echo "Verify fallocate punch: Very large Range"
16593         fallocate -l${space}k $DIR/$tfile ||
16594                 error "fallocate ${space}k $DIR/$tfile failed"
16595         # write 1M at the end, start and in the middle
16596         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
16597                 error "dd failed: bs $BS count 256"
16598         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
16599                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
16600         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
16601                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
16602
16603         # Gather stats.
16604         size=$(stat -c '%s' $DIR/$tfile)
16605
16606         # gather punch length.
16607         local punch_size=$((size - (BS * 2)))
16608
16609         echo "punch_size = $punch_size"
16610         echo "size - punch_size: $((size - punch_size))"
16611         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
16612
16613         # Call fallocate to punch all except 2 blocks. We leave the
16614         # first and the last block
16615         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
16616         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
16617                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
16618
16619         size_after=$(stat -c '%s' $DIR/$tfile)
16620         blocks_after=$(stat -c '%b' $DIR/$tfile)
16621
16622         # Verify punch worked.
16623         # Size should be kept
16624         (( size == size_after )) ||
16625                 error "punch failed: size $size != $size_after"
16626
16627         # two 4k data blocks to remain plus possible 1 extra extent block
16628         (( blocks_after <= ((BS / 512) * 3) )) ||
16629                 error "too many blocks remains: $blocks_after"
16630
16631         # Verify that file has hole between the first and the last blocks
16632         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
16633         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
16634
16635         echo "Hole at [$hole_start, $hole_end)"
16636         (( hole_start == BS )) ||
16637                 error "no hole at offset $BS after punch"
16638
16639         (( hole_end == BS + punch_size )) ||
16640                 error "data at offset $hole_end < $((BS + punch_size))"
16641 }
16642 run_test 150g "Verify fallocate punch on large range"
16643
16644 test_150h() {
16645         local file=$DIR/$tfile
16646         local size
16647
16648         check_set_fallocate_or_skip
16649         statx_supported || skip_env "Test must be statx() syscall supported"
16650
16651         # fallocate() does not update the size information on the MDT
16652         fallocate -l 16K $file || error "failed to fallocate $file"
16653         cancel_lru_locks $OSC
16654         # STATX with cached-always mode will not send glimpse RPCs to OST,
16655         # it uses the caching attrs on the client side as much as possible.
16656         size=$($STATX --cached=always -c %s $file)
16657         [ $size == 16384 ] ||
16658                 error "size after fallocate() is $size, expected 16384"
16659 }
16660 run_test 150h "Verify extend fallocate updates the file size"
16661
16662 #LU-2902 roc_hit was not able to read all values from lproc
16663 function roc_hit_init() {
16664         local list=$(comma_list $(osts_nodes))
16665         local dir=$DIR/$tdir-check
16666         local file=$dir/$tfile
16667         local BEFORE
16668         local AFTER
16669         local idx
16670
16671         test_mkdir $dir
16672         #use setstripe to do a write to every ost
16673         for i in $(seq 0 $((OSTCOUNT-1))); do
16674                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
16675                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
16676                 idx=$(printf %04x $i)
16677                 BEFORE=$(get_osd_param $list *OST*$idx stats |
16678                         awk '$1 == "cache_access" {sum += $7}
16679                                 END { printf("%0.0f", sum) }')
16680
16681                 cancel_lru_locks osc
16682                 cat $file >/dev/null
16683
16684                 AFTER=$(get_osd_param $list *OST*$idx stats |
16685                         awk '$1 == "cache_access" {sum += $7}
16686                                 END { printf("%0.0f", sum) }')
16687
16688                 echo BEFORE:$BEFORE AFTER:$AFTER
16689                 if ! let "AFTER - BEFORE == 4"; then
16690                         rm -rf $dir
16691                         error "roc_hit is not safe to use"
16692                 fi
16693                 rm $file
16694         done
16695
16696         rm -rf $dir
16697 }
16698
16699 function roc_hit() {
16700         local list=$(comma_list $(osts_nodes))
16701         echo $(get_osd_param $list '' stats |
16702                 awk '$1 == "cache_hit" {sum += $7}
16703                         END { printf("%0.0f", sum) }')
16704 }
16705
16706 function set_cache() {
16707         local on=1
16708
16709         if [ "$2" == "off" ]; then
16710                 on=0;
16711         fi
16712         local list=$(comma_list $(osts_nodes))
16713         set_osd_param $list '' $1_cache_enable $on
16714
16715         cancel_lru_locks osc
16716 }
16717
16718 test_151() {
16719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16720         remote_ost_nodsh && skip "remote OST with nodsh"
16721         (( CLIENT_VERSION == OST1_VERSION )) ||
16722                 skip "LU-13081: no interop testing for OSS cache"
16723
16724         local CPAGES=3
16725         local list=$(comma_list $(osts_nodes))
16726
16727         # check whether obdfilter is cache capable at all
16728         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
16729                 skip "not cache-capable obdfilter"
16730         fi
16731
16732         # check cache is enabled on all obdfilters
16733         if get_osd_param $list '' read_cache_enable | grep 0; then
16734                 skip "oss cache is disabled"
16735         fi
16736
16737         set_osd_param $list '' writethrough_cache_enable 1
16738
16739         # check write cache is enabled on all obdfilters
16740         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
16741                 skip "oss write cache is NOT enabled"
16742         fi
16743
16744         roc_hit_init
16745
16746         #define OBD_FAIL_OBD_NO_LRU  0x609
16747         do_nodes $list $LCTL set_param fail_loc=0x609
16748
16749         # pages should be in the case right after write
16750         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
16751                 error "dd failed"
16752
16753         local BEFORE=$(roc_hit)
16754         cancel_lru_locks osc
16755         cat $DIR/$tfile >/dev/null
16756         local AFTER=$(roc_hit)
16757
16758         do_nodes $list $LCTL set_param fail_loc=0
16759
16760         if ! let "AFTER - BEFORE == CPAGES"; then
16761                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
16762         fi
16763
16764         cancel_lru_locks osc
16765         # invalidates OST cache
16766         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
16767         set_osd_param $list '' read_cache_enable 0
16768         cat $DIR/$tfile >/dev/null
16769
16770         # now data shouldn't be found in the cache
16771         BEFORE=$(roc_hit)
16772         cancel_lru_locks osc
16773         cat $DIR/$tfile >/dev/null
16774         AFTER=$(roc_hit)
16775         if let "AFTER - BEFORE != 0"; then
16776                 error "IN CACHE: before: $BEFORE, after: $AFTER"
16777         fi
16778
16779         set_osd_param $list '' read_cache_enable 1
16780         rm -f $DIR/$tfile
16781 }
16782 run_test 151 "test cache on oss and controls ==============================="
16783
16784 test_152() {
16785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16786
16787         local TF="$TMP/$tfile"
16788
16789         # simulate ENOMEM during write
16790 #define OBD_FAIL_OST_NOMEM      0x226
16791         lctl set_param fail_loc=0x80000226
16792         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
16793         cp $TF $DIR/$tfile
16794         sync || error "sync failed"
16795         lctl set_param fail_loc=0
16796
16797         # discard client's cache
16798         cancel_lru_locks osc
16799
16800         # simulate ENOMEM during read
16801         lctl set_param fail_loc=0x80000226
16802         cmp $TF $DIR/$tfile || error "cmp failed"
16803         lctl set_param fail_loc=0
16804
16805         rm -f $TF
16806 }
16807 run_test 152 "test read/write with enomem ============================"
16808
16809 test_153() {
16810         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
16811 }
16812 run_test 153 "test if fdatasync does not crash ======================="
16813
16814 dot_lustre_fid_permission_check() {
16815         local fid=$1
16816         local ffid=$MOUNT/.lustre/fid/$fid
16817         local test_dir=$2
16818
16819         echo "stat fid $fid"
16820         stat $ffid || error "stat $ffid failed."
16821         echo "touch fid $fid"
16822         touch $ffid || error "touch $ffid failed."
16823         echo "write to fid $fid"
16824         cat /etc/hosts > $ffid || error "write $ffid failed."
16825         echo "read fid $fid"
16826         diff /etc/hosts $ffid || error "read $ffid failed."
16827         echo "append write to fid $fid"
16828         cat /etc/hosts >> $ffid || error "append write $ffid failed."
16829         echo "rename fid $fid"
16830         mv $ffid $test_dir/$tfile.1 &&
16831                 error "rename $ffid to $tfile.1 should fail."
16832         touch $test_dir/$tfile.1
16833         mv $test_dir/$tfile.1 $ffid &&
16834                 error "rename $tfile.1 to $ffid should fail."
16835         rm -f $test_dir/$tfile.1
16836         echo "truncate fid $fid"
16837         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
16838         echo "link fid $fid"
16839         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
16840         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
16841                 id $USER0 || skip_env "missing user $USER0"
16842                 echo "setfacl fid $fid"
16843                 setfacl -R -m u:$USER0:rwx $ffid ||
16844                         error "setfacl $ffid failed"
16845                 echo "getfacl fid $fid"
16846                 getfacl $ffid || error "getfacl $ffid failed."
16847         fi
16848         echo "unlink fid $fid"
16849         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
16850         echo "mknod fid $fid"
16851         mknod $ffid c 1 3 && error "mknod $ffid should fail."
16852
16853         fid=[0xf00000400:0x1:0x0]
16854         ffid=$MOUNT/.lustre/fid/$fid
16855
16856         echo "stat non-exist fid $fid"
16857         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
16858         echo "write to non-exist fid $fid"
16859         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
16860         echo "link new fid $fid"
16861         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16862
16863         mkdir -p $test_dir/$tdir
16864         touch $test_dir/$tdir/$tfile
16865         fid=$($LFS path2fid $test_dir/$tdir)
16866         rc=$?
16867         [ $rc -ne 0 ] &&
16868                 error "error: could not get fid for $test_dir/$dir/$tfile."
16869
16870         ffid=$MOUNT/.lustre/fid/$fid
16871
16872         echo "ls $fid"
16873         ls $ffid || error "ls $ffid failed."
16874         echo "touch $fid/$tfile.1"
16875         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16876
16877         echo "touch $MOUNT/.lustre/fid/$tfile"
16878         touch $MOUNT/.lustre/fid/$tfile && \
16879                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16880
16881         echo "setxattr to $MOUNT/.lustre/fid"
16882         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16883
16884         echo "listxattr for $MOUNT/.lustre/fid"
16885         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16886
16887         echo "delxattr from $MOUNT/.lustre/fid"
16888         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16889
16890         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16891         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16892                 error "touch invalid fid should fail."
16893
16894         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16895         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16896                 error "touch non-normal fid should fail."
16897
16898         echo "rename $tdir to $MOUNT/.lustre/fid"
16899         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16900                 error "rename to $MOUNT/.lustre/fid should fail."
16901
16902         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16903         then            # LU-3547
16904                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16905                 local new_obf_mode=777
16906
16907                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16908                 chmod $new_obf_mode $DIR/.lustre/fid ||
16909                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16910
16911                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16912                 [ $obf_mode -eq $new_obf_mode ] ||
16913                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16914
16915                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16916                 chmod $old_obf_mode $DIR/.lustre/fid ||
16917                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16918         fi
16919
16920         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16921         fid=$($LFS path2fid $test_dir/$tfile-2)
16922
16923         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16924         then # LU-5424
16925                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16926                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16927                         error "create lov data thru .lustre failed"
16928         fi
16929         echo "cp /etc/passwd $test_dir/$tfile-2"
16930         cp /etc/passwd $test_dir/$tfile-2 ||
16931                 error "copy to $test_dir/$tfile-2 failed."
16932         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16933         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16934                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16935
16936         rm -rf $test_dir/tfile.lnk
16937         rm -rf $test_dir/$tfile-2
16938 }
16939
16940 test_154A() {
16941         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16942                 skip "Need MDS version at least 2.4.1"
16943
16944         local tf=$DIR/$tfile
16945         touch $tf
16946
16947         local fid=$($LFS path2fid $tf)
16948         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16949
16950         # check that we get the same pathname back
16951         local rootpath
16952         local found
16953         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16954                 echo "$rootpath $fid"
16955                 found=$($LFS fid2path $rootpath "$fid")
16956                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16957                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16958         done
16959
16960         # check wrong root path format
16961         rootpath=$MOUNT"_wrong"
16962         found=$($LFS fid2path $rootpath "$fid")
16963         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16964 }
16965 run_test 154A "lfs path2fid and fid2path basic checks"
16966
16967 test_154B() {
16968         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16969                 skip "Need MDS version at least 2.4.1"
16970
16971         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16972         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16973         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16974         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16975
16976         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16977         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16978
16979         # check that we get the same pathname
16980         echo "PFID: $PFID, name: $name"
16981         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16982         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16983         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16984                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16985
16986         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16987 }
16988 run_test 154B "verify the ll_decode_linkea tool"
16989
16990 test_154a() {
16991         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16992         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16993         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16994                 skip "Need MDS version at least 2.2.51"
16995         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16996
16997         cp /etc/hosts $DIR/$tfile
16998
16999         fid=$($LFS path2fid $DIR/$tfile)
17000         rc=$?
17001         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
17002
17003         dot_lustre_fid_permission_check "$fid" $DIR ||
17004                 error "dot lustre permission check $fid failed"
17005
17006         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
17007
17008         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
17009
17010         touch $MOUNT/.lustre/file &&
17011                 error "creation is not allowed under .lustre"
17012
17013         mkdir $MOUNT/.lustre/dir &&
17014                 error "mkdir is not allowed under .lustre"
17015
17016         rm -rf $DIR/$tfile
17017 }
17018 run_test 154a "Open-by-FID"
17019
17020 test_154b() {
17021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17022         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17023         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17024         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
17025                 skip "Need MDS version at least 2.2.51"
17026
17027         local remote_dir=$DIR/$tdir/remote_dir
17028         local MDTIDX=1
17029         local rc=0
17030
17031         mkdir -p $DIR/$tdir
17032         $LFS mkdir -i $MDTIDX $remote_dir ||
17033                 error "create remote directory failed"
17034
17035         cp /etc/hosts $remote_dir/$tfile
17036
17037         fid=$($LFS path2fid $remote_dir/$tfile)
17038         rc=$?
17039         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
17040
17041         dot_lustre_fid_permission_check "$fid" $remote_dir ||
17042                 error "dot lustre permission check $fid failed"
17043         rm -rf $DIR/$tdir
17044 }
17045 run_test 154b "Open-by-FID for remote directory"
17046
17047 test_154c() {
17048         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
17049                 skip "Need MDS version at least 2.4.1"
17050
17051         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
17052         local FID1=$($LFS path2fid $DIR/$tfile.1)
17053         local FID2=$($LFS path2fid $DIR/$tfile.2)
17054         local FID3=$($LFS path2fid $DIR/$tfile.3)
17055
17056         local N=1
17057         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
17058                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
17059                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
17060                 local want=FID$N
17061                 [ "$FID" = "${!want}" ] ||
17062                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
17063                 N=$((N + 1))
17064         done
17065
17066         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
17067         do
17068                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
17069                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
17070                 N=$((N + 1))
17071         done
17072 }
17073 run_test 154c "lfs path2fid and fid2path multiple arguments"
17074
17075 test_154d() {
17076         remote_mds_nodsh && skip "remote MDS with nodsh"
17077         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
17078                 skip "Need MDS version at least 2.5.53"
17079
17080         if remote_mds; then
17081                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
17082         else
17083                 nid="0@lo"
17084         fi
17085         local proc_ofile="mdt.*.exports.'$nid'.open_files"
17086         local fd
17087         local cmd
17088
17089         rm -f $DIR/$tfile
17090         touch $DIR/$tfile
17091
17092         local fid=$($LFS path2fid $DIR/$tfile)
17093         # Open the file
17094         fd=$(free_fd)
17095         cmd="exec $fd<$DIR/$tfile"
17096         eval $cmd
17097         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
17098         echo "$fid_list" | grep "$fid"
17099         rc=$?
17100
17101         cmd="exec $fd>/dev/null"
17102         eval $cmd
17103         if [ $rc -ne 0 ]; then
17104                 error "FID $fid not found in open files list $fid_list"
17105         fi
17106 }
17107 run_test 154d "Verify open file fid"
17108
17109 test_154e()
17110 {
17111         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
17112                 skip "Need MDS version at least 2.6.50"
17113
17114         if ls -a $MOUNT | grep -q '^\.lustre$'; then
17115                 error ".lustre returned by readdir"
17116         fi
17117 }
17118 run_test 154e ".lustre is not returned by readdir"
17119
17120 test_154f() {
17121         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
17122
17123         # create parent directory on a single MDT to avoid cross-MDT hardlinks
17124         mkdir_on_mdt0 $DIR/$tdir
17125         # test dirs inherit from its stripe
17126         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
17127         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
17128         cp /etc/hosts $DIR/$tdir/foo1/$tfile
17129         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
17130         touch $DIR/f
17131
17132         # get fid of parents
17133         local FID0=$($LFS path2fid $DIR/$tdir)
17134         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
17135         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
17136         local FID3=$($LFS path2fid $DIR)
17137
17138         # check that path2fid --parents returns expected <parent_fid>/name
17139         # 1) test for a directory (single parent)
17140         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
17141         [ "$parent" == "$FID0/foo1" ] ||
17142                 error "expected parent: $FID0/foo1, got: $parent"
17143
17144         # 2) test for a file with nlink > 1 (multiple parents)
17145         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
17146         echo "$parent" | grep -F "$FID1/$tfile" ||
17147                 error "$FID1/$tfile not returned in parent list"
17148         echo "$parent" | grep -F "$FID2/link" ||
17149                 error "$FID2/link not returned in parent list"
17150
17151         # 3) get parent by fid
17152         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
17153         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17154         echo "$parent" | grep -F "$FID1/$tfile" ||
17155                 error "$FID1/$tfile not returned in parent list (by fid)"
17156         echo "$parent" | grep -F "$FID2/link" ||
17157                 error "$FID2/link not returned in parent list (by fid)"
17158
17159         # 4) test for entry in root directory
17160         parent=$($LFS path2fid --parents $DIR/f)
17161         echo "$parent" | grep -F "$FID3/f" ||
17162                 error "$FID3/f not returned in parent list"
17163
17164         # 5) test it on root directory
17165         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
17166                 error "$MOUNT should not have parents"
17167
17168         # enable xattr caching and check that linkea is correctly updated
17169         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
17170         save_lustre_params client "llite.*.xattr_cache" > $save
17171         lctl set_param llite.*.xattr_cache 1
17172
17173         # 6.1) linkea update on rename
17174         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
17175
17176         # get parents by fid
17177         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17178         # foo1 should no longer be returned in parent list
17179         echo "$parent" | grep -F "$FID1" &&
17180                 error "$FID1 should no longer be in parent list"
17181         # the new path should appear
17182         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
17183                 error "$FID2/$tfile.moved is not in parent list"
17184
17185         # 6.2) linkea update on unlink
17186         rm -f $DIR/$tdir/foo2/link
17187         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
17188         # foo2/link should no longer be returned in parent list
17189         echo "$parent" | grep -F "$FID2/link" &&
17190                 error "$FID2/link should no longer be in parent list"
17191         true
17192
17193         rm -f $DIR/f
17194         restore_lustre_params < $save
17195         rm -f $save
17196 }
17197 run_test 154f "get parent fids by reading link ea"
17198
17199 test_154g()
17200 {
17201         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
17202            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
17203                 skip "Need MDS version at least 2.6.92"
17204
17205         mkdir_on_mdt0 $DIR/$tdir
17206         llapi_fid_test -d $DIR/$tdir
17207 }
17208 run_test 154g "various llapi FID tests"
17209
17210 test_154h()
17211 {
17212         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
17213                 skip "Need client at least version 2.15.55.1"
17214
17215         # Create an empty file
17216         touch $DIR/$tfile
17217
17218         # Get FID (interactive mode) and save under $TMP/$tfile.log
17219         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
17220                 path2fid $DIR/$tfile
17221         EOF
17222
17223         fid=$(cat $TMP/$tfile.log)
17224         # $fid should not be empty
17225         [[ ! -z $fid ]] || error "FID is empty"
17226         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
17227 }
17228 run_test 154h "Verify interactive path2fid"
17229
17230 test_155_small_load() {
17231     local temp=$TMP/$tfile
17232     local file=$DIR/$tfile
17233
17234     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
17235         error "dd of=$temp bs=6096 count=1 failed"
17236     cp $temp $file
17237     cancel_lru_locks $OSC
17238     cmp $temp $file || error "$temp $file differ"
17239
17240     $TRUNCATE $temp 6000
17241     $TRUNCATE $file 6000
17242     cmp $temp $file || error "$temp $file differ (truncate1)"
17243
17244     echo "12345" >>$temp
17245     echo "12345" >>$file
17246     cmp $temp $file || error "$temp $file differ (append1)"
17247
17248     echo "12345" >>$temp
17249     echo "12345" >>$file
17250     cmp $temp $file || error "$temp $file differ (append2)"
17251
17252     rm -f $temp $file
17253     true
17254 }
17255
17256 test_155_big_load() {
17257         remote_ost_nodsh && skip "remote OST with nodsh"
17258
17259         local temp=$TMP/$tfile
17260         local file=$DIR/$tfile
17261
17262         free_min_max
17263         local cache_size=$(do_facet ost$((MAXI+1)) \
17264                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
17265
17266         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
17267         # pre-set value
17268         if [ -z "$cache_size" ]; then
17269                 cache_size=256
17270         fi
17271         local large_file_size=$((cache_size * 2))
17272
17273         echo "OSS cache size: $cache_size KB"
17274         echo "Large file size: $large_file_size KB"
17275
17276         [ $MAXV -le $large_file_size ] &&
17277                 skip_env "max available OST size needs > $large_file_size KB"
17278
17279         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
17280
17281         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
17282                 error "dd of=$temp bs=$large_file_size count=1k failed"
17283         cp $temp $file
17284         ls -lh $temp $file
17285         cancel_lru_locks osc
17286         cmp $temp $file || error "$temp $file differ"
17287
17288         rm -f $temp $file
17289         true
17290 }
17291
17292 save_writethrough() {
17293         local facets=$(get_facets OST)
17294
17295         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
17296 }
17297
17298 test_155a() {
17299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17300
17301         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17302
17303         save_writethrough $p
17304
17305         set_cache read on
17306         set_cache writethrough on
17307         test_155_small_load
17308         restore_lustre_params < $p
17309         rm -f $p
17310 }
17311 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
17312
17313 test_155b() {
17314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17315
17316         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17317
17318         save_writethrough $p
17319
17320         set_cache read on
17321         set_cache writethrough off
17322         test_155_small_load
17323         restore_lustre_params < $p
17324         rm -f $p
17325 }
17326 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
17327
17328 test_155c() {
17329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17330
17331         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17332
17333         save_writethrough $p
17334
17335         set_cache read off
17336         set_cache writethrough on
17337         test_155_small_load
17338         restore_lustre_params < $p
17339         rm -f $p
17340 }
17341 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
17342
17343 test_155d() {
17344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17345
17346         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17347
17348         save_writethrough $p
17349
17350         set_cache read off
17351         set_cache writethrough off
17352         test_155_small_load
17353         restore_lustre_params < $p
17354         rm -f $p
17355 }
17356 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
17357
17358 test_155e() {
17359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17360
17361         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17362
17363         save_writethrough $p
17364
17365         set_cache read on
17366         set_cache writethrough on
17367         test_155_big_load
17368         restore_lustre_params < $p
17369         rm -f $p
17370 }
17371 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
17372
17373 test_155f() {
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 off
17382         test_155_big_load
17383         restore_lustre_params < $p
17384         rm -f $p
17385 }
17386 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
17387
17388 test_155g() {
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 off
17396         set_cache writethrough on
17397         test_155_big_load
17398         restore_lustre_params < $p
17399         rm -f $p
17400 }
17401 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
17402
17403 test_155h() {
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 off
17412         test_155_big_load
17413         restore_lustre_params < $p
17414         rm -f $p
17415 }
17416 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
17417
17418 test_156() {
17419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17420         remote_ost_nodsh && skip "remote OST with nodsh"
17421         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
17422                 skip "stats not implemented on old servers"
17423         [ "$ost1_FSTYPE" = "zfs" ] &&
17424                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
17425         (( CLIENT_VERSION == OST1_VERSION )) ||
17426                 skip "LU-13081: no interop testing for OSS cache"
17427
17428         local CPAGES=3
17429         local BEFORE
17430         local AFTER
17431         local file="$DIR/$tfile"
17432         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
17433
17434         save_writethrough $p
17435         roc_hit_init
17436
17437         log "Turn on read and write cache"
17438         set_cache read on
17439         set_cache writethrough on
17440
17441         log "Write data and read it back."
17442         log "Read should be satisfied from the cache."
17443         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17444         BEFORE=$(roc_hit)
17445         cancel_lru_locks osc
17446         cat $file >/dev/null
17447         AFTER=$(roc_hit)
17448         if ! let "AFTER - BEFORE == CPAGES"; then
17449                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
17450         else
17451                 log "cache hits: before: $BEFORE, after: $AFTER"
17452         fi
17453
17454         log "Read again; it should be satisfied from the cache."
17455         BEFORE=$AFTER
17456         cancel_lru_locks osc
17457         cat $file >/dev/null
17458         AFTER=$(roc_hit)
17459         if ! let "AFTER - BEFORE == CPAGES"; then
17460                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
17461         else
17462                 log "cache hits:: before: $BEFORE, after: $AFTER"
17463         fi
17464
17465         log "Turn off the read cache and turn on the write cache"
17466         set_cache read off
17467         set_cache writethrough on
17468
17469         log "Read again; it should be satisfied from the cache."
17470         BEFORE=$(roc_hit)
17471         cancel_lru_locks osc
17472         cat $file >/dev/null
17473         AFTER=$(roc_hit)
17474         if ! let "AFTER - BEFORE == CPAGES"; then
17475                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
17476         else
17477                 log "cache hits:: before: $BEFORE, after: $AFTER"
17478         fi
17479
17480         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17481                 # > 2.12.56 uses pagecache if cached
17482                 log "Read again; it should not be satisfied from the cache."
17483                 BEFORE=$AFTER
17484                 cancel_lru_locks osc
17485                 cat $file >/dev/null
17486                 AFTER=$(roc_hit)
17487                 if ! let "AFTER - BEFORE == 0"; then
17488                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
17489                 else
17490                         log "cache hits:: before: $BEFORE, after: $AFTER"
17491                 fi
17492         fi
17493
17494         log "Write data and read it back."
17495         log "Read should be satisfied from the cache."
17496         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17497         BEFORE=$(roc_hit)
17498         cancel_lru_locks osc
17499         cat $file >/dev/null
17500         AFTER=$(roc_hit)
17501         if ! let "AFTER - BEFORE == CPAGES"; then
17502                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
17503         else
17504                 log "cache hits:: before: $BEFORE, after: $AFTER"
17505         fi
17506
17507         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
17508                 # > 2.12.56 uses pagecache if cached
17509                 log "Read again; it should not be satisfied from the cache."
17510                 BEFORE=$AFTER
17511                 cancel_lru_locks osc
17512                 cat $file >/dev/null
17513                 AFTER=$(roc_hit)
17514                 if ! let "AFTER - BEFORE == 0"; then
17515                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
17516                 else
17517                         log "cache hits:: before: $BEFORE, after: $AFTER"
17518                 fi
17519         fi
17520
17521         log "Turn off read and write cache"
17522         set_cache read off
17523         set_cache writethrough off
17524
17525         log "Write data and read it back"
17526         log "It should not be satisfied from the cache."
17527         rm -f $file
17528         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17529         cancel_lru_locks osc
17530         BEFORE=$(roc_hit)
17531         cat $file >/dev/null
17532         AFTER=$(roc_hit)
17533         if ! let "AFTER - BEFORE == 0"; then
17534                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
17535         else
17536                 log "cache hits:: before: $BEFORE, after: $AFTER"
17537         fi
17538
17539         log "Turn on the read cache and turn off the write cache"
17540         set_cache read on
17541         set_cache writethrough off
17542
17543         log "Write data and read it back"
17544         log "It should not be satisfied from the cache."
17545         rm -f $file
17546         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
17547         BEFORE=$(roc_hit)
17548         cancel_lru_locks osc
17549         cat $file >/dev/null
17550         AFTER=$(roc_hit)
17551         if ! let "AFTER - BEFORE == 0"; then
17552                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
17553         else
17554                 log "cache hits:: before: $BEFORE, after: $AFTER"
17555         fi
17556
17557         log "Read again; it should be satisfied from the cache."
17558         BEFORE=$(roc_hit)
17559         cancel_lru_locks osc
17560         cat $file >/dev/null
17561         AFTER=$(roc_hit)
17562         if ! let "AFTER - BEFORE == CPAGES"; then
17563                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
17564         else
17565                 log "cache hits:: before: $BEFORE, after: $AFTER"
17566         fi
17567
17568         restore_lustre_params < $p
17569         rm -f $p $file
17570 }
17571 run_test 156 "Verification of tunables"
17572
17573 test_160a() {
17574         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17575         remote_mds_nodsh && skip "remote MDS with nodsh"
17576         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17577                 skip "Need MDS version at least 2.2.0"
17578
17579         changelog_register || error "changelog_register failed"
17580         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17581         changelog_users $SINGLEMDS | grep -q $cl_user ||
17582                 error "User $cl_user not found in changelog_users"
17583
17584         mkdir_on_mdt0 $DIR/$tdir
17585
17586         # change something
17587         test_mkdir -p $DIR/$tdir/pics/2008/zachy
17588         changelog_clear 0 || error "changelog_clear failed"
17589         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
17590         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
17591         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17592         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17593         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17594         rm $DIR/$tdir/pics/desktop.jpg
17595
17596         echo "verifying changelog mask"
17597         changelog_chmask "-MKDIR"
17598         changelog_chmask "-CLOSE"
17599
17600         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
17601         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
17602
17603         changelog_chmask "+MKDIR"
17604         changelog_chmask "+CLOSE"
17605
17606         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
17607         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
17608
17609         MKDIRS=$(changelog_dump | grep -c "MKDIR")
17610         CLOSES=$(changelog_dump | grep -c "CLOSE")
17611         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
17612         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
17613
17614         # verify contents
17615         echo "verifying target fid"
17616         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
17617         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
17618         [ "$fidc" == "$fidf" ] ||
17619                 error "changelog '$tfile' fid $fidc != file fid $fidf"
17620         echo "verifying parent fid"
17621         # The FID returned from the Changelog may be the directory shard on
17622         # a different MDT, and not the FID returned by path2fid on the parent.
17623         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
17624         # since this is what will matter when recreating this file in the tree.
17625         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
17626         local pathp=$($LFS fid2path $MOUNT "$fidp")
17627         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
17628                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
17629
17630         echo "getting records for $cl_user"
17631         changelog_users $SINGLEMDS
17632         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
17633         local nclr=3
17634         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
17635                 error "changelog_clear failed"
17636         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
17637         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
17638         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
17639                 error "user index expect $user_rec1 + $nclr != $user_rec2"
17640
17641         local min0_rec=$(changelog_users $SINGLEMDS |
17642                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
17643         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
17644                           awk '{ print $1; exit; }')
17645
17646         changelog_dump | tail -n 5
17647         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
17648         [ $first_rec == $((min0_rec + 1)) ] ||
17649                 error "first index should be $min0_rec + 1 not $first_rec"
17650
17651         # LU-3446 changelog index reset on MDT restart
17652         local cur_rec1=$(changelog_users $SINGLEMDS |
17653                          awk '/^current.index:/ { print $NF }')
17654         changelog_clear 0 ||
17655                 error "clear all changelog records for $cl_user failed"
17656         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
17657         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
17658                 error "Fail to start $SINGLEMDS"
17659         local cur_rec2=$(changelog_users $SINGLEMDS |
17660                          awk '/^current.index:/ { print $NF }')
17661         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
17662         [ $cur_rec1 == $cur_rec2 ] ||
17663                 error "current index should be $cur_rec1 not $cur_rec2"
17664
17665         echo "verifying users from this test are deregistered"
17666         changelog_deregister || error "changelog_deregister failed"
17667         changelog_users $SINGLEMDS | grep -q $cl_user &&
17668                 error "User '$cl_user' still in changelog_users"
17669
17670         # lctl get_param -n mdd.*.changelog_users
17671         # current_index: 144
17672         # ID    index (idle seconds)
17673         # cl3   144   (2) mask=<list>
17674         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
17675                 # this is the normal case where all users were deregistered
17676                 # make sure no new records are added when no users are present
17677                 local last_rec1=$(changelog_users $SINGLEMDS |
17678                                   awk '/^current.index:/ { print $NF }')
17679                 touch $DIR/$tdir/chloe
17680                 local last_rec2=$(changelog_users $SINGLEMDS |
17681                                   awk '/^current.index:/ { print $NF }')
17682                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
17683                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
17684         else
17685                 # any changelog users must be leftovers from a previous test
17686                 changelog_users $SINGLEMDS
17687                 echo "other changelog users; can't verify off"
17688         fi
17689 }
17690 run_test 160a "changelog sanity"
17691
17692 test_160b() { # LU-3587
17693         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17694         remote_mds_nodsh && skip "remote MDS with nodsh"
17695         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
17696                 skip "Need MDS version at least 2.2.0"
17697
17698         changelog_register || error "changelog_register failed"
17699         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17700         changelog_users $SINGLEMDS | grep -q $cl_user ||
17701                 error "User '$cl_user' not found in changelog_users"
17702
17703         local longname1=$(str_repeat a 255)
17704         local longname2=$(str_repeat b 255)
17705
17706         cd $DIR
17707         echo "creating very long named file"
17708         touch $longname1 || error "create of '$longname1' failed"
17709         echo "renaming very long named file"
17710         mv $longname1 $longname2
17711
17712         changelog_dump | grep RENME | tail -n 5
17713         rm -f $longname2
17714 }
17715 run_test 160b "Verify that very long rename doesn't crash in changelog"
17716
17717 test_160c() {
17718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17719         remote_mds_nodsh && skip "remote MDS with nodsh"
17720
17721         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17722                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17723                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17724                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17725
17726         local rc=0
17727
17728         # Registration step
17729         changelog_register || error "changelog_register failed"
17730
17731         rm -rf $DIR/$tdir
17732         mkdir -p $DIR/$tdir
17733         $MCREATE $DIR/$tdir/foo_160c
17734         changelog_chmask "-TRUNC"
17735         $TRUNCATE $DIR/$tdir/foo_160c 200
17736         changelog_chmask "+TRUNC"
17737         $TRUNCATE $DIR/$tdir/foo_160c 199
17738         changelog_dump | tail -n 5
17739         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
17740         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
17741 }
17742 run_test 160c "verify that changelog log catch the truncate event"
17743
17744 test_160d() {
17745         remote_mds_nodsh && skip "remote MDS with nodsh"
17746         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17748         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
17749                 skip "Need MDS version at least 2.7.60"
17750
17751         # Registration step
17752         changelog_register || error "changelog_register failed"
17753
17754         mkdir -p $DIR/$tdir/migrate_dir
17755         changelog_clear 0 || error "changelog_clear failed"
17756
17757         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
17758         changelog_dump | tail -n 5
17759         local migrates=$(changelog_dump | grep -c "MIGRT")
17760         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
17761 }
17762 run_test 160d "verify that changelog log catch the migrate event"
17763
17764 test_160e() {
17765         remote_mds_nodsh && skip "remote MDS with nodsh"
17766
17767         # Create a user
17768         changelog_register || error "changelog_register failed"
17769
17770         local MDT0=$(facet_svc $SINGLEMDS)
17771         local rc
17772
17773         # No user (expect fail)
17774         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
17775         rc=$?
17776         if [ $rc -eq 0 ]; then
17777                 error "Should fail without user"
17778         elif [ $rc -ne 4 ]; then
17779                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
17780         fi
17781
17782         # Delete a future user (expect fail)
17783         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
17784         rc=$?
17785         if [ $rc -eq 0 ]; then
17786                 error "Deleted non-existant user cl77"
17787         elif [ $rc -ne 2 ]; then
17788                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
17789         fi
17790
17791         # Clear to a bad index (1 billion should be safe)
17792         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
17793         rc=$?
17794
17795         if [ $rc -eq 0 ]; then
17796                 error "Successfully cleared to invalid CL index"
17797         elif [ $rc -ne 22 ]; then
17798                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
17799         fi
17800 }
17801 run_test 160e "changelog negative testing (should return errors)"
17802
17803 test_160f() {
17804         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17805         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17806                 skip "Need MDS version at least 2.10.56"
17807
17808         local mdts=$(comma_list $(mdts_nodes))
17809
17810         # Create a user
17811         changelog_register || error "first changelog_register failed"
17812         changelog_register || error "second changelog_register failed"
17813         local cl_users
17814         declare -A cl_user1
17815         declare -A cl_user2
17816         local user_rec1
17817         local user_rec2
17818         local i
17819
17820         # generate some changelog records to accumulate on each MDT
17821         # use all_char because created files should be evenly distributed
17822         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17823                 error "test_mkdir $tdir failed"
17824         log "$(date +%s): creating first files"
17825         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17826                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
17827                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
17828         done
17829
17830         # check changelogs have been generated
17831         local start=$SECONDS
17832         local idle_time=$((MDSCOUNT * 5 + 5))
17833         local nbcl=$(changelog_dump | wc -l)
17834         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17835
17836         for param in "changelog_max_idle_time=$idle_time" \
17837                      "changelog_gc=1" \
17838                      "changelog_min_gc_interval=2" \
17839                      "changelog_min_free_cat_entries=3"; do
17840                 local MDT0=$(facet_svc $SINGLEMDS)
17841                 local var="${param%=*}"
17842                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17843
17844                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17845                 do_nodes $mdts $LCTL set_param mdd.*.$param
17846         done
17847
17848         # force cl_user2 to be idle (1st part), but also cancel the
17849         # cl_user1 records so that it is not evicted later in the test.
17850         local sleep1=$((idle_time / 2))
17851         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
17852         sleep $sleep1
17853
17854         # simulate changelog catalog almost full
17855         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
17856         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
17857
17858         for i in $(seq $MDSCOUNT); do
17859                 cl_users=(${CL_USERS[mds$i]})
17860                 cl_user1[mds$i]="${cl_users[0]}"
17861                 cl_user2[mds$i]="${cl_users[1]}"
17862
17863                 [ -n "${cl_user1[mds$i]}" ] ||
17864                         error "mds$i: no user registered"
17865                 [ -n "${cl_user2[mds$i]}" ] ||
17866                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17867
17868                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17869                 [ -n "$user_rec1" ] ||
17870                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17871                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17872                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17873                 [ -n "$user_rec2" ] ||
17874                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17875                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17876                      "$user_rec1 + 2 == $user_rec2"
17877                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17878                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17879                               "$user_rec1 + 2, but is $user_rec2"
17880                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17881                 [ -n "$user_rec2" ] ||
17882                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17883                 [ $user_rec1 == $user_rec2 ] ||
17884                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17885                               "$user_rec1, but is $user_rec2"
17886         done
17887
17888         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17889         local sleep2=$((idle_time - (SECONDS - start) + 1))
17890         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17891         sleep $sleep2
17892
17893         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17894         # cl_user1 should be OK because it recently processed records.
17895         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17896         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17897                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17898                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17899         done
17900
17901         # ensure gc thread is done
17902         for i in $(mdts_nodes); do
17903                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17904                         error "$i: GC-thread not done"
17905         done
17906
17907         local first_rec
17908         for (( i = 1; i <= MDSCOUNT; i++ )); do
17909                 # check cl_user1 still registered
17910                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17911                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17912                 # check cl_user2 unregistered
17913                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17914                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17915
17916                 # check changelogs are present and starting at $user_rec1 + 1
17917                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17918                 [ -n "$user_rec1" ] ||
17919                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17920                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17921                             awk '{ print $1; exit; }')
17922
17923                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17924                 [ $((user_rec1 + 1)) == $first_rec ] ||
17925                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17926         done
17927 }
17928 run_test 160f "changelog garbage collect (timestamped users)"
17929
17930 test_160g() {
17931         remote_mds_nodsh && skip "remote MDS with nodsh"
17932         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17933                 skip "Need MDS version at least 2.14.55"
17934
17935         local mdts=$(comma_list $(mdts_nodes))
17936
17937         # Create a user
17938         changelog_register || error "first changelog_register failed"
17939         changelog_register || error "second changelog_register failed"
17940         local cl_users
17941         declare -A cl_user1
17942         declare -A cl_user2
17943         local user_rec1
17944         local user_rec2
17945         local i
17946
17947         # generate some changelog records to accumulate on each MDT
17948         # use all_char because created files should be evenly distributed
17949         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17950                 error "test_mkdir $tdir failed"
17951         for ((i = 0; i < MDSCOUNT; i++)); do
17952                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17953                         error "create $DIR/$tdir/d$i.1 failed"
17954         done
17955
17956         # check changelogs have been generated
17957         local nbcl=$(changelog_dump | wc -l)
17958         (( $nbcl > 0 )) || error "no changelogs found"
17959
17960         # reduce the max_idle_indexes value to make sure we exceed it
17961         for param in "changelog_max_idle_indexes=2" \
17962                      "changelog_gc=1" \
17963                      "changelog_min_gc_interval=2"; do
17964                 local MDT0=$(facet_svc $SINGLEMDS)
17965                 local var="${param%=*}"
17966                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17967
17968                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17969                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17970                         error "unable to set mdd.*.$param"
17971         done
17972
17973         local start=$SECONDS
17974         for i in $(seq $MDSCOUNT); do
17975                 cl_users=(${CL_USERS[mds$i]})
17976                 cl_user1[mds$i]="${cl_users[0]}"
17977                 cl_user2[mds$i]="${cl_users[1]}"
17978
17979                 [ -n "${cl_user1[mds$i]}" ] ||
17980                         error "mds$i: user1 is not registered"
17981                 [ -n "${cl_user2[mds$i]}" ] ||
17982                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17983
17984                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17985                 [ -n "$user_rec1" ] ||
17986                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17987                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17988                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17989                 [ -n "$user_rec2" ] ||
17990                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17991                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17992                      "$user_rec1 + 2 == $user_rec2"
17993                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17994                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17995                               "expected $user_rec1 + 2, but is $user_rec2"
17996                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17997                 [ -n "$user_rec2" ] ||
17998                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17999                 [ $user_rec1 == $user_rec2 ] ||
18000                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
18001                               "expected $user_rec1, but is $user_rec2"
18002         done
18003
18004         # ensure we are past the previous changelog_min_gc_interval set above
18005         local sleep2=$((start + 2 - SECONDS))
18006         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18007         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
18008         # cl_user1 should be OK because it recently processed records.
18009         for ((i = 0; i < MDSCOUNT; i++)); do
18010                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
18011                         error "create $DIR/$tdir/d$i.3 failed"
18012         done
18013
18014         # ensure gc thread is done
18015         for i in $(mdts_nodes); do
18016                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
18017                         error "$i: GC-thread not done"
18018         done
18019
18020         local first_rec
18021         for (( i = 1; i <= MDSCOUNT; i++ )); do
18022                 # check cl_user1 still registered
18023                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18024                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
18025                 # check cl_user2 unregistered
18026                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18027                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
18028
18029                 # check changelogs are present and starting at $user_rec1 + 1
18030                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18031                 [ -n "$user_rec1" ] ||
18032                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
18033                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18034                             awk '{ print $1; exit; }')
18035
18036                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
18037                 [ $((user_rec1 + 1)) == $first_rec ] ||
18038                         error "mds$i: rec $first_rec != $user_rec1 + 1"
18039         done
18040 }
18041 run_test 160g "changelog garbage collect on idle records"
18042
18043 test_160h() {
18044         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18045         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
18046                 skip "Need MDS version at least 2.10.56"
18047
18048         local mdts=$(comma_list $(mdts_nodes))
18049
18050         # Create a user
18051         changelog_register || error "first changelog_register failed"
18052         changelog_register || error "second changelog_register failed"
18053         local cl_users
18054         declare -A cl_user1
18055         declare -A cl_user2
18056         local user_rec1
18057         local user_rec2
18058         local i
18059
18060         # generate some changelog records to accumulate on each MDT
18061         # use all_char because created files should be evenly distributed
18062         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18063                 error "test_mkdir $tdir failed"
18064         for ((i = 0; i < MDSCOUNT; i++)); do
18065                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18066                         error "create $DIR/$tdir/d$i.1 failed"
18067         done
18068
18069         # check changelogs have been generated
18070         local nbcl=$(changelog_dump | wc -l)
18071         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18072
18073         for param in "changelog_max_idle_time=10" \
18074                      "changelog_gc=1" \
18075                      "changelog_min_gc_interval=2"; do
18076                 local MDT0=$(facet_svc $SINGLEMDS)
18077                 local var="${param%=*}"
18078                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18079
18080                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18081                 do_nodes $mdts $LCTL set_param mdd.*.$param
18082         done
18083
18084         # force cl_user2 to be idle (1st part)
18085         sleep 9
18086
18087         for i in $(seq $MDSCOUNT); do
18088                 cl_users=(${CL_USERS[mds$i]})
18089                 cl_user1[mds$i]="${cl_users[0]}"
18090                 cl_user2[mds$i]="${cl_users[1]}"
18091
18092                 [ -n "${cl_user1[mds$i]}" ] ||
18093                         error "mds$i: no user registered"
18094                 [ -n "${cl_user2[mds$i]}" ] ||
18095                         error "mds$i: only ${cl_user2[mds$i]} is registered"
18096
18097                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18098                 [ -n "$user_rec1" ] ||
18099                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18100                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
18101                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18102                 [ -n "$user_rec2" ] ||
18103                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18104                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
18105                      "$user_rec1 + 2 == $user_rec2"
18106                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
18107                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
18108                               "$user_rec1 + 2, but is $user_rec2"
18109                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
18110                 [ -n "$user_rec2" ] ||
18111                         error "mds$i: User ${cl_user2[mds$i]} not registered"
18112                 [ $user_rec1 == $user_rec2 ] ||
18113                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
18114                               "$user_rec1, but is $user_rec2"
18115         done
18116
18117         # force cl_user2 to be idle (2nd part) and to reach
18118         # changelog_max_idle_time
18119         sleep 2
18120
18121         # force each GC-thread start and block then
18122         # one per MDT/MDD, set fail_val accordingly
18123         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
18124         do_nodes $mdts $LCTL set_param fail_loc=0x1316
18125
18126         # generate more changelogs to trigger fail_loc
18127         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18128                 error "create $DIR/$tdir/${tfile}bis failed"
18129
18130         # stop MDT to stop GC-thread, should be done in back-ground as it will
18131         # block waiting for the thread to be released and exit
18132         declare -A stop_pids
18133         for i in $(seq $MDSCOUNT); do
18134                 stop mds$i &
18135                 stop_pids[mds$i]=$!
18136         done
18137
18138         for i in $(mdts_nodes); do
18139                 local facet
18140                 local nb=0
18141                 local facets=$(facets_up_on_host $i)
18142
18143                 for facet in ${facets//,/ }; do
18144                         if [[ $facet == mds* ]]; then
18145                                 nb=$((nb + 1))
18146                         fi
18147                 done
18148                 # ensure each MDS's gc threads are still present and all in "R"
18149                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
18150                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
18151                         error "$i: expected $nb GC-thread"
18152                 wait_update $i \
18153                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
18154                         "R" 20 ||
18155                         error "$i: GC-thread not found in R-state"
18156                 # check umounts of each MDT on MDS have reached kthread_stop()
18157                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
18158                         error "$i: expected $nb umount"
18159                 wait_update $i \
18160                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
18161                         error "$i: umount not found in D-state"
18162         done
18163
18164         # release all GC-threads
18165         do_nodes $mdts $LCTL set_param fail_loc=0
18166
18167         # wait for MDT stop to complete
18168         for i in $(seq $MDSCOUNT); do
18169                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
18170         done
18171
18172         # XXX
18173         # may try to check if any orphan changelog records are present
18174         # via ldiskfs/zfs and llog_reader...
18175
18176         # re-start/mount MDTs
18177         for i in $(seq $MDSCOUNT); do
18178                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
18179                         error "Fail to start mds$i"
18180         done
18181
18182         local first_rec
18183         for i in $(seq $MDSCOUNT); do
18184                 # check cl_user1 still registered
18185                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
18186                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18187                 # check cl_user2 unregistered
18188                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
18189                         error "mds$i: User ${cl_user2[mds$i]} still registered"
18190
18191                 # check changelogs are present and starting at $user_rec1 + 1
18192                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
18193                 [ -n "$user_rec1" ] ||
18194                         error "mds$i: User ${cl_user1[mds$i]} not registered"
18195                 first_rec=$($LFS changelog $(facet_svc mds$i) |
18196                             awk '{ print $1; exit; }')
18197
18198                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
18199                 [ $((user_rec1 + 1)) == $first_rec ] ||
18200                         error "mds$i: first index should be $user_rec1 + 1, " \
18201                               "but is $first_rec"
18202         done
18203 }
18204 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
18205               "during mount"
18206
18207 test_160i() {
18208
18209         local mdts=$(comma_list $(mdts_nodes))
18210
18211         changelog_register || error "first changelog_register failed"
18212
18213         # generate some changelog records to accumulate on each MDT
18214         # use all_char because created files should be evenly distributed
18215         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18216                 error "test_mkdir $tdir failed"
18217         for ((i = 0; i < MDSCOUNT; i++)); do
18218                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18219                         error "create $DIR/$tdir/d$i.1 failed"
18220         done
18221
18222         # check changelogs have been generated
18223         local nbcl=$(changelog_dump | wc -l)
18224         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18225
18226         # simulate race between register and unregister
18227         # XXX as fail_loc is set per-MDS, with DNE configs the race
18228         # simulation will only occur for one MDT per MDS and for the
18229         # others the normal race scenario will take place
18230         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
18231         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
18232         do_nodes $mdts $LCTL set_param fail_val=1
18233
18234         # unregister 1st user
18235         changelog_deregister &
18236         local pid1=$!
18237         # wait some time for deregister work to reach race rdv
18238         sleep 2
18239         # register 2nd user
18240         changelog_register || error "2nd user register failed"
18241
18242         wait $pid1 || error "1st user deregister failed"
18243
18244         local i
18245         local last_rec
18246         declare -A LAST_REC
18247         for i in $(seq $MDSCOUNT); do
18248                 if changelog_users mds$i | grep "^cl"; then
18249                         # make sure new records are added with one user present
18250                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
18251                                           awk '/^current.index:/ { print $NF }')
18252                 else
18253                         error "mds$i has no user registered"
18254                 fi
18255         done
18256
18257         # generate more changelog records to accumulate on each MDT
18258         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
18259                 error "create $DIR/$tdir/${tfile}bis failed"
18260
18261         for i in $(seq $MDSCOUNT); do
18262                 last_rec=$(changelog_users $SINGLEMDS |
18263                            awk '/^current.index:/ { print $NF }')
18264                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
18265                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
18266                         error "changelogs are off on mds$i"
18267         done
18268 }
18269 run_test 160i "changelog user register/unregister race"
18270
18271 test_160j() {
18272         remote_mds_nodsh && skip "remote MDS with nodsh"
18273         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
18274                 skip "Need MDS version at least 2.12.56"
18275
18276         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
18277         stack_trap "umount $MOUNT2" EXIT
18278
18279         changelog_register || error "first changelog_register failed"
18280         stack_trap "changelog_deregister" EXIT
18281
18282         # generate some changelog
18283         # use all_char because created files should be evenly distributed
18284         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18285                 error "mkdir $tdir failed"
18286         for ((i = 0; i < MDSCOUNT; i++)); do
18287                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18288                         error "create $DIR/$tdir/d$i.1 failed"
18289         done
18290
18291         # open the changelog device
18292         exec 3>/dev/changelog-$FSNAME-MDT0000
18293         stack_trap "exec 3>&-" EXIT
18294         exec 4</dev/changelog-$FSNAME-MDT0000
18295         stack_trap "exec 4<&-" EXIT
18296
18297         # umount the first lustre mount
18298         umount $MOUNT
18299         stack_trap "mount_client $MOUNT" EXIT
18300
18301         # read changelog, which may or may not fail, but should not crash
18302         cat <&4 >/dev/null
18303
18304         # clear changelog
18305         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18306         changelog_users $SINGLEMDS | grep -q $cl_user ||
18307                 error "User $cl_user not found in changelog_users"
18308
18309         printf 'clear:'$cl_user':0' >&3
18310 }
18311 run_test 160j "client can be umounted while its chanangelog is being used"
18312
18313 test_160k() {
18314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18315         remote_mds_nodsh && skip "remote MDS with nodsh"
18316
18317         mkdir -p $DIR/$tdir/1/1
18318
18319         changelog_register || error "changelog_register failed"
18320         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18321
18322         changelog_users $SINGLEMDS | grep -q $cl_user ||
18323                 error "User '$cl_user' not found in changelog_users"
18324 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
18325         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
18326         rmdir $DIR/$tdir/1/1 & sleep 1
18327         mkdir $DIR/$tdir/2
18328         touch $DIR/$tdir/2/2
18329         rm -rf $DIR/$tdir/2
18330
18331         wait
18332         sleep 4
18333
18334         changelog_dump | grep rmdir || error "rmdir not recorded"
18335 }
18336 run_test 160k "Verify that changelog records are not lost"
18337
18338 # Verifies that a file passed as a parameter has recently had an operation
18339 # performed on it that has generated an MTIME changelog which contains the
18340 # correct parent FID. As files might reside on a different MDT from the
18341 # parent directory in DNE configurations, the FIDs are translated to paths
18342 # before being compared, which should be identical
18343 compare_mtime_changelog() {
18344         local file="${1}"
18345         local mdtidx
18346         local mtime
18347         local cl_fid
18348         local pdir
18349         local dir
18350
18351         mdtidx=$($LFS getstripe --mdt-index $file)
18352         mdtidx=$(printf "%04x" $mdtidx)
18353
18354         # Obtain the parent FID from the MTIME changelog
18355         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
18356         [ -z "$mtime" ] && error "MTIME changelog not recorded"
18357
18358         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
18359         [ -z "$cl_fid" ] && error "parent FID not present"
18360
18361         # Verify that the path for the parent FID is the same as the path for
18362         # the test directory
18363         pdir=$($LFS fid2path $MOUNT "$cl_fid")
18364
18365         dir=$(dirname $1)
18366
18367         [[ "${pdir%/}" == "$dir" ]] ||
18368                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
18369 }
18370
18371 test_160l() {
18372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18373
18374         remote_mds_nodsh && skip "remote MDS with nodsh"
18375         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
18376                 skip "Need MDS version at least 2.13.55"
18377
18378         local cl_user
18379
18380         changelog_register || error "changelog_register failed"
18381         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18382
18383         changelog_users $SINGLEMDS | grep -q $cl_user ||
18384                 error "User '$cl_user' not found in changelog_users"
18385
18386         # Clear some types so that MTIME changelogs are generated
18387         changelog_chmask "-CREAT"
18388         changelog_chmask "-CLOSE"
18389
18390         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
18391
18392         # Test CL_MTIME during setattr
18393         touch $DIR/$tdir/$tfile
18394         compare_mtime_changelog $DIR/$tdir/$tfile
18395
18396         # Test CL_MTIME during close
18397         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
18398         compare_mtime_changelog $DIR/$tdir/${tfile}_2
18399 }
18400 run_test 160l "Verify that MTIME changelog records contain the parent FID"
18401
18402 test_160m() {
18403         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18404         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18405                 skip "Need MDS version at least 2.14.51"
18406         local cl_users
18407         local cl_user1
18408         local cl_user2
18409         local pid1
18410
18411         # Create a user
18412         changelog_register || error "first changelog_register failed"
18413         changelog_register || error "second changelog_register failed"
18414
18415         cl_users=(${CL_USERS[mds1]})
18416         cl_user1="${cl_users[0]}"
18417         cl_user2="${cl_users[1]}"
18418         # generate some changelog records to accumulate on MDT0
18419         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18420         createmany -m $DIR/$tdir/$tfile 50 ||
18421                 error "create $DIR/$tdir/$tfile failed"
18422         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18423         rm -f $DIR/$tdir
18424
18425         # check changelogs have been generated
18426         local nbcl=$(changelog_dump | wc -l)
18427         [[ $nbcl -eq 0 ]] && error "no changelogs found"
18428
18429 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
18430         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
18431
18432         __changelog_clear mds1 $cl_user1 +10
18433         __changelog_clear mds1 $cl_user2 0 &
18434         pid1=$!
18435         sleep 2
18436         __changelog_clear mds1 $cl_user1 0 ||
18437                 error "fail to cancel record for $cl_user1"
18438         wait $pid1
18439         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18440 }
18441 run_test 160m "Changelog clear race"
18442
18443 test_160n() {
18444         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18445         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18446                 skip "Need MDS version at least 2.14.51"
18447         local cl_users
18448         local cl_user1
18449         local cl_user2
18450         local pid1
18451         local first_rec
18452         local last_rec=0
18453
18454         # Create a user
18455         changelog_register || error "first changelog_register failed"
18456
18457         cl_users=(${CL_USERS[mds1]})
18458         cl_user1="${cl_users[0]}"
18459
18460         # generate some changelog records to accumulate on MDT0
18461         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18462         first_rec=$(changelog_users $SINGLEMDS |
18463                         awk '/^current.index:/ { print $NF }')
18464         while (( last_rec < (( first_rec + 65000)) )); do
18465                 createmany -m $DIR/$tdir/$tfile 10000 ||
18466                         error "create $DIR/$tdir/$tfile failed"
18467
18468                 for i in $(seq 0 10000); do
18469                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
18470                                 > /dev/null
18471                 done
18472
18473                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
18474                         error "unlinkmany failed unlink"
18475                 last_rec=$(changelog_users $SINGLEMDS |
18476                         awk '/^current.index:/ { print $NF }')
18477                 echo last record $last_rec
18478                 (( last_rec == 0 )) && error "no changelog found"
18479         done
18480
18481 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
18482         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
18483
18484         __changelog_clear mds1 $cl_user1 0 &
18485         pid1=$!
18486         sleep 2
18487         __changelog_clear mds1 $cl_user1 0 ||
18488                 error "fail to cancel record for $cl_user1"
18489         wait $pid1
18490         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
18491 }
18492 run_test 160n "Changelog destroy race"
18493
18494 test_160o() {
18495         local mdt="$(facet_svc $SINGLEMDS)"
18496
18497         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18498         remote_mds_nodsh && skip "remote MDS with nodsh"
18499         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
18500                 skip "Need MDS version at least 2.14.52"
18501
18502         changelog_register --user test_160o -m unlnk+close+open ||
18503                 error "changelog_register failed"
18504
18505         do_facet $SINGLEMDS $LCTL --device $mdt \
18506                                 changelog_register -u "Tt3_-#" &&
18507                 error "bad symbols in name should fail"
18508
18509         do_facet $SINGLEMDS $LCTL --device $mdt \
18510                                 changelog_register -u test_160o &&
18511                 error "the same name registration should fail"
18512
18513         do_facet $SINGLEMDS $LCTL --device $mdt \
18514                         changelog_register -u test_160toolongname &&
18515                 error "too long name registration should fail"
18516
18517         changelog_chmask "MARK+HSM"
18518         lctl get_param mdd.*.changelog*mask
18519         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18520         changelog_users $SINGLEMDS | grep -q $cl_user ||
18521                 error "User $cl_user not found in changelog_users"
18522         #verify username
18523         echo $cl_user | grep -q test_160o ||
18524                 error "User $cl_user has no specific name 'test160o'"
18525
18526         # change something
18527         changelog_clear 0 || error "changelog_clear failed"
18528         # generate some changelog records to accumulate on MDT0
18529         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18530         touch $DIR/$tdir/$tfile                 # open 1
18531
18532         OPENS=$(changelog_dump | grep -c "OPEN")
18533         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
18534
18535         # must be no MKDIR it wasn't set as user mask
18536         MKDIR=$(changelog_dump | grep -c "MKDIR")
18537         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
18538
18539         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
18540                                 mdd.$mdt.changelog_current_mask -n)
18541         # register maskless user
18542         changelog_register || error "changelog_register failed"
18543         # effective mask should be not changed because it is not minimal
18544         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18545                                 mdd.$mdt.changelog_current_mask -n)
18546         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
18547         # set server mask to minimal value
18548         changelog_chmask "MARK"
18549         # check effective mask again, should be treated as DEFMASK now
18550         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18551                                 mdd.$mdt.changelog_current_mask -n)
18552         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18553
18554         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
18555                 # set server mask back to some value
18556                 changelog_chmask "CLOSE,UNLNK"
18557                 # check effective mask again, should not remain as DEFMASK
18558                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
18559                                 mdd.$mdt.changelog_current_mask -n)
18560                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
18561         fi
18562
18563         do_facet $SINGLEMDS $LCTL --device $mdt \
18564                                 changelog_deregister -u test_160o ||
18565                 error "cannot deregister by name"
18566 }
18567 run_test 160o "changelog user name and mask"
18568
18569 test_160p() {
18570         remote_mds_nodsh && skip "remote MDS with nodsh" && return
18571         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
18572                 skip "Need MDS version at least 2.14.51"
18573         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
18574         local cl_users
18575         local cl_user1
18576         local entry_count
18577
18578         # Create a user
18579         changelog_register || error "first changelog_register failed"
18580
18581         cl_users=(${CL_USERS[mds1]})
18582         cl_user1="${cl_users[0]}"
18583
18584         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
18585         createmany -m $DIR/$tdir/$tfile 50 ||
18586                 error "create $DIR/$tdir/$tfile failed"
18587         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
18588         rm -rf $DIR/$tdir
18589
18590         # check changelogs have been generated
18591         entry_count=$(changelog_dump | wc -l)
18592         ((entry_count != 0)) || error "no changelog entries found"
18593
18594         # remove changelog_users and check that orphan entries are removed
18595         stop mds1
18596         local dev=$(mdsdevname 1)
18597         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
18598         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
18599         entry_count=$(changelog_dump | wc -l)
18600         ((entry_count == 0)) ||
18601                 error "found $entry_count changelog entries, expected none"
18602 }
18603 run_test 160p "Changelog orphan cleanup with no users"
18604
18605 test_160q() {
18606         local mdt="$(facet_svc $SINGLEMDS)"
18607         local clu
18608
18609         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
18610         remote_mds_nodsh && skip "remote MDS with nodsh"
18611         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
18612                 skip "Need MDS version at least 2.14.54"
18613
18614         # set server mask to minimal value like server init does
18615         changelog_chmask "MARK"
18616         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
18617                 error "changelog_register failed"
18618         # check effective mask again, should be treated as DEFMASK now
18619         mask=$(do_facet $SINGLEMDS $LCTL get_param \
18620                                 mdd.$mdt.changelog_current_mask -n)
18621         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
18622                 error "changelog_deregister failed"
18623         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
18624 }
18625 run_test 160q "changelog effective mask is DEFMASK if not set"
18626
18627 test_160s() {
18628         remote_mds_nodsh && skip "remote MDS with nodsh"
18629         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
18630                 skip "Need MDS version at least 2.14.55"
18631
18632         local mdts=$(comma_list $(mdts_nodes))
18633
18634         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
18635         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
18636                                        fail_val=$((24 * 3600 * 10))
18637
18638         # Create a user which is 10 days old
18639         changelog_register || error "first changelog_register failed"
18640         local cl_users
18641         declare -A cl_user1
18642         local i
18643
18644         # generate some changelog records to accumulate on each MDT
18645         # use all_char because created files should be evenly distributed
18646         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
18647                 error "test_mkdir $tdir failed"
18648         for ((i = 0; i < MDSCOUNT; i++)); do
18649                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
18650                         error "create $DIR/$tdir/d$i.1 failed"
18651         done
18652
18653         # check changelogs have been generated
18654         local nbcl=$(changelog_dump | wc -l)
18655         (( nbcl > 0 )) || error "no changelogs found"
18656
18657         # reduce the max_idle_indexes value to make sure we exceed it
18658         for param in "changelog_max_idle_indexes=2097446912" \
18659                      "changelog_max_idle_time=2592000" \
18660                      "changelog_gc=1" \
18661                      "changelog_min_gc_interval=2"; do
18662                 local MDT0=$(facet_svc $SINGLEMDS)
18663                 local var="${param%=*}"
18664                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18665
18666                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
18667                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
18668                         error "unable to set mdd.*.$param"
18669         done
18670
18671         local start=$SECONDS
18672         for i in $(seq $MDSCOUNT); do
18673                 cl_users=(${CL_USERS[mds$i]})
18674                 cl_user1[mds$i]="${cl_users[0]}"
18675
18676                 [[ -n "${cl_user1[mds$i]}" ]] ||
18677                         error "mds$i: no user registered"
18678         done
18679
18680         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
18681         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
18682
18683         # ensure we are past the previous changelog_min_gc_interval set above
18684         local sleep2=$((start + 2 - SECONDS))
18685         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18686
18687         # Generate one more changelog to trigger GC
18688         for ((i = 0; i < MDSCOUNT; i++)); do
18689                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
18690                         error "create $DIR/$tdir/d$i.3 failed"
18691         done
18692
18693         # ensure gc thread is done
18694         for node in $(mdts_nodes); do
18695                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
18696                         error "$node: GC-thread not done"
18697         done
18698
18699         do_nodes $mdts $LCTL set_param fail_loc=0
18700
18701         for (( i = 1; i <= MDSCOUNT; i++ )); do
18702                 # check cl_user1 is purged
18703                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
18704                         error "mds$i: User ${cl_user1[mds$i]} is registered"
18705         done
18706         return 0
18707 }
18708 run_test 160s "changelog garbage collect on idle records * time"
18709
18710 test_160t() {
18711         remote_mds_nodsh && skip "remote MDS with nodsh"
18712         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
18713                 skip "Need MDS version at least 2.15.50"
18714
18715         local MDT0=$(facet_svc $SINGLEMDS)
18716         local cl_users
18717         local cl_user1
18718         local cl_user2
18719         local start
18720
18721         changelog_register --user user1 -m all ||
18722                 error "user1 failed to register"
18723
18724         mkdir_on_mdt0 $DIR/$tdir
18725         # create default overstripe to maximize changelog size
18726         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
18727         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
18728         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18729
18730         # user2 consumes less records so less space
18731         changelog_register --user user2 || error "user2 failed to register"
18732         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
18733         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
18734
18735         # check changelogs have been generated
18736         local nbcl=$(changelog_dump | wc -l)
18737         (( nbcl > 0 )) || error "no changelogs found"
18738
18739         # reduce the changelog_min_gc_interval to force check
18740         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
18741                 local var="${param%=*}"
18742                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
18743
18744                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
18745                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
18746                         error "unable to set mdd.*.$param"
18747         done
18748
18749         start=$SECONDS
18750         cl_users=(${CL_USERS[mds1]})
18751         cl_user1="${cl_users[0]}"
18752         cl_user2="${cl_users[1]}"
18753
18754         [[ -n $cl_user1 ]] ||
18755                 error "mds1: user #1 isn't registered"
18756         [[ -n $cl_user2 ]] ||
18757                 error "mds1: user #2 isn't registered"
18758
18759         # ensure we are past the previous changelog_min_gc_interval set above
18760         local sleep2=$((start + 2 - SECONDS))
18761         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
18762
18763         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
18764         do_facet mds1 $LCTL set_param fail_loc=0x018c \
18765                         fail_val=$(((llog_size1 + llog_size2) / 2))
18766
18767         # Generate more changelog to trigger GC
18768         createmany -o $DIR/$tdir/u3_ 4 ||
18769                 error "create failed for more files"
18770
18771         # ensure gc thread is done
18772         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
18773                 error "mds1: GC-thread not done"
18774
18775         do_facet mds1 $LCTL set_param fail_loc=0
18776
18777         # check cl_user1 is purged
18778         changelog_users mds1 | grep -q "$cl_user1" &&
18779                 error "User $cl_user1 is registered"
18780         # check cl_user2 is not purged
18781         changelog_users mds1 | grep -q "$cl_user2" ||
18782                 error "User $cl_user2 is not registered"
18783 }
18784 run_test 160t "changelog garbage collect on lack of space"
18785
18786 test_160u() { # LU-17400
18787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18788         remote_mds_nodsh && skip "remote MDS with nodsh"
18789         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
18790                 skip "Need MDS version at least 2.2.0"
18791
18792         cd $DIR || error "cd $DIR failed"
18793
18794         # ensure changelog has a clean view if tests are run multiple times
18795         [ -d rename ] && rm -rf rename
18796
18797         changelog_register || error "changelog_register failed"
18798         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
18799
18800         changelog_users $SINGLEMDS | grep -q $cl_user ||
18801                 error "User '$cl_user' not found in changelog_users"
18802
18803         local longname1=$(str_repeat a 255)
18804
18805         echo "creating simple directory tree"
18806         mkdir -p rename/a || error "create of simple directory tree failed"
18807         echo "creating rename/hw file"
18808         echo "hello world" > rename/hw || error "create of rename/hw failed"
18809         echo "creating very long named file"
18810         touch rename/$longname1 || error "create of 'rename/$longname1' failed"
18811         echo "move rename/hw to rename/a/a.hw"
18812         mv rename/hw rename/a/a.hw || error "mv failed"
18813
18814         RENME=($(changelog_dump | grep "RENME"))
18815         #declare -p RENME # for debugging captured value with indexes
18816
18817         [[ "${RENME[11]}" == "a.hw" && "${RENME[14]}" == "hw" ]] ||
18818                 error "changelog rename record type name/sname error"
18819 }
18820 run_test 160u "changelog rename record type name and sname strings are correct"
18821
18822 test_161a() {
18823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18824
18825         test_mkdir -c1 $DIR/$tdir
18826         cp /etc/hosts $DIR/$tdir/$tfile
18827         test_mkdir -c1 $DIR/$tdir/foo1
18828         test_mkdir -c1 $DIR/$tdir/foo2
18829         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
18830         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
18831         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
18832         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
18833         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
18834         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18835                 $LFS fid2path $DIR $FID
18836                 error "bad link ea"
18837         fi
18838         # middle
18839         rm $DIR/$tdir/foo2/zachary
18840         # last
18841         rm $DIR/$tdir/foo2/thor
18842         # first
18843         rm $DIR/$tdir/$tfile
18844         # rename
18845         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
18846         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
18847                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
18848         rm $DIR/$tdir/foo2/maggie
18849
18850         # overflow the EA
18851         local longname=$tfile.avg_len_is_thirty_two_
18852         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
18853                 error_noexit 'failed to unlink many hardlinks'" EXIT
18854         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
18855                 error "failed to hardlink many files"
18856         links=$($LFS fid2path $DIR $FID | wc -l)
18857         echo -n "${links}/1000 links in link EA"
18858         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
18859 }
18860 run_test 161a "link ea sanity"
18861
18862 test_161b() {
18863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18864         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
18865
18866         local MDTIDX=1
18867         local remote_dir=$DIR/$tdir/remote_dir
18868
18869         mkdir -p $DIR/$tdir
18870         $LFS mkdir -i $MDTIDX $remote_dir ||
18871                 error "create remote directory failed"
18872
18873         cp /etc/hosts $remote_dir/$tfile
18874         mkdir -p $remote_dir/foo1
18875         mkdir -p $remote_dir/foo2
18876         ln $remote_dir/$tfile $remote_dir/foo1/sofia
18877         ln $remote_dir/$tfile $remote_dir/foo2/zachary
18878         ln $remote_dir/$tfile $remote_dir/foo1/luna
18879         ln $remote_dir/$tfile $remote_dir/foo2/thor
18880
18881         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
18882                      tr -d ']')
18883         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
18884                 $LFS fid2path $DIR $FID
18885                 error "bad link ea"
18886         fi
18887         # middle
18888         rm $remote_dir/foo2/zachary
18889         # last
18890         rm $remote_dir/foo2/thor
18891         # first
18892         rm $remote_dir/$tfile
18893         # rename
18894         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
18895         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
18896         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
18897                 $LFS fid2path $DIR $FID
18898                 error "bad link rename"
18899         fi
18900         rm $remote_dir/foo2/maggie
18901
18902         # overflow the EA
18903         local longname=filename_avg_len_is_thirty_two_
18904         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18905                 error "failed to hardlink many files"
18906         links=$($LFS fid2path $DIR $FID | wc -l)
18907         echo -n "${links}/1000 links in link EA"
18908         [[ ${links} -gt 60 ]] ||
18909                 error "expected at least 60 links in link EA"
18910         unlinkmany $remote_dir/foo2/$longname 1000 ||
18911         error "failed to unlink many hardlinks"
18912 }
18913 run_test 161b "link ea sanity under remote directory"
18914
18915 test_161c() {
18916         remote_mds_nodsh && skip "remote MDS with nodsh"
18917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18918         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18919                 skip "Need MDS version at least 2.1.5"
18920
18921         # define CLF_RENAME_LAST 0x0001
18922         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18923         changelog_register || error "changelog_register failed"
18924
18925         rm -rf $DIR/$tdir
18926         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18927         touch $DIR/$tdir/foo_161c
18928         touch $DIR/$tdir/bar_161c
18929         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18930         changelog_dump | grep RENME | tail -n 5
18931         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18932         changelog_clear 0 || error "changelog_clear failed"
18933         if [ x$flags != "x0x1" ]; then
18934                 error "flag $flags is not 0x1"
18935         fi
18936
18937         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18938         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18939         touch $DIR/$tdir/foo_161c
18940         touch $DIR/$tdir/bar_161c
18941         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18942         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18943         changelog_dump | grep RENME | tail -n 5
18944         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18945         changelog_clear 0 || error "changelog_clear failed"
18946         if [ x$flags != "x0x0" ]; then
18947                 error "flag $flags is not 0x0"
18948         fi
18949         echo "rename overwrite a target having nlink > 1," \
18950                 "changelog record has flags of $flags"
18951
18952         # rename doesn't overwrite a target (changelog flag 0x0)
18953         touch $DIR/$tdir/foo_161c
18954         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18955         changelog_dump | grep RENME | tail -n 5
18956         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18957         changelog_clear 0 || error "changelog_clear failed"
18958         if [ x$flags != "x0x0" ]; then
18959                 error "flag $flags is not 0x0"
18960         fi
18961         echo "rename doesn't overwrite a target," \
18962                 "changelog record has flags of $flags"
18963
18964         # define CLF_UNLINK_LAST 0x0001
18965         # unlink a file having nlink = 1 (changelog flag 0x1)
18966         rm -f $DIR/$tdir/foo2_161c
18967         changelog_dump | grep UNLNK | tail -n 5
18968         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18969         changelog_clear 0 || error "changelog_clear failed"
18970         if [ x$flags != "x0x1" ]; then
18971                 error "flag $flags is not 0x1"
18972         fi
18973         echo "unlink a file having nlink = 1," \
18974                 "changelog record has flags of $flags"
18975
18976         # unlink a file having nlink > 1 (changelog flag 0x0)
18977         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18978         rm -f $DIR/$tdir/foobar_161c
18979         changelog_dump | grep UNLNK | tail -n 5
18980         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18981         changelog_clear 0 || error "changelog_clear failed"
18982         if [ x$flags != "x0x0" ]; then
18983                 error "flag $flags is not 0x0"
18984         fi
18985         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18986 }
18987 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18988
18989 test_161d() {
18990         remote_mds_nodsh && skip "remote MDS with nodsh"
18991         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18992
18993         local pid
18994         local fid
18995
18996         changelog_register || error "changelog_register failed"
18997
18998         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18999         # interfer with $MOUNT/.lustre/fid/ access
19000         mkdir $DIR/$tdir
19001         [[ $? -eq 0 ]] || error "mkdir failed"
19002
19003         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | CFS_FAIL_ONCE
19004         $LCTL set_param fail_loc=0x8000140c
19005         # 5s pause
19006         $LCTL set_param fail_val=5
19007
19008         # create file
19009         echo foofoo > $DIR/$tdir/$tfile &
19010         pid=$!
19011
19012         # wait for create to be delayed
19013         sleep 2
19014
19015         ps -p $pid
19016         [[ $? -eq 0 ]] || error "create should be blocked"
19017
19018         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
19019         stack_trap "rm -f $tempfile"
19020         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
19021         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
19022         # some delay may occur during ChangeLog publishing and file read just
19023         # above, that could allow file write to happen finally
19024         [[ -s $tempfile ]] && echo "file should be empty"
19025
19026         $LCTL set_param fail_loc=0
19027
19028         wait $pid
19029         [[ $? -eq 0 ]] || error "create failed"
19030 }
19031 run_test 161d "create with concurrent .lustre/fid access"
19032
19033 check_path() {
19034         local expected="$1"
19035         shift
19036         local fid="$2"
19037
19038         local path
19039         path=$($LFS fid2path "$@")
19040         local rc=$?
19041
19042         if [ $rc -ne 0 ]; then
19043                 error "path looked up of '$expected' failed: rc=$rc"
19044         elif [ "$path" != "$expected" ]; then
19045                 error "path looked up '$path' instead of '$expected'"
19046         else
19047                 echo "FID '$fid' resolves to path '$path' as expected"
19048         fi
19049 }
19050
19051 test_162a() { # was test_162
19052         test_mkdir -p -c1 $DIR/$tdir/d2
19053         touch $DIR/$tdir/d2/$tfile
19054         touch $DIR/$tdir/d2/x1
19055         touch $DIR/$tdir/d2/x2
19056         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
19057         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
19058         # regular file
19059         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
19060         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
19061
19062         # softlink
19063         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
19064         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
19065         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
19066
19067         # softlink to wrong file
19068         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
19069         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
19070         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
19071
19072         # hardlink
19073         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
19074         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
19075         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
19076         # fid2path dir/fsname should both work
19077         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
19078         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
19079
19080         # hardlink count: check that there are 2 links
19081         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
19082         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
19083
19084         # hardlink indexing: remove the first link
19085         rm $DIR/$tdir/d2/p/q/r/hlink
19086         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
19087 }
19088 run_test 162a "path lookup sanity"
19089
19090 test_162b() {
19091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19092         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19093
19094         mkdir $DIR/$tdir
19095         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19096                                 error "create striped dir failed"
19097
19098         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19099                                         tail -n 1 | awk '{print $2}')
19100         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
19101
19102         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
19103         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
19104
19105         # regular file
19106         for ((i=0;i<5;i++)); do
19107                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
19108                         error "get fid for f$i failed"
19109                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
19110
19111                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
19112                         error "get fid for d$i failed"
19113                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
19114         done
19115
19116         return 0
19117 }
19118 run_test 162b "striped directory path lookup sanity"
19119
19120 # LU-4239: Verify fid2path works with paths 100 or more directories deep
19121 test_162c() {
19122         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
19123                 skip "Need MDS version at least 2.7.51"
19124
19125         local lpath=$tdir.local
19126         local rpath=$tdir.remote
19127
19128         test_mkdir $DIR/$lpath
19129         test_mkdir $DIR/$rpath
19130
19131         for ((i = 0; i <= 101; i++)); do
19132                 lpath="$lpath/$i"
19133                 mkdir $DIR/$lpath
19134                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
19135                         error "get fid for local directory $DIR/$lpath failed"
19136                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
19137
19138                 rpath="$rpath/$i"
19139                 test_mkdir $DIR/$rpath
19140                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
19141                         error "get fid for remote directory $DIR/$rpath failed"
19142                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
19143         done
19144
19145         return 0
19146 }
19147 run_test 162c "fid2path works with paths 100 or more directories deep"
19148
19149 oalr_event_count() {
19150         local event="${1}"
19151         local trace="${2}"
19152
19153         awk -v name="${FSNAME}-OST0000" \
19154             -v event="${event}" \
19155             '$1 == "TRACE" && $2 == event && $3 == name' \
19156             "${trace}" |
19157         wc -l
19158 }
19159
19160 oalr_expect_event_count() {
19161         local event="${1}"
19162         local trace="${2}"
19163         local expect="${3}"
19164         local count
19165
19166         count=$(oalr_event_count "${event}" "${trace}")
19167         if ((count == expect)); then
19168                 return 0
19169         fi
19170
19171         error_noexit "${event} event count was '${count}', expected ${expect}"
19172         cat "${trace}" >&2
19173         exit 1
19174 }
19175
19176 cleanup_165() {
19177         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
19178         stop ost1
19179         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
19180 }
19181
19182 setup_165() {
19183         sync # Flush previous IOs so we can count log entries.
19184         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
19185         stack_trap cleanup_165 EXIT
19186 }
19187
19188 test_165a() {
19189         local trace="/tmp/${tfile}.trace"
19190         local rc
19191         local count
19192
19193         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19194                 skip "OFD access log unsupported"
19195
19196         setup_165
19197         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19198         sleep 5
19199
19200         do_facet ost1 ofd_access_log_reader --list
19201         stop ost1
19202
19203         do_facet ost1 killall -TERM ofd_access_log_reader
19204         wait
19205         rc=$?
19206
19207         if ((rc != 0)); then
19208                 error "ofd_access_log_reader exited with rc = '${rc}'"
19209         fi
19210
19211         # Parse trace file for discovery events:
19212         oalr_expect_event_count alr_log_add "${trace}" 1
19213         oalr_expect_event_count alr_log_eof "${trace}" 1
19214         oalr_expect_event_count alr_log_free "${trace}" 1
19215 }
19216 run_test 165a "ofd access log discovery"
19217
19218 test_165b() {
19219         local trace="/tmp/${tfile}.trace"
19220         local file="${DIR}/${tfile}"
19221         local pfid1
19222         local pfid2
19223         local -a entry
19224         local rc
19225         local count
19226         local size
19227         local flags
19228
19229         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19230                 skip "OFD access log unsupported"
19231
19232         setup_165
19233         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19234         sleep 5
19235
19236         do_facet ost1 ofd_access_log_reader --list
19237
19238         lfs setstripe -c 1 -i 0 "${file}"
19239         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19240                 error "cannot create '${file}'"
19241
19242         sleep 5
19243         do_facet ost1 killall -TERM ofd_access_log_reader
19244         wait
19245         rc=$?
19246
19247         if ((rc != 0)); then
19248                 error "ofd_access_log_reader exited with rc = '${rc}'"
19249         fi
19250
19251         oalr_expect_event_count alr_log_entry "${trace}" 1
19252
19253         pfid1=$($LFS path2fid "${file}")
19254
19255         # 1     2             3   4    5     6   7    8    9     10
19256         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
19257         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19258
19259         echo "entry = '${entry[*]}'" >&2
19260
19261         pfid2=${entry[4]}
19262         if [[ "${pfid1}" != "${pfid2}" ]]; then
19263                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19264         fi
19265
19266         size=${entry[8]}
19267         if ((size != 1048576)); then
19268                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
19269         fi
19270
19271         flags=${entry[10]}
19272         if [[ "${flags}" != "w" ]]; then
19273                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
19274         fi
19275
19276         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19277         sleep 5
19278
19279         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
19280                 error "cannot read '${file}'"
19281         sleep 5
19282
19283         do_facet ost1 killall -TERM ofd_access_log_reader
19284         wait
19285         rc=$?
19286
19287         if ((rc != 0)); then
19288                 error "ofd_access_log_reader exited with rc = '${rc}'"
19289         fi
19290
19291         oalr_expect_event_count alr_log_entry "${trace}" 1
19292
19293         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
19294         echo "entry = '${entry[*]}'" >&2
19295
19296         pfid2=${entry[4]}
19297         if [[ "${pfid1}" != "${pfid2}" ]]; then
19298                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
19299         fi
19300
19301         size=${entry[8]}
19302         if ((size != 524288)); then
19303                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
19304         fi
19305
19306         flags=${entry[10]}
19307         if [[ "${flags}" != "r" ]]; then
19308                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
19309         fi
19310 }
19311 run_test 165b "ofd access log entries are produced and consumed"
19312
19313 test_165c() {
19314         local trace="/tmp/${tfile}.trace"
19315         local file="${DIR}/${tdir}/${tfile}"
19316
19317         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19318                 skip "OFD access log unsupported"
19319
19320         test_mkdir "${DIR}/${tdir}"
19321
19322         setup_165
19323         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
19324         sleep 5
19325
19326         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
19327
19328         # 4096 / 64 = 64. Create twice as many entries.
19329         for ((i = 0; i < 128; i++)); do
19330                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
19331                         error "cannot create file"
19332         done
19333
19334         sync
19335
19336         do_facet ost1 killall -TERM ofd_access_log_reader
19337         wait
19338         rc=$?
19339         if ((rc != 0)); then
19340                 error "ofd_access_log_reader exited with rc = '${rc}'"
19341         fi
19342
19343         unlinkmany  "${file}-%d" 128
19344 }
19345 run_test 165c "full ofd access logs do not block IOs"
19346
19347 oal_get_read_count() {
19348         local stats="$1"
19349
19350         # STATS lustre-OST0001 alr_read_count 1
19351
19352         do_facet ost1 cat "${stats}" |
19353         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
19354              END { print count; }'
19355 }
19356
19357 oal_expect_read_count() {
19358         local stats="$1"
19359         local count
19360         local expect="$2"
19361
19362         # Ask ofd_access_log_reader to write stats.
19363         do_facet ost1 killall -USR1 ofd_access_log_reader
19364
19365         # Allow some time for things to happen.
19366         sleep 1
19367
19368         count=$(oal_get_read_count "${stats}")
19369         if ((count == expect)); then
19370                 return 0
19371         fi
19372
19373         error_noexit "bad read count, got ${count}, expected ${expect}"
19374         do_facet ost1 cat "${stats}" >&2
19375         exit 1
19376 }
19377
19378 test_165d() {
19379         local stats="/tmp/${tfile}.stats"
19380         local file="${DIR}/${tdir}/${tfile}"
19381         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
19382
19383         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19384                 skip "OFD access log unsupported"
19385
19386         test_mkdir "${DIR}/${tdir}"
19387
19388         setup_165
19389         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
19390         sleep 5
19391
19392         lfs setstripe -c 1 -i 0 "${file}"
19393
19394         do_facet ost1 lctl set_param "${param}=rw"
19395         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19396                 error "cannot create '${file}'"
19397         oal_expect_read_count "${stats}" 1
19398
19399         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19400                 error "cannot read '${file}'"
19401         oal_expect_read_count "${stats}" 2
19402
19403         do_facet ost1 lctl set_param "${param}=r"
19404         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19405                 error "cannot create '${file}'"
19406         oal_expect_read_count "${stats}" 2
19407
19408         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19409                 error "cannot read '${file}'"
19410         oal_expect_read_count "${stats}" 3
19411
19412         do_facet ost1 lctl set_param "${param}=w"
19413         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19414                 error "cannot create '${file}'"
19415         oal_expect_read_count "${stats}" 4
19416
19417         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19418                 error "cannot read '${file}'"
19419         oal_expect_read_count "${stats}" 4
19420
19421         do_facet ost1 lctl set_param "${param}=0"
19422         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
19423                 error "cannot create '${file}'"
19424         oal_expect_read_count "${stats}" 4
19425
19426         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
19427                 error "cannot read '${file}'"
19428         oal_expect_read_count "${stats}" 4
19429
19430         do_facet ost1 killall -TERM ofd_access_log_reader
19431         wait
19432         rc=$?
19433         if ((rc != 0)); then
19434                 error "ofd_access_log_reader exited with rc = '${rc}'"
19435         fi
19436 }
19437 run_test 165d "ofd_access_log mask works"
19438
19439 test_165e() {
19440         local stats="/tmp/${tfile}.stats"
19441         local file0="${DIR}/${tdir}-0/${tfile}"
19442         local file1="${DIR}/${tdir}-1/${tfile}"
19443
19444         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
19445                 skip "OFD access log unsupported"
19446
19447         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
19448
19449         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
19450         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
19451
19452         lfs setstripe -c 1 -i 0 "${file0}"
19453         lfs setstripe -c 1 -i 0 "${file1}"
19454
19455         setup_165
19456         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
19457         sleep 5
19458
19459         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
19460                 error "cannot create '${file0}'"
19461         sync
19462         oal_expect_read_count "${stats}" 0
19463
19464         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
19465                 error "cannot create '${file1}'"
19466         sync
19467         oal_expect_read_count "${stats}" 1
19468
19469         do_facet ost1 killall -TERM ofd_access_log_reader
19470         wait
19471         rc=$?
19472         if ((rc != 0)); then
19473                 error "ofd_access_log_reader exited with rc = '${rc}'"
19474         fi
19475 }
19476 run_test 165e "ofd_access_log MDT index filter works"
19477
19478 test_165f() {
19479         local trace="/tmp/${tfile}.trace"
19480         local rc
19481         local count
19482
19483         setup_165
19484         do_facet ost1 timeout 60 ofd_access_log_reader \
19485                 --exit-on-close --debug=- --trace=- > "${trace}" &
19486         sleep 5
19487         stop ost1
19488
19489         wait
19490         rc=$?
19491
19492         if ((rc != 0)); then
19493                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
19494                 cat "${trace}"
19495                 exit 1
19496         fi
19497 }
19498 run_test 165f "ofd_access_log_reader --exit-on-close works"
19499
19500 test_169() {
19501         # do directio so as not to populate the page cache
19502         log "creating a 10 Mb file"
19503         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
19504                 error "multiop failed while creating a file"
19505         log "starting reads"
19506         dd if=$DIR/$tfile of=/dev/null bs=4096 &
19507         log "truncating the file"
19508         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
19509                 error "multiop failed while truncating the file"
19510         log "killing dd"
19511         kill %+ || true # reads might have finished
19512         echo "wait until dd is finished"
19513         wait
19514         log "removing the temporary file"
19515         rm -rf $DIR/$tfile || error "tmp file removal failed"
19516 }
19517 run_test 169 "parallel read and truncate should not deadlock"
19518
19519 test_170() {
19520         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19521
19522         $LCTL clear     # bug 18514
19523         $LCTL debug_daemon start $TMP/${tfile}_log_good
19524         touch $DIR/$tfile
19525         $LCTL debug_daemon stop
19526         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
19527                 error "sed failed to read log_good"
19528
19529         $LCTL debug_daemon start $TMP/${tfile}_log_good
19530         rm -rf $DIR/$tfile
19531         $LCTL debug_daemon stop
19532
19533         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
19534                error "lctl df log_bad failed"
19535
19536         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19537         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19538
19539         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
19540         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
19541
19542         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
19543                 error "bad_line good_line1 good_line2 are empty"
19544
19545         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19546         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
19547         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
19548
19549         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
19550         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
19551         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
19552
19553         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
19554                 error "bad_line_new good_line_new are empty"
19555
19556         local expected_good=$((good_line1 + good_line2*2))
19557
19558         rm -f $TMP/${tfile}*
19559         # LU-231, short malformed line may not be counted into bad lines
19560         if [ $bad_line -ne $bad_line_new ] &&
19561                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
19562                 error "expected $bad_line bad lines, but got $bad_line_new"
19563                 return 1
19564         fi
19565
19566         if [ $expected_good -ne $good_line_new ]; then
19567                 error "expected $expected_good good lines, but got $good_line_new"
19568                 return 2
19569         fi
19570         true
19571 }
19572 run_test 170 "test lctl df to handle corrupted log ====================="
19573
19574 test_171() { # bug20592
19575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19576
19577         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
19578         $LCTL set_param fail_loc=0x50e
19579         $LCTL set_param fail_val=3000
19580         multiop_bg_pause $DIR/$tfile O_s || true
19581         local MULTIPID=$!
19582         kill -USR1 $MULTIPID
19583         # cause log dump
19584         sleep 3
19585         wait $MULTIPID
19586         if dmesg | grep "recursive fault"; then
19587                 error "caught a recursive fault"
19588         fi
19589         $LCTL set_param fail_loc=0
19590         true
19591 }
19592 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
19593
19594 test_172() {
19595
19596         #define OBD_FAIL_OBD_CLEANUP  0x60e
19597         $LCTL set_param fail_loc=0x60e
19598         umount $MOUNT || error "umount $MOUNT failed"
19599         stack_trap "mount_client $MOUNT"
19600
19601         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
19602                 error "no client OBDs are remained"
19603
19604         $LCTL dl | while read devno state type name foo; do
19605                 case $type in
19606                 lov|osc|lmv|mdc)
19607                         $LCTL --device $name cleanup
19608                         $LCTL --device $name detach
19609                         ;;
19610                 *)
19611                         # skip server devices
19612                         ;;
19613                 esac
19614         done
19615
19616         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
19617                 $LCTL dl | egrep " osc | lov | lmv | mdc "
19618                 error "some client OBDs are still remained"
19619         fi
19620
19621 }
19622 run_test 172 "manual device removal with lctl cleanup/detach ======"
19623
19624 # it would be good to share it with obdfilter-survey/iokit-libecho code
19625 setup_obdecho_osc () {
19626         local rc=0
19627         local ost_nid=$1
19628         local obdfilter_name=$2
19629         echo "Creating new osc for $obdfilter_name on $ost_nid"
19630         # make sure we can find loopback nid
19631         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
19632
19633         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
19634                            ${obdfilter_name}_osc_UUID || rc=2; }
19635         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
19636                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
19637         return $rc
19638 }
19639
19640 cleanup_obdecho_osc () {
19641         local obdfilter_name=$1
19642         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
19643         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
19644         return 0
19645 }
19646
19647 obdecho_test() {
19648         local OBD=$1
19649         local node=$2
19650         local pages=${3:-64}
19651         local rc=0
19652         local id
19653
19654         local count=10
19655         local obd_size=$(get_obd_size $node $OBD)
19656         local page_size=$(get_page_size $node)
19657         if [[ -n "$obd_size" ]]; then
19658                 local new_count=$((obd_size / (pages * page_size / 1024)))
19659                 [[ $new_count -ge $count ]] || count=$new_count
19660         fi
19661
19662         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
19663         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
19664                            rc=2; }
19665         if [ $rc -eq 0 ]; then
19666             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
19667             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
19668         fi
19669         echo "New object id is $id"
19670         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
19671                            rc=4; }
19672         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
19673                            "test_brw $count w v $pages $id" || rc=4; }
19674         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
19675                            rc=4; }
19676         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
19677                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
19678         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
19679                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
19680         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
19681         return $rc
19682 }
19683
19684 test_180a() {
19685         skip "obdecho on osc is no longer supported"
19686 }
19687 run_test 180a "test obdecho on osc"
19688
19689 test_180b() {
19690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19691         remote_ost_nodsh && skip "remote OST with nodsh"
19692
19693         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19694                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19695                 error "failed to load module obdecho"
19696
19697         local target=$(do_facet ost1 $LCTL dl |
19698                        awk '/obdfilter/ { print $4; exit; }')
19699
19700         if [ -n "$target" ]; then
19701                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
19702         else
19703                 do_facet ost1 $LCTL dl
19704                 error "there is no obdfilter target on ost1"
19705         fi
19706 }
19707 run_test 180b "test obdecho directly on obdfilter"
19708
19709 test_180c() { # LU-2598
19710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19711         remote_ost_nodsh && skip "remote OST with nodsh"
19712         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
19713                 skip "Need MDS version at least 2.4.0"
19714
19715         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
19716                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
19717                 error "failed to load module obdecho"
19718
19719         local target=$(do_facet ost1 $LCTL dl |
19720                        awk '/obdfilter/ { print $4; exit; }')
19721
19722         if [ -n "$target" ]; then
19723                 local pages=16384 # 64MB bulk I/O RPC size
19724
19725                 obdecho_test "$target" ost1 "$pages" ||
19726                         error "obdecho_test with pages=$pages failed with $?"
19727         else
19728                 do_facet ost1 $LCTL dl
19729                 error "there is no obdfilter target on ost1"
19730         fi
19731 }
19732 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
19733
19734 test_181() { # bug 22177
19735         test_mkdir $DIR/$tdir
19736         # create enough files to index the directory
19737         createmany -o $DIR/$tdir/foobar 4000
19738         # print attributes for debug purpose
19739         lsattr -d .
19740         # open dir
19741         multiop_bg_pause $DIR/$tdir D_Sc || return 1
19742         MULTIPID=$!
19743         # remove the files & current working dir
19744         unlinkmany $DIR/$tdir/foobar 4000
19745         rmdir $DIR/$tdir
19746         kill -USR1 $MULTIPID
19747         wait $MULTIPID
19748         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
19749         return 0
19750 }
19751 run_test 181 "Test open-unlinked dir ========================"
19752
19753 test_182a() {
19754         local fcount=1000
19755         local tcount=10
19756
19757         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19758
19759         $LCTL set_param mdc.*.rpc_stats=clear
19760
19761         for (( i = 0; i < $tcount; i++ )) ; do
19762                 mkdir $DIR/$tdir/$i
19763         done
19764
19765         for (( i = 0; i < $tcount; i++ )) ; do
19766                 createmany -o $DIR/$tdir/$i/f- $fcount &
19767         done
19768         wait
19769
19770         for (( i = 0; i < $tcount; i++ )) ; do
19771                 unlinkmany $DIR/$tdir/$i/f- $fcount &
19772         done
19773         wait
19774
19775         $LCTL get_param mdc.*.rpc_stats
19776
19777         rm -rf $DIR/$tdir
19778 }
19779 run_test 182a "Test parallel modify metadata operations from mdc"
19780
19781 test_182b() {
19782         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19783         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19784         local dcount=1000
19785         local tcount=10
19786         local stime
19787         local etime
19788         local delta
19789
19790         do_facet mds1 $LCTL list_param \
19791                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
19792                 skip "MDS lacks parallel RPC handling"
19793
19794         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19795
19796         rpc_count=$(do_facet mds1 $LCTL get_param -n \
19797                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
19798
19799         stime=$(date +%s)
19800         createmany -i 0 -d $DIR/$tdir/t- $tcount
19801
19802         for (( i = 0; i < $tcount; i++ )) ; do
19803                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19804         done
19805         wait
19806         etime=$(date +%s)
19807         delta=$((etime - stime))
19808         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
19809
19810         stime=$(date +%s)
19811         for (( i = 0; i < $tcount; i++ )) ; do
19812                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
19813         done
19814         wait
19815         etime=$(date +%s)
19816         delta=$((etime - stime))
19817         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
19818
19819         rm -rf $DIR/$tdir
19820
19821         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19822
19823         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
19824
19825         stime=$(date +%s)
19826         createmany -i 0 -d $DIR/$tdir/t- $tcount
19827
19828         for (( i = 0; i < $tcount; i++ )) ; do
19829                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
19830         done
19831         wait
19832         etime=$(date +%s)
19833         delta=$((etime - stime))
19834         echo "Time for file creation $delta sec for 1 RPC sent at a time"
19835
19836         stime=$(date +%s)
19837         for (( i = 0; i < $tcount; i++ )) ; do
19838                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
19839         done
19840         wait
19841         etime=$(date +%s)
19842         delta=$((etime - stime))
19843         echo "Time for file removal $delta sec for 1 RPC sent at a time"
19844
19845         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
19846 }
19847 run_test 182b "Test parallel modify metadata operations from osp"
19848
19849 test_183() { # LU-2275
19850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19851         remote_mds_nodsh && skip "remote MDS with nodsh"
19852         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
19853                 skip "Need MDS version at least 2.3.56"
19854
19855         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
19856         echo aaa > $DIR/$tdir/$tfile
19857
19858 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
19859         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
19860
19861         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
19862         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
19863
19864         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
19865
19866         # Flush negative dentry cache
19867         touch $DIR/$tdir/$tfile
19868
19869         # We are not checking for any leaked references here, they'll
19870         # become evident next time we do cleanup with module unload.
19871         rm -rf $DIR/$tdir
19872 }
19873 run_test 183 "No crash or request leak in case of strange dispositions ========"
19874
19875 # test suite 184 is for LU-2016, LU-2017
19876 test_184a() {
19877         check_swap_layouts_support
19878
19879         dir0=$DIR/$tdir/$testnum
19880         test_mkdir -p -c1 $dir0
19881         ref1=/etc/passwd
19882         ref2=/etc/group
19883         file1=$dir0/f1
19884         file2=$dir0/f2
19885         $LFS setstripe -c1 $file1
19886         cp $ref1 $file1
19887         $LFS setstripe -c2 $file2
19888         cp $ref2 $file2
19889         gen1=$($LFS getstripe -g $file1)
19890         gen2=$($LFS getstripe -g $file2)
19891
19892         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
19893         gen=$($LFS getstripe -g $file1)
19894         [[ $gen1 != $gen ]] ||
19895                 error "Layout generation on $file1 does not change"
19896         gen=$($LFS getstripe -g $file2)
19897         [[ $gen2 != $gen ]] ||
19898                 error "Layout generation on $file2 does not change"
19899
19900         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19901         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19902
19903         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19904 }
19905 run_test 184a "Basic layout swap"
19906
19907 test_184b() {
19908         check_swap_layouts_support
19909
19910         dir0=$DIR/$tdir/$testnum
19911         mkdir -p $dir0 || error "creating dir $dir0"
19912         file1=$dir0/f1
19913         file2=$dir0/f2
19914         file3=$dir0/f3
19915         dir1=$dir0/d1
19916         dir2=$dir0/d2
19917         mkdir $dir1 $dir2
19918         $LFS setstripe -c1 $file1
19919         $LFS setstripe -c2 $file2
19920         $LFS setstripe -c1 $file3
19921         chown $RUNAS_ID $file3
19922         gen1=$($LFS getstripe -g $file1)
19923         gen2=$($LFS getstripe -g $file2)
19924
19925         $LFS swap_layouts $dir1 $dir2 &&
19926                 error "swap of directories layouts should fail"
19927         $LFS swap_layouts $dir1 $file1 &&
19928                 error "swap of directory and file layouts should fail"
19929         $RUNAS $LFS swap_layouts $file1 $file2 &&
19930                 error "swap of file we cannot write should fail"
19931         $LFS swap_layouts $file1 $file3 &&
19932                 error "swap of file with different owner should fail"
19933         /bin/true # to clear error code
19934 }
19935 run_test 184b "Forbidden layout swap (will generate errors)"
19936
19937 test_184c() {
19938         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19939         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19940         check_swap_layouts_support
19941         check_swap_layout_no_dom $DIR
19942
19943         local dir0=$DIR/$tdir/$testnum
19944         mkdir -p $dir0 || error "creating dir $dir0"
19945
19946         local ref1=$dir0/ref1
19947         local ref2=$dir0/ref2
19948         local file1=$dir0/file1
19949         local file2=$dir0/file2
19950         # create a file large enough for the concurrent test
19951         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19952         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19953         echo "ref file size: ref1($(stat -c %s $ref1))," \
19954              "ref2($(stat -c %s $ref2))"
19955
19956         cp $ref2 $file2
19957         dd if=$ref1 of=$file1 bs=16k &
19958         local DD_PID=$!
19959
19960         # Make sure dd starts to copy file, but wait at most 5 seconds
19961         local loops=0
19962         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19963
19964         $LFS swap_layouts $file1 $file2
19965         local rc=$?
19966         wait $DD_PID
19967         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19968         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19969
19970         # how many bytes copied before swapping layout
19971         local copied=$(stat -c %s $file2)
19972         local remaining=$(stat -c %s $ref1)
19973         remaining=$((remaining - copied))
19974         echo "Copied $copied bytes before swapping layout..."
19975
19976         cmp -n $copied $file1 $ref2 | grep differ &&
19977                 error "Content mismatch [0, $copied) of ref2 and file1"
19978         cmp -n $copied $file2 $ref1 ||
19979                 error "Content mismatch [0, $copied) of ref1 and file2"
19980         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19981                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19982
19983         # clean up
19984         rm -f $ref1 $ref2 $file1 $file2
19985 }
19986 run_test 184c "Concurrent write and layout swap"
19987
19988 test_184d() {
19989         check_swap_layouts_support
19990         check_swap_layout_no_dom $DIR
19991         [ -z "$(which getfattr 2>/dev/null)" ] &&
19992                 skip_env "no getfattr command"
19993
19994         local file1=$DIR/$tdir/$tfile-1
19995         local file2=$DIR/$tdir/$tfile-2
19996         local file3=$DIR/$tdir/$tfile-3
19997         local lovea1
19998         local lovea2
19999
20000         mkdir -p $DIR/$tdir
20001         touch $file1 || error "create $file1 failed"
20002         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20003                 error "create $file2 failed"
20004         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20005                 error "create $file3 failed"
20006         lovea1=$(get_layout_param $file1)
20007
20008         $LFS swap_layouts $file2 $file3 ||
20009                 error "swap $file2 $file3 layouts failed"
20010         $LFS swap_layouts $file1 $file2 ||
20011                 error "swap $file1 $file2 layouts failed"
20012
20013         lovea2=$(get_layout_param $file2)
20014         echo "$lovea1"
20015         echo "$lovea2"
20016         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
20017
20018         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20019         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
20020 }
20021 run_test 184d "allow stripeless layouts swap"
20022
20023 test_184e() {
20024         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
20025                 skip "Need MDS version at least 2.6.94"
20026         check_swap_layouts_support
20027         check_swap_layout_no_dom $DIR
20028         [ -z "$(which getfattr 2>/dev/null)" ] &&
20029                 skip_env "no getfattr command"
20030
20031         local file1=$DIR/$tdir/$tfile-1
20032         local file2=$DIR/$tdir/$tfile-2
20033         local file3=$DIR/$tdir/$tfile-3
20034         local lovea
20035
20036         mkdir -p $DIR/$tdir
20037         touch $file1 || error "create $file1 failed"
20038         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
20039                 error "create $file2 failed"
20040         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
20041                 error "create $file3 failed"
20042
20043         $LFS swap_layouts $file1 $file2 ||
20044                 error "swap $file1 $file2 layouts failed"
20045
20046         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
20047         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
20048
20049         echo 123 > $file1 || error "Should be able to write into $file1"
20050
20051         $LFS swap_layouts $file1 $file3 ||
20052                 error "swap $file1 $file3 layouts failed"
20053
20054         echo 123 > $file1 || error "Should be able to write into $file1"
20055
20056         rm -rf $file1 $file2 $file3
20057 }
20058 run_test 184e "Recreate layout after stripeless layout swaps"
20059
20060 test_184f() {
20061         # Create a file with name longer than sizeof(struct stat) ==
20062         # 144 to see if we can get chars from the file name to appear
20063         # in the returned striping. Note that 'f' == 0x66.
20064         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
20065
20066         mkdir -p $DIR/$tdir
20067         mcreate $DIR/$tdir/$file
20068         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
20069                 error "IOC_MDC_GETFILEINFO returned garbage striping"
20070         fi
20071 }
20072 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
20073
20074 test_185() { # LU-2441
20075         # LU-3553 - no volatile file support in old servers
20076         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
20077                 skip "Need MDS version at least 2.3.60"
20078
20079         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
20080         touch $DIR/$tdir/spoo
20081         local mtime1=$(stat -c "%Y" $DIR/$tdir)
20082         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
20083                 error "cannot create/write a volatile file"
20084         [ "$FILESET" == "" ] &&
20085         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
20086                 error "FID is still valid after close"
20087
20088         multiop_bg_pause $DIR/$tdir Vw4096_c
20089         local multi_pid=$!
20090
20091         local OLD_IFS=$IFS
20092         IFS=":"
20093         local fidv=($fid)
20094         IFS=$OLD_IFS
20095         # assume that the next FID for this client is sequential, since stdout
20096         # is unfortunately eaten by multiop_bg_pause
20097         local n=$((${fidv[1]} + 1))
20098         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
20099         if [ "$FILESET" == "" ]; then
20100                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
20101                         error "FID is missing before close"
20102         fi
20103         kill -USR1 $multi_pid
20104         # 1 second delay, so if mtime change we will see it
20105         sleep 1
20106         local mtime2=$(stat -c "%Y" $DIR/$tdir)
20107         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
20108 }
20109 run_test 185 "Volatile file support"
20110
20111 function create_check_volatile() {
20112         local idx=$1
20113         local tgt
20114
20115         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
20116         local PID=$!
20117         sleep 1
20118         local FID=$(cat /tmp/${tfile}.fid)
20119         [ "$FID" == "" ] && error "can't get FID for volatile"
20120         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
20121         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
20122         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
20123         kill -USR1 $PID
20124         wait
20125         sleep 1
20126         cancel_lru_locks mdc # flush opencache
20127         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
20128         return 0
20129 }
20130
20131 test_185a(){
20132         # LU-12516 - volatile creation via .lustre
20133         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
20134                 skip "Need MDS version at least 2.3.55"
20135
20136         create_check_volatile 0
20137         [ $MDSCOUNT -lt 2 ] && return 0
20138
20139         # DNE case
20140         create_check_volatile 1
20141
20142         return 0
20143 }
20144 run_test 185a "Volatile file creation in .lustre/fid/"
20145
20146 test_187a() {
20147         remote_mds_nodsh && skip "remote MDS with nodsh"
20148         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20149                 skip "Need MDS version at least 2.3.0"
20150
20151         local dir0=$DIR/$tdir/$testnum
20152         mkdir -p $dir0 || error "creating dir $dir0"
20153
20154         local file=$dir0/file1
20155         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
20156         stack_trap "rm -f $file"
20157         local dv1=$($LFS data_version $file)
20158         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
20159         local dv2=$($LFS data_version $file)
20160         [[ $dv1 != $dv2 ]] ||
20161                 error "data version did not change on write $dv1 == $dv2"
20162 }
20163 run_test 187a "Test data version change"
20164
20165 test_187b() {
20166         remote_mds_nodsh && skip "remote MDS with nodsh"
20167         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
20168                 skip "Need MDS version at least 2.3.0"
20169
20170         local dir0=$DIR/$tdir/$testnum
20171         mkdir -p $dir0 || error "creating dir $dir0"
20172
20173         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
20174         [[ ${DV[0]} != ${DV[1]} ]] ||
20175                 error "data version did not change on write"\
20176                       " ${DV[0]} == ${DV[1]}"
20177
20178         # clean up
20179         rm -f $file1
20180 }
20181 run_test 187b "Test data version change on volatile file"
20182
20183 test_200() {
20184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20185         remote_mgs_nodsh && skip "remote MGS with nodsh"
20186         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20187
20188         local POOL=${POOL:-cea1}
20189         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
20190         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
20191         # Pool OST targets
20192         local first_ost=0
20193         local last_ost=$(($OSTCOUNT - 1))
20194         local ost_step=2
20195         local ost_list=$(seq $first_ost $ost_step $last_ost)
20196         local ost_range="$first_ost $last_ost $ost_step"
20197         local test_path=$POOL_ROOT/$POOL_DIR_NAME
20198         local file_dir=$POOL_ROOT/file_tst
20199         local subdir=$test_path/subdir
20200         local rc=0
20201
20202         while : ; do
20203                 # former test_200a test_200b
20204                 pool_add $POOL                          || { rc=$? ; break; }
20205                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
20206                 # former test_200c test_200d
20207                 mkdir -p $test_path
20208                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
20209                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
20210                 mkdir -p $subdir
20211                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
20212                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
20213                                                         || { rc=$? ; break; }
20214                 # former test_200e test_200f
20215                 local files=$((OSTCOUNT*3))
20216                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
20217                                                         || { rc=$? ; break; }
20218                 pool_create_files $POOL $file_dir $files "$ost_list" \
20219                                                         || { rc=$? ; break; }
20220                 # former test_200g test_200h
20221                 pool_lfs_df $POOL                       || { rc=$? ; break; }
20222                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
20223
20224                 # former test_201a test_201b test_201c
20225                 pool_remove_first_target $POOL          || { rc=$? ; break; }
20226
20227                 local f=$test_path/$tfile
20228                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
20229                 pool_remove $POOL $f                    || { rc=$? ; break; }
20230                 break
20231         done
20232
20233         destroy_test_pools
20234
20235         return $rc
20236 }
20237 run_test 200 "OST pools"
20238
20239 # usage: default_attr <count | size | offset>
20240 default_attr() {
20241         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
20242 }
20243
20244 # usage: check_default_stripe_attr
20245 check_default_stripe_attr() {
20246         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
20247         case $1 in
20248         --stripe-count|-c)
20249                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
20250         --stripe-size|-S)
20251                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
20252         --stripe-index|-i)
20253                 EXPECTED=-1;;
20254         *)
20255                 error "unknown getstripe attr '$1'"
20256         esac
20257
20258         [ $ACTUAL == $EXPECTED ] ||
20259                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
20260 }
20261
20262 test_204a() {
20263         test_mkdir $DIR/$tdir
20264         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
20265
20266         check_default_stripe_attr --stripe-count
20267         check_default_stripe_attr --stripe-size
20268         check_default_stripe_attr --stripe-index
20269 }
20270 run_test 204a "Print default stripe attributes"
20271
20272 test_204b() {
20273         test_mkdir $DIR/$tdir
20274         $LFS setstripe --stripe-count 1 $DIR/$tdir
20275
20276         check_default_stripe_attr --stripe-size
20277         check_default_stripe_attr --stripe-index
20278 }
20279 run_test 204b "Print default stripe size and offset"
20280
20281 test_204c() {
20282         test_mkdir $DIR/$tdir
20283         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20284
20285         check_default_stripe_attr --stripe-count
20286         check_default_stripe_attr --stripe-index
20287 }
20288 run_test 204c "Print default stripe count and offset"
20289
20290 test_204d() {
20291         test_mkdir $DIR/$tdir
20292         $LFS setstripe --stripe-index 0 $DIR/$tdir
20293
20294         check_default_stripe_attr --stripe-count
20295         check_default_stripe_attr --stripe-size
20296 }
20297 run_test 204d "Print default stripe count and size"
20298
20299 test_204e() {
20300         test_mkdir $DIR/$tdir
20301         $LFS setstripe -d $DIR/$tdir
20302
20303         # LU-16904 check if root is set as PFL layout
20304         local numcomp=$($LFS getstripe --component-count $MOUNT)
20305
20306         if [[ $numcomp -gt 0 ]]; then
20307                 check_default_stripe_attr --stripe-count
20308         else
20309                 check_default_stripe_attr --stripe-count --raw
20310         fi
20311         check_default_stripe_attr --stripe-size --raw
20312         check_default_stripe_attr --stripe-index --raw
20313 }
20314 run_test 204e "Print raw stripe attributes"
20315
20316 test_204f() {
20317         test_mkdir $DIR/$tdir
20318         $LFS setstripe --stripe-count 1 $DIR/$tdir
20319
20320         check_default_stripe_attr --stripe-size --raw
20321         check_default_stripe_attr --stripe-index --raw
20322 }
20323 run_test 204f "Print raw stripe size and offset"
20324
20325 test_204g() {
20326         test_mkdir $DIR/$tdir
20327         $LFS setstripe --stripe-size 65536 $DIR/$tdir
20328
20329         check_default_stripe_attr --stripe-count --raw
20330         check_default_stripe_attr --stripe-index --raw
20331 }
20332 run_test 204g "Print raw stripe count and offset"
20333
20334 test_204h() {
20335         test_mkdir $DIR/$tdir
20336         $LFS setstripe --stripe-index 0 $DIR/$tdir
20337
20338         check_default_stripe_attr --stripe-count --raw
20339         check_default_stripe_attr --stripe-size --raw
20340 }
20341 run_test 204h "Print raw stripe count and size"
20342
20343 # Figure out which job scheduler is being used, if any,
20344 # or use a fake one
20345 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
20346         JOBENV=SLURM_JOB_ID
20347 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
20348         JOBENV=LSB_JOBID
20349 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
20350         JOBENV=PBS_JOBID
20351 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
20352         JOBENV=LOADL_STEP_ID
20353 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
20354         JOBENV=JOB_ID
20355 else
20356         $LCTL list_param jobid_name > /dev/null 2>&1
20357         if [ $? -eq 0 ]; then
20358                 JOBENV=nodelocal
20359         else
20360                 JOBENV=FAKE_JOBID
20361         fi
20362 fi
20363 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
20364
20365 verify_jobstats() {
20366         local cmd=($1)
20367         shift
20368         local facets="$@"
20369
20370 # we don't really need to clear the stats for this test to work, since each
20371 # command has a unique jobid, but it makes debugging easier if needed.
20372 #       for facet in $facets; do
20373 #               local dev=$(convert_facet2label $facet)
20374 #               # clear old jobstats
20375 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
20376 #       done
20377
20378         # use a new JobID for each test, or we might see an old one
20379         [ "$JOBENV" = "FAKE_JOBID" ] &&
20380                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
20381
20382         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
20383
20384         [ "$JOBENV" = "nodelocal" ] && {
20385                 FAKE_JOBID=id.$testnum.%e.$RANDOM
20386                 $LCTL set_param jobid_name=$FAKE_JOBID
20387                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
20388         }
20389
20390         log "Test: ${cmd[*]}"
20391         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
20392
20393         if [ $JOBENV = "FAKE_JOBID" ]; then
20394                 FAKE_JOBID=$JOBVAL ${cmd[*]}
20395         else
20396                 ${cmd[*]}
20397         fi
20398
20399         # all files are created on OST0000
20400         for facet in $facets; do
20401                 local stats="*.$(convert_facet2label $facet).job_stats"
20402
20403                 # strip out libtool wrappers for in-tree executables
20404                 if (( $(do_facet $facet lctl get_param $stats |
20405                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
20406                         do_facet $facet lctl get_param $stats
20407                         error "No jobstats for $JOBVAL found on $facet::$stats"
20408                 fi
20409         done
20410 }
20411
20412 jobstats_set() {
20413         local new_jobenv=$1
20414
20415         set_persistent_param_and_check client "jobid_var" \
20416                 "$FSNAME.sys.jobid_var" $new_jobenv
20417 }
20418
20419 test_205a() { # Job stats
20420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20421         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
20422                 skip "Need MDS version with at least 2.7.1"
20423         remote_mgs_nodsh && skip "remote MGS with nodsh"
20424         remote_mds_nodsh && skip "remote MDS with nodsh"
20425         remote_ost_nodsh && skip "remote OST with nodsh"
20426         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
20427                 skip "Server doesn't support jobstats"
20428         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
20429
20430         local old_jobenv=$($LCTL get_param -n jobid_var)
20431         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
20432         stack_trap "jobstats_set $old_jobenv" EXIT
20433
20434         changelog_register
20435
20436         local old_jobid_name=$($LCTL get_param jobid_name)
20437         stack_trap "$LCTL set_param $old_jobid_name" EXIT
20438
20439         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
20440                                 mdt.*.job_cleanup_interval | head -n 1)
20441         local new_interval=5
20442         do_facet $SINGLEMDS \
20443                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
20444         stack_trap "do_facet $SINGLEMDS \
20445                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
20446         local start=$SECONDS
20447
20448         local cmd
20449         # mkdir
20450         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
20451         verify_jobstats "$cmd" "$SINGLEMDS"
20452         # rmdir
20453         cmd="rmdir $DIR/$tdir"
20454         verify_jobstats "$cmd" "$SINGLEMDS"
20455         # mkdir on secondary MDT
20456         if [ $MDSCOUNT -gt 1 ]; then
20457                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
20458                 verify_jobstats "$cmd" "mds2"
20459         fi
20460         # mknod
20461         cmd="mknod $DIR/$tfile c 1 3"
20462         verify_jobstats "$cmd" "$SINGLEMDS"
20463         # unlink
20464         cmd="rm -f $DIR/$tfile"
20465         verify_jobstats "$cmd" "$SINGLEMDS"
20466         # create all files on OST0000 so verify_jobstats can find OST stats
20467         # open & close
20468         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
20469         verify_jobstats "$cmd" "$SINGLEMDS"
20470         # setattr
20471         cmd="touch $DIR/$tfile"
20472         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20473         # write
20474         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
20475         verify_jobstats "$cmd" "ost1"
20476         # read
20477         cancel_lru_locks osc
20478         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
20479         verify_jobstats "$cmd" "ost1"
20480         # truncate
20481         cmd="$TRUNCATE $DIR/$tfile 0"
20482         verify_jobstats "$cmd" "$SINGLEMDS ost1"
20483         # rename
20484         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
20485         verify_jobstats "$cmd" "$SINGLEMDS"
20486         # jobstats expiry - sleep until old stats should be expired
20487         local left=$((new_interval + 5 - (SECONDS - start)))
20488         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
20489                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
20490                         "0" $left
20491         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
20492         verify_jobstats "$cmd" "$SINGLEMDS"
20493         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
20494             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
20495
20496         # Ensure that jobid are present in changelog (if supported by MDS)
20497         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
20498                 changelog_dump | tail -10
20499                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
20500                 [ $jobids -eq 9 ] ||
20501                         error "Wrong changelog jobid count $jobids != 9"
20502
20503                 # LU-5862
20504                 JOBENV="disable"
20505                 jobstats_set $JOBENV
20506                 touch $DIR/$tfile
20507                 changelog_dump | grep $tfile
20508                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
20509                 [ $jobids -eq 0 ] ||
20510                         error "Unexpected jobids when jobid_var=$JOBENV"
20511         fi
20512
20513         # test '%j' access to environment variable - if supported
20514         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
20515                 JOBENV="JOBCOMPLEX"
20516                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20517
20518                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20519         fi
20520
20521         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
20522                 JOBENV="JOBCOMPLEX"
20523                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
20524
20525                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20526         fi
20527
20528         # test '%j' access to per-session jobid - if supported
20529         if lctl list_param jobid_this_session > /dev/null 2>&1
20530         then
20531                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
20532                 lctl set_param jobid_this_session=$USER
20533
20534                 JOBENV="JOBCOMPLEX"
20535                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
20536
20537                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
20538         fi
20539 }
20540 run_test 205a "Verify job stats"
20541
20542 # LU-13117, LU-13597, LU-16599
20543 test_205b() {
20544         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
20545                 skip "Need MDS version at least 2.13.54.91"
20546
20547         local job_stats="mdt.*.job_stats"
20548         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
20549
20550         do_facet mds1 $LCTL set_param $job_stats=clear
20551
20552         # Setting jobid_var to USER might not be supported
20553         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
20554         $LCTL set_param jobid_var=USER || true
20555         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
20556         $LCTL set_param jobid_name="%j.%e.%u"
20557
20558         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
20559         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
20560                 { do_facet mds1 $LCTL get_param $job_stats;
20561                   error "Unexpected jobid found"; }
20562         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
20563                 { do_facet mds1 $LCTL get_param $job_stats;
20564                   error "wrong job_stats format found"; }
20565
20566         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
20567                 echo "MDS does not yet escape jobid" && return 0
20568
20569         mkdir_on_mdt0 $DIR/$tdir
20570         $LCTL set_param jobid_var=TEST205b
20571         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
20572         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
20573                       awk '/has\\x20sp/ {print $3}')
20574         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
20575                   error "jobid not escaped"; }
20576
20577         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
20578                 # need to run such a command on mds1:
20579                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
20580                 #
20581                 # there might be multiple MDTs on single mds server, so need to
20582                 # specifiy MDT0000. Or the command will fail due to other MDTs
20583                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
20584                         error "cannot clear escaped jobid in job_stats";
20585         else
20586                 echo "MDS does not support clearing escaped jobid"
20587         fi
20588 }
20589 run_test 205b "Verify job stats jobid and output format"
20590
20591 # LU-13733
20592 test_205c() {
20593         $LCTL set_param llite.*.stats=0
20594         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
20595         $LCTL get_param llite.*.stats
20596         $LCTL get_param llite.*.stats | grep \
20597                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
20598                         error "wrong client stats format found"
20599 }
20600 run_test 205c "Verify client stats format"
20601
20602 test_205d() {
20603         local file=$DIR/$tdir/$tfile
20604
20605         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20606                 skip "need lustre >= 2.15.53 for lljobstat"
20607         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20608                 skip "need lustre >= 2.15.53 for lljobstat"
20609         verify_yaml_available || skip_env "YAML verification not installed"
20610
20611         test_mkdir -i 0 $DIR/$tdir
20612         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
20613         stack_trap "rm -rf $DIR/$tdir"
20614
20615         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
20616                 error "failed to write data to $file"
20617         mv $file $file.2
20618
20619         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
20620         echo -n 'verify rename_stats...'
20621         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
20622                 verify_yaml || error "rename_stats is not valid YAML"
20623         echo " OK"
20624
20625         echo -n 'verify mdt job_stats...'
20626         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
20627                 verify_yaml || error "job_stats on mds1 is not valid YAML"
20628         echo " OK"
20629
20630         echo -n 'verify ost job_stats...'
20631         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
20632                 verify_yaml || error "job_stats on ost1 is not valid YAML"
20633         echo " OK"
20634 }
20635 run_test 205d "verify the format of some stats files"
20636
20637 test_205e() {
20638         local ops_comma
20639         local file=$DIR/$tdir/$tfile
20640         local -a cli_params
20641
20642         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
20643                 skip "need lustre >= 2.15.53 for lljobstat"
20644         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
20645                 skip "need lustre >= 2.15.53 for lljobstat"
20646         verify_yaml_available || skip_env "YAML verification not installed"
20647
20648         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20649         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
20650         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20651
20652         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
20653         stack_trap "rm -rf $DIR/$tdir"
20654
20655         $LFS setstripe -E EOF -i 0 -c 1 $file ||
20656                 error "failed to create $file on ost1"
20657         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
20658                 error "failed to write data to $file"
20659
20660         do_facet mds1 "$LCTL get_param *.*.job_stats"
20661         do_facet ost1 "$LCTL get_param *.*.job_stats"
20662
20663         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
20664         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
20665                 error "The output of lljobstat is not an valid YAML"
20666
20667         # verify that job dd.0 does exist and has some ops on ost1
20668         # typically this line is like:
20669         # - 205e.dd.0:            {ops: 20, ...}
20670         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
20671                     awk '$2=="205e.dd.0:" {print $4}')
20672
20673         (( ${ops_comma%,} >= 10 )) ||
20674                 error "cannot find job 205e.dd.0 with ops >= 10"
20675 }
20676 run_test 205e "verify the output of lljobstat"
20677
20678 test_205f() {
20679         verify_yaml_available || skip_env "YAML verification not installed"
20680
20681         # check both qos_ost_weights and qos_mdt_weights
20682         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
20683         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
20684                 error "qos_ost_weights is not valid YAML"
20685 }
20686 run_test 205f "verify qos_ost_weights YAML format "
20687
20688 __test_205_jobstats_dump() {
20689         local -a pids
20690         local nbr_instance=$1
20691
20692         while true; do
20693                 if (( ${#pids[@]} >= nbr_instance )); then
20694                         wait ${pids[@]}
20695                         pids=()
20696                 fi
20697
20698                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
20699                 pids+=( $! )
20700         done
20701 }
20702
20703 __test_205_cleanup() {
20704         kill $@
20705         # Clear all job entries
20706         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
20707 }
20708
20709 test_205g() {
20710         local -a mds1_params
20711         local -a cli_params
20712         local pids
20713         local interval=5
20714
20715         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
20716         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
20717         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
20718
20719         cli_params=( $($LCTL get_param jobid_name jobid_var) )
20720         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
20721         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
20722
20723         # start jobs loop
20724         export TEST205G_ID=205g
20725         stack_trap "unset TEST205G_ID" EXIT
20726         while true; do
20727                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
20728         done & pids="$! "
20729
20730         __test_205_jobstats_dump 4 & pids+="$! "
20731         stack_trap "__test_205_cleanup $pids" EXIT INT
20732
20733         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
20734 }
20735 run_test 205g "stress test for job_stats procfile"
20736
20737 test_205h() {
20738         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20739                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20740         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20741
20742         local dir=$DIR/$tdir
20743         local f=$dir/$tfile
20744         local f2=$dir/$tfile-2
20745         local f3=$dir/$tfile-3
20746         local subdir=$DIR/dir
20747         local val
20748
20749         local mdts=$(comma_list $(mdts_nodes))
20750         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20751         local client_saved=$($LCTL get_param -n jobid_var)
20752
20753         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20754         stack_trap "$LCTL set_param jobid_var=$client_saved" EXIT
20755
20756         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job ||
20757                 error "failed to set job_xattr parameter to user.job"
20758         $LCTL set_param jobid_var=procname.uid ||
20759                 error "failed to set jobid_var parameter"
20760
20761         test_mkdir $dir
20762
20763         touch $f
20764         val=$(getfattr -n user.job $f | grep user.job)
20765         [[ $val = user.job=\"touch.0\" ]] ||
20766                 error "expected user.job=\"touch.0\", got '$val'"
20767
20768         mkdir $subdir
20769         val=$(getfattr -n user.job $subdir | grep user.job)
20770         [[ $val = user.job=\"mkdir.0\" ]] ||
20771                 error "expected user.job=\"mkdir.0\", got '$val'"
20772
20773         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=NONE ||
20774                 error "failed to set job_xattr parameter to NONE"
20775
20776         touch $f2
20777         val=$(getfattr -d $f2)
20778         [[ -z $val ]] ||
20779                 error "expected no user xattr, got '$val'"
20780
20781         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=trusted.job ||
20782                 error "failed to set job_xattr parameter to trusted.job"
20783
20784         touch $f3
20785         val=$(getfattr -n trusted.job $f3 | grep trusted.job)
20786         [[ $val = trusted.job=\"touch.0\" ]] ||
20787                 error "expected trusted.job=\"touch.0\", got '$val'"
20788 }
20789 run_test 205h "check jobid xattr is stored correctly"
20790
20791 test_205i() {
20792         (( $MDS1_VERSION >= $(version_code 2.15.57.7) )) ||
20793                 skip "Need MDS >= v2_15_57-7-g23a2db28dc for jobid xattr"
20794
20795         local mdts=$(comma_list $(mdts_nodes))
20796         local mds_saved=$(do_facet mds1 $LCTL get_param -n mdt.$FSNAME-MDT0000.job_xattr)
20797
20798         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.job_xattr=$mds_saved" EXIT
20799
20800         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.1234567 ||
20801                 error "failed to set mdt.*.job_xattr to user.1234567"
20802
20803         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.12345678 &&
20804                 error "failed to reject too long job_xattr name"
20805
20806         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=userjob &&
20807                 error "failed to reject job_xattr name in bad format"
20808
20809         do_nodes $mdts $LCTL set_param mdt.*.job_xattr=user.job/ &&
20810                 error "failed to reject job_xattr name with invalid character"
20811
20812         do_nodes $mdts "printf 'mdt.*.job_xattr=user.job\x80' |
20813                         xargs $LCTL set_param" &&
20814                 error "failed to reject job_xattr name with non-ascii character"
20815
20816         return 0
20817 }
20818 run_test 205i "check job_xattr parameter accepts and rejects values correctly"
20819
20820 # LU-1480, LU-1773 and LU-1657
20821 test_206() {
20822         mkdir -p $DIR/$tdir
20823         $LFS setstripe -c -1 $DIR/$tdir
20824 #define OBD_FAIL_LOV_INIT 0x1403
20825         $LCTL set_param fail_loc=0xa0001403
20826         $LCTL set_param fail_val=1
20827         touch $DIR/$tdir/$tfile || true
20828 }
20829 run_test 206 "fail lov_init_raid0() doesn't lbug"
20830
20831 test_207a() {
20832         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20833         local fsz=`stat -c %s $DIR/$tfile`
20834         cancel_lru_locks mdc
20835
20836         # do not return layout in getattr intent
20837 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
20838         $LCTL set_param fail_loc=0x170
20839         local sz=`stat -c %s $DIR/$tfile`
20840
20841         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
20842
20843         rm -rf $DIR/$tfile
20844 }
20845 run_test 207a "can refresh layout at glimpse"
20846
20847 test_207b() {
20848         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
20849         local cksum=`md5sum $DIR/$tfile`
20850         local fsz=`stat -c %s $DIR/$tfile`
20851         cancel_lru_locks mdc
20852         cancel_lru_locks osc
20853
20854         # do not return layout in getattr intent
20855 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
20856         $LCTL set_param fail_loc=0x171
20857
20858         # it will refresh layout after the file is opened but before read issues
20859         echo checksum is "$cksum"
20860         echo "$cksum" |md5sum -c --quiet || error "file differs"
20861
20862         rm -rf $DIR/$tfile
20863 }
20864 run_test 207b "can refresh layout at open"
20865
20866 test_208() {
20867         # FIXME: in this test suite, only RD lease is used. This is okay
20868         # for now as only exclusive open is supported. After generic lease
20869         # is done, this test suite should be revised. - Jinshan
20870
20871         remote_mds_nodsh && skip "remote MDS with nodsh"
20872         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
20873                 skip "Need MDS version at least 2.4.52"
20874
20875         echo "==== test 1: verify get lease work"
20876         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
20877
20878         echo "==== test 2: verify lease can be broken by upcoming open"
20879         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20880         local PID=$!
20881         sleep 2
20882
20883         $MULTIOP $DIR/$tfile oO_RDWR:c
20884         kill -USR1 $PID && wait $PID || error "break lease error"
20885
20886         echo "==== test 3: verify lease can't be granted if an open already exists"
20887         $MULTIOP $DIR/$tfile oO_RDWR:_c &
20888         local PID=$!
20889         sleep 2
20890
20891         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
20892         kill -USR1 $PID && wait $PID || error "open file error"
20893
20894         echo "==== test 4: lease can sustain over recovery"
20895         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
20896         PID=$!
20897         sleep 2
20898
20899         fail mds1
20900
20901         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
20902
20903         echo "==== test 5: lease broken can't be regained by replay"
20904         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
20905         PID=$!
20906         sleep 2
20907
20908         # open file to break lease and then recovery
20909         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
20910         fail mds1
20911
20912         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
20913
20914         rm -f $DIR/$tfile
20915 }
20916 run_test 208 "Exclusive open"
20917
20918 test_209() {
20919         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
20920                 skip_env "must have disp_stripe"
20921
20922         touch $DIR/$tfile
20923         sync; sleep 5; sync;
20924
20925         echo 3 > /proc/sys/vm/drop_caches
20926         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20927                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20928         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20929
20930         # open/close 500 times
20931         for i in $(seq 500); do
20932                 cat $DIR/$tfile
20933         done
20934
20935         echo 3 > /proc/sys/vm/drop_caches
20936         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
20937                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
20938         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
20939
20940         echo "before: $req_before, after: $req_after"
20941         [ $((req_after - req_before)) -ge 300 ] &&
20942                 error "open/close requests are not freed"
20943         return 0
20944 }
20945 run_test 209 "read-only open/close requests should be freed promptly"
20946
20947 test_210() {
20948         local pid
20949
20950         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
20951         pid=$!
20952         sleep 1
20953
20954         $LFS getstripe $DIR/$tfile
20955         kill -USR1 $pid
20956         wait $pid || error "multiop failed"
20957
20958         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
20959         pid=$!
20960         sleep 1
20961
20962         $LFS getstripe $DIR/$tfile
20963         kill -USR1 $pid
20964         wait $pid || error "multiop failed"
20965 }
20966 run_test 210 "lfs getstripe does not break leases"
20967
20968 function test_211() {
20969         local PID
20970         local id
20971         local rc
20972
20973         stack_trap "rm -f $DIR/$tfile" EXIT
20974         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=10 oflag=direct ||
20975                 error "can't create file"
20976         $LFS mirror extend -N $DIR/$tfile ||
20977                 error "can't create a replica"
20978         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20979         $LFS getstripe $DIR/$tfile
20980         stale=$($LFS getstripe $DIR/$tfile | grep stale | wc -l)
20981         (( $stale != 1 )) && error "expected 1 stale, found $stale"
20982
20983         $MULTIOP $DIR/$tfile OeW_E+eUc &
20984         PID=$!
20985         sleep 0.3
20986
20987         id=$($LFS getstripe $DIR/$tfile |
20988                 awk '/lcme_mirror_id:/{id=$2}/lcme_flags.*init$/{print id}')
20989         $LFS mirror split -d --mirror-id $id $DIR/$tfile &&
20990                 error "removed last in-sync replica?"
20991
20992         kill -USR1 $PID
20993         wait $PID
20994         (( $? == 0 )) || error "failed split broke the lease"
20995 }
20996 run_test 211 "failed mirror split doesn't break write lease"
20997
20998 test_212() {
20999         size=`date +%s`
21000         size=$((size % 8192 + 1))
21001         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
21002         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
21003         rm -f $DIR/f212 $DIR/f212.xyz
21004 }
21005 run_test 212 "Sendfile test ============================================"
21006
21007 test_213() {
21008         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
21009         cancel_lru_locks osc
21010         lctl set_param fail_loc=0x8000040f
21011         # generate a read lock
21012         cat $DIR/$tfile > /dev/null
21013         # write to the file, it will try to cancel the above read lock.
21014         cat /etc/hosts >> $DIR/$tfile
21015 }
21016 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
21017
21018 test_214() { # for bug 20133
21019         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
21020         for (( i=0; i < 340; i++ )) ; do
21021                 touch $DIR/$tdir/d214c/a$i
21022         done
21023
21024         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
21025         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
21026         ls $DIR/d214c || error "ls $DIR/d214c failed"
21027         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
21028         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
21029 }
21030 run_test 214 "hash-indexed directory test - bug 20133"
21031
21032 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
21033 create_lnet_proc_files() {
21034         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
21035 }
21036
21037 # counterpart of create_lnet_proc_files
21038 remove_lnet_proc_files() {
21039         rm -f $TMP/lnet_$1.sys
21040 }
21041
21042 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21043 # 3rd arg as regexp for body
21044 check_lnet_proc_stats() {
21045         local l=$(cat "$TMP/lnet_$1" |wc -l)
21046         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
21047
21048         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
21049 }
21050
21051 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
21052 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
21053 # optional and can be regexp for 2nd line (lnet.routes case)
21054 check_lnet_proc_entry() {
21055         local blp=2          # blp stands for 'position of 1st line of body'
21056         [ -z "$5" ] || blp=3 # lnet.routes case
21057
21058         local l=$(cat "$TMP/lnet_$1" |wc -l)
21059         # subtracting one from $blp because the body can be empty
21060         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
21061
21062         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
21063                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
21064
21065         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
21066                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
21067
21068         # bail out if any unexpected line happened
21069         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
21070         [ "$?" != 0 ] || error "$2 misformatted"
21071 }
21072
21073 test_215() { # for bugs 18102, 21079, 21517
21074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21075
21076         local N='(0|[1-9][0-9]*)'       # non-negative numeric
21077         local P='[1-9][0-9]*'           # positive numeric
21078         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
21079         local NET='[a-z][a-z0-9]*'      # LNet net like o2ib2
21080         local ADDR='[0-9.]+'            # LNet addr like 10.0.0.1
21081         local ADDR6='([0-9a-f]{0,4}:){2,7}[0-9a-f]{0,4}' # IPv6 LNet addr
21082         local NID="$ADDR@$NET"          # LNet nid like 10.0.0.1@o2ib2
21083         local NID6="$ADDR6@$NET"        # LNet nid like 2601:8c1:c180::cbdd@tcp
21084
21085         local L1 # regexp for 1st line
21086         local L2 # regexp for 2nd line (optional)
21087         local BR # regexp for the rest (body)
21088
21089         # lnet.stats should look as 11 space-separated non-negative numerics
21090         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
21091         create_lnet_proc_files "stats"
21092         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
21093         remove_lnet_proc_files "stats"
21094
21095         # lnet.routes should look like this:
21096         # Routing disabled/enabled
21097         # net hops priority state router
21098         # where net is a string like tcp0, hops > 0, priority >= 0,
21099         # state is up/down,
21100         # router is a string like 192.168.1.1@tcp2
21101         L1="^Routing (disabled|enabled)$"
21102         L2="^net +hops +priority +state +router$"
21103         BR="^$NET +$N +(0|1) +(up|down) +($NID|$NID6)$"
21104         create_lnet_proc_files "routes"
21105         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
21106         remove_lnet_proc_files "routes"
21107
21108         # lnet.routers should look like this:
21109         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
21110         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
21111         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
21112         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
21113         L1="^ref +rtr_ref +alive +router$"
21114         BR="^$P +$P +(up|down) +($NID|$NID6)$"
21115         create_lnet_proc_files "routers"
21116         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
21117         remove_lnet_proc_files "routers"
21118
21119         # lnet.peers should look like this:
21120         # nid refs state last max rtr min tx min queue
21121         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
21122         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
21123         # numeric (0 or >0 or <0), queue >= 0.
21124         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
21125         BR="^($NID|$NID6) +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
21126         create_lnet_proc_files "peers"
21127         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
21128         remove_lnet_proc_files "peers"
21129
21130         # lnet.buffers  should look like this:
21131         # pages count credits min
21132         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
21133         L1="^pages +count +credits +min$"
21134         BR="^ +$N +$N +$I +$I$"
21135         create_lnet_proc_files "buffers"
21136         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
21137         remove_lnet_proc_files "buffers"
21138
21139         # lnet.nis should look like this:
21140         # nid status alive refs peer rtr max tx min
21141         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
21142         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
21143         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
21144         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
21145         BR="^($NID|$NID6) +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
21146         create_lnet_proc_files "nis"
21147         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
21148         remove_lnet_proc_files "nis"
21149
21150         # can we successfully write to lnet.stats?
21151         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
21152 }
21153 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
21154
21155 test_216() { # bug 20317
21156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21157         remote_ost_nodsh && skip "remote OST with nodsh"
21158
21159         local node
21160         local facets=$(get_facets OST)
21161         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21162
21163         save_lustre_params client "osc.*.contention_seconds" > $p
21164         save_lustre_params $facets \
21165                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
21166         save_lustre_params $facets \
21167                 "ldlm.namespaces.filter-*.contended_locks" >> $p
21168         save_lustre_params $facets \
21169                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
21170         clear_stats osc.*.osc_stats
21171
21172         # agressive lockless i/o settings
21173         do_nodes $(comma_list $(osts_nodes)) \
21174                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
21175                         ldlm.namespaces.filter-*.contended_locks=0 \
21176                         ldlm.namespaces.filter-*.contention_seconds=60"
21177         lctl set_param -n osc.*.contention_seconds=60
21178
21179         $DIRECTIO write $DIR/$tfile 0 10 4096
21180         $CHECKSTAT -s 40960 $DIR/$tfile
21181
21182         # disable lockless i/o
21183         do_nodes $(comma_list $(osts_nodes)) \
21184                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
21185                         ldlm.namespaces.filter-*.contended_locks=32 \
21186                         ldlm.namespaces.filter-*.contention_seconds=0"
21187         lctl set_param -n osc.*.contention_seconds=0
21188         clear_stats osc.*.osc_stats
21189
21190         dd if=/dev/zero of=$DIR/$tfile count=0
21191         $CHECKSTAT -s 0 $DIR/$tfile
21192
21193         restore_lustre_params <$p
21194         rm -f $p
21195         rm $DIR/$tfile
21196 }
21197 run_test 216 "check lockless direct write updates file size and kms correctly"
21198
21199 test_217() { # bug 22430
21200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21201
21202         local node
21203
21204         for node in $(nodes_list); do
21205                 local nid=$(host_nids_address $node $NETTYPE)
21206                 local node_ip=$(do_node $node getent ahostsv4 $node |
21207                                 awk '{ print $1; exit; }')
21208
21209                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
21210                 # if hostname matches any NID, use hostname for better testing
21211                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
21212                         echo "lctl ping node $node@$NETTYPE"
21213                         lctl ping $node@$NETTYPE ||
21214                                 error "ping $node@$NETTYPE failed rc=$?"
21215                 else # otherwise, at least test 'lctl ping' is working
21216                         echo "lctl ping nid $(h2nettype $nid)"
21217                         lctl ping $(h2nettype $nid) ||
21218                                 error "ping $(h2nettype $nid) failed rc=$?"
21219                         echo "skipping $node (no hyphen detected)"
21220                 fi
21221         done
21222
21223         return 0
21224 }
21225 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
21226
21227 test_218() {
21228         # do directio so as not to populate the page cache
21229         log "creating a 10 Mb file"
21230         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
21231                 error "multiop failed while creating a file"
21232         log "starting reads"
21233         dd if=$DIR/$tfile of=/dev/null bs=4096 &
21234         log "truncating the file"
21235         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
21236                 error "multiop failed while truncating the file"
21237         log "killing dd"
21238         kill %+ || true # reads might have finished
21239         echo "wait until dd is finished"
21240         wait
21241         log "removing the temporary file"
21242         rm -rf $DIR/$tfile || error "tmp file removal failed"
21243 }
21244 run_test 218 "parallel read and truncate should not deadlock"
21245
21246 test_219() {
21247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21248
21249         # write one partial page
21250         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
21251         # set no grant so vvp_io_commit_write will do sync write
21252         $LCTL set_param fail_loc=0x411
21253         # write a full page at the end of file
21254         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
21255
21256         $LCTL set_param fail_loc=0
21257         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
21258         $LCTL set_param fail_loc=0x411
21259         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
21260
21261         # LU-4201
21262         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
21263         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
21264 }
21265 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
21266
21267 test_220() { #LU-325
21268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21269         remote_ost_nodsh && skip "remote OST with nodsh"
21270         remote_mds_nodsh && skip "remote MDS with nodsh"
21271         remote_mgs_nodsh && skip "remote MGS with nodsh"
21272
21273         local OSTIDX=0
21274
21275         # create on MDT0000 so the last_id and next_id are correct
21276         mkdir_on_mdt0 $DIR/$tdir
21277         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
21278         OST=${OST%_UUID}
21279
21280         # on the mdt's osc
21281         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
21282         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
21283                         osp.$mdtosc_proc1.prealloc_last_id)
21284         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
21285                         osp.$mdtosc_proc1.prealloc_next_id)
21286
21287         $LFS df -i
21288
21289         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
21290         #define OBD_FAIL_OST_ENOINO              0x229
21291         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
21292         create_pool $FSNAME.$TESTNAME || return 1
21293         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
21294
21295         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
21296
21297         MDSOBJS=$((last_id - next_id))
21298         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
21299
21300         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
21301         echo "OST still has $count kbytes free"
21302
21303         echo "create $MDSOBJS files @next_id..."
21304         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
21305
21306         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21307                         osp.$mdtosc_proc1.prealloc_last_id)
21308         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
21309                         osp.$mdtosc_proc1.prealloc_next_id)
21310
21311         echo "after creation, last_id=$last_id2, next_id=$next_id2"
21312         $LFS df -i
21313
21314         echo "cleanup..."
21315
21316         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
21317         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
21318
21319         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
21320                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
21321         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
21322                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
21323         echo "unlink $MDSOBJS files @$next_id..."
21324         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
21325 }
21326 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
21327
21328 test_221() {
21329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21330
21331         dd if=`which date` of=$MOUNT/date oflag=sync
21332         chmod +x $MOUNT/date
21333
21334         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
21335         $LCTL set_param fail_loc=0x80001401
21336
21337         $MOUNT/date > /dev/null
21338         rm -f $MOUNT/date
21339 }
21340 run_test 221 "make sure fault and truncate race to not cause OOM"
21341
21342 test_222a () {
21343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21344
21345         rm -rf $DIR/$tdir
21346         test_mkdir $DIR/$tdir
21347         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21348         createmany -o $DIR/$tdir/$tfile 10
21349         cancel_lru_locks mdc
21350         cancel_lru_locks osc
21351         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21352         $LCTL set_param fail_loc=0x31a
21353         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
21354         $LCTL set_param fail_loc=0
21355         rm -r $DIR/$tdir
21356 }
21357 run_test 222a "AGL for ls should not trigger CLIO lock failure"
21358
21359 test_222b () {
21360         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21361
21362         rm -rf $DIR/$tdir
21363         test_mkdir $DIR/$tdir
21364         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21365         createmany -o $DIR/$tdir/$tfile 10
21366         cancel_lru_locks mdc
21367         cancel_lru_locks osc
21368         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
21369         $LCTL set_param fail_loc=0x31a
21370         rm -r $DIR/$tdir || error "AGL for rmdir failed"
21371         $LCTL set_param fail_loc=0
21372 }
21373 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
21374
21375 test_223 () {
21376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21377
21378         rm -rf $DIR/$tdir
21379         test_mkdir $DIR/$tdir
21380         $LFS setstripe -c 1 -i 0 $DIR/$tdir
21381         createmany -o $DIR/$tdir/$tfile 10
21382         cancel_lru_locks mdc
21383         cancel_lru_locks osc
21384         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
21385         $LCTL set_param fail_loc=0x31b
21386         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
21387         $LCTL set_param fail_loc=0
21388         rm -r $DIR/$tdir
21389 }
21390 run_test 223 "osc reenqueue if without AGL lock granted ======================="
21391
21392 test_224a() { # LU-1039, MRP-303
21393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21394         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
21395         $LCTL set_param fail_loc=0x508
21396         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
21397         $LCTL set_param fail_loc=0
21398         df $DIR
21399 }
21400 run_test 224a "Don't panic on bulk IO failure"
21401
21402 test_224bd_sub() { # LU-1039, MRP-303
21403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21404         local timeout=$1
21405
21406         shift
21407         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
21408
21409         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21410
21411         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
21412         cancel_lru_locks osc
21413         set_checksums 0
21414         stack_trap "set_checksums $ORIG_CSUM" EXIT
21415         local at_max_saved=0
21416
21417         # adaptive timeouts may prevent seeing the issue
21418         if at_is_enabled; then
21419                 at_max_saved=$(at_max_get mds)
21420                 at_max_set 0 mds client
21421                 stack_trap "at_max_set $at_max_saved mds client" EXIT
21422         fi
21423
21424         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
21425         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
21426         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
21427
21428         do_facet ost1 $LCTL set_param fail_loc=0
21429         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
21430         df $DIR
21431 }
21432
21433 test_224b() {
21434         test_224bd_sub 3 error "dd failed"
21435 }
21436 run_test 224b "Don't panic on bulk IO failure"
21437
21438 test_224c() { # LU-6441
21439         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21440         remote_mds_nodsh && skip "remote MDS with nodsh"
21441
21442         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
21443         save_writethrough $p
21444         set_cache writethrough on
21445
21446         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
21447         local at_max=$($LCTL get_param -n at_max)
21448         local timeout=$($LCTL get_param -n timeout)
21449         local test_at="at_max"
21450         local param_at="$FSNAME.sys.at_max"
21451         local test_timeout="timeout"
21452         local param_timeout="$FSNAME.sys.timeout"
21453
21454         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
21455
21456         set_persistent_param_and_check client "$test_at" "$param_at" 0
21457         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
21458
21459         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
21460         do_facet ost1 "$LCTL set_param fail_loc=0x520"
21461         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21462         stack_trap "rm -f $DIR/$tfile"
21463         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
21464         sync
21465         do_facet ost1 "$LCTL set_param fail_loc=0"
21466
21467         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
21468         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
21469                 $timeout
21470
21471         $LCTL set_param -n $pages_per_rpc
21472         restore_lustre_params < $p
21473         rm -f $p
21474 }
21475 run_test 224c "Don't hang if one of md lost during large bulk RPC"
21476
21477 test_224d() { # LU-11169
21478         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
21479 }
21480 run_test 224d "Don't corrupt data on bulk IO timeout"
21481
21482 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
21483 test_225a () {
21484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21485         if [ -z ${MDSSURVEY} ]; then
21486                 skip_env "mds-survey not found"
21487         fi
21488         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21489                 skip "Need MDS version at least 2.2.51"
21490
21491         local mds=$(facet_host $SINGLEMDS)
21492         local target=$(do_nodes $mds 'lctl dl' |
21493                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21494
21495         local cmd1="file_count=1000 thrhi=4"
21496         local cmd2="dir_count=2 layer=mdd stripe_count=0"
21497         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21498         local cmd="$cmd1 $cmd2 $cmd3"
21499
21500         rm -f ${TMP}/mds_survey*
21501         echo + $cmd
21502         eval $cmd || error "mds-survey with zero-stripe failed"
21503         cat ${TMP}/mds_survey*
21504         rm -f ${TMP}/mds_survey*
21505 }
21506 run_test 225a "Metadata survey sanity with zero-stripe"
21507
21508 test_225b () {
21509         if [ -z ${MDSSURVEY} ]; then
21510                 skip_env "mds-survey not found"
21511         fi
21512         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
21513                 skip "Need MDS version at least 2.2.51"
21514         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21515         remote_mds_nodsh && skip "remote MDS with nodsh"
21516         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
21517                 skip_env "Need to mount OST to test"
21518         fi
21519
21520         local mds=$(facet_host $SINGLEMDS)
21521         local target=$(do_nodes $mds 'lctl dl' |
21522                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
21523
21524         local cmd1="file_count=1000 thrhi=4"
21525         local cmd2="dir_count=2 layer=mdd stripe_count=1"
21526         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
21527         local cmd="$cmd1 $cmd2 $cmd3"
21528
21529         rm -f ${TMP}/mds_survey*
21530         echo + $cmd
21531         eval $cmd || error "mds-survey with stripe_count failed"
21532         cat ${TMP}/mds_survey*
21533         rm -f ${TMP}/mds_survey*
21534 }
21535 run_test 225b "Metadata survey sanity with stripe_count = 1"
21536
21537 mcreate_path2fid () {
21538         local mode=$1
21539         local major=$2
21540         local minor=$3
21541         local name=$4
21542         local desc=$5
21543         local path=$DIR/$tdir/$name
21544         local fid
21545         local rc
21546         local fid_path
21547
21548         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
21549                 error "cannot create $desc"
21550
21551         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
21552         rc=$?
21553         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
21554
21555         fid_path=$($LFS fid2path $MOUNT $fid)
21556         rc=$?
21557         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
21558
21559         [ "$path" == "$fid_path" ] ||
21560                 error "fid2path returned $fid_path, expected $path"
21561
21562         echo "pass with $path and $fid"
21563 }
21564
21565 test_226a () {
21566         rm -rf $DIR/$tdir
21567         mkdir -p $DIR/$tdir
21568
21569         mcreate_path2fid 0010666 0 0 fifo "FIFO"
21570         mcreate_path2fid 0020666 1 3 null "character special file (null)"
21571         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
21572         mcreate_path2fid 0040666 0 0 dir "directory"
21573         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
21574         mcreate_path2fid 0100666 0 0 file "regular file"
21575         mcreate_path2fid 0120666 0 0 link "symbolic link"
21576         mcreate_path2fid 0140666 0 0 sock "socket"
21577 }
21578 run_test 226a "call path2fid and fid2path on files of all type"
21579
21580 test_226b () {
21581         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21582
21583         local MDTIDX=1
21584
21585         rm -rf $DIR/$tdir
21586         mkdir -p $DIR/$tdir
21587         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
21588                 error "create remote directory failed"
21589         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
21590         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
21591                                 "character special file (null)"
21592         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
21593                                 "character special file (no device)"
21594         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
21595         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
21596                                 "block special file (loop)"
21597         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
21598         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
21599         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
21600 }
21601 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
21602
21603 test_226c () {
21604         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21605         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
21606                 skip "Need MDS version at least 2.13.55"
21607
21608         local submnt=/mnt/submnt
21609         local srcfile=/etc/passwd
21610         local dstfile=$submnt/passwd
21611         local path
21612         local fid
21613
21614         rm -rf $DIR/$tdir
21615         rm -rf $submnt
21616         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
21617                 error "create remote directory failed"
21618         mkdir -p $submnt || error "create $submnt failed"
21619         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
21620                 error "mount $submnt failed"
21621         stack_trap "umount $submnt" EXIT
21622
21623         cp $srcfile $dstfile
21624         fid=$($LFS path2fid $dstfile)
21625         path=$($LFS fid2path $submnt "$fid")
21626         [ "$path" = "$dstfile" ] ||
21627                 error "fid2path $submnt $fid failed ($path != $dstfile)"
21628 }
21629 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
21630
21631 test_226d () {
21632         (( $CLIENT_VERSION >= $(version_code 2.15.57) )) ||
21633                 skip "Need client at least version 2.15.57"
21634
21635         # Define First test dataset
21636         local testdirs_01=$DIR/$tdir
21637         local testdata_01=$testdirs_01/${tdir}_01
21638         local testresult_01=${tdir}_01
21639         # Define Second test dataset
21640         local testdirs_02=$DIR/$tdir/$tdir
21641         local testdata_02=$testdirs_02/${tdir}_02
21642         local testresult_02=${tdir}_02
21643         # Define third test dataset (top level)
21644         local testdata_03=$DIR/${tdir}_03
21645         local testresult_03=${tdir}_03
21646
21647         # Create first test dataset
21648         mkdir -p $testdirs_01 || error "cannot create dir $testdirs_01"
21649         touch $testdata_01 || error "cannot create file $testdata_01"
21650
21651         # Create second test dataset
21652         mkdir -p $testdirs_02 || error "cannot create dir $testdirs_02"
21653         touch $testdata_02 || error "cannot create file $testdata_02"
21654
21655         # Create third test dataset
21656         touch $testdata_03 || error "cannot create file $testdata_03"
21657
21658         local fid01=$($LFS getstripe -F "$testdata_01") ||
21659                 error "getstripe failed on $testdata_01"
21660         local fid02=$($LFS getstripe -F "$testdata_02") ||
21661                 error "getstripe failed on $testdata_01"
21662         local fid03=$($LFS getstripe -F "$testdata_03") ||
21663                 error "getstripe failed on $testdata_03"
21664
21665         # Verify only -n option
21666         local out1=$($LFS fid2path -n $DIR $fid01) ||
21667                 error "fid2path failed on $fid01"
21668         local out2=$($LFS fid2path -n $DIR $fid02) ||
21669                 error "fid2path failed on $fid02"
21670         local out3=$($LFS fid2path -n $DIR $fid03) ||
21671                 error "fid2path failed on $fid03"
21672
21673         [[ "$out1" == "$testresult_01" ]] ||
21674                 error "fid2path failed: Expected $testresult_01 got $out1"
21675         [[ "$out2" == "$testresult_02" ]] ||
21676                 error "fid2path failed: Expected $testresult_02 got $out2"
21677         [[ "$out3" == "$testresult_03" ]] ||
21678                 error "fid2path failed: Expected $testresult_03 got $out3"
21679
21680         # Verify with option -fn together
21681         out1=$($LFS fid2path -fn $DIR $fid01) ||
21682                 error "fid2path -fn failed on $fid01"
21683         out2=$($LFS fid2path -fn $DIR $fid02) ||
21684                 error "fid2path -fn failed on $fid02"
21685         out3=$($LFS fid2path -fn $DIR $fid03) ||
21686                 error "fid2path -fn failed on $fid03"
21687
21688         local tmpout=$(echo $out1 | cut -d" " -f2)
21689         [[ "$tmpout" == "$testresult_01" ]] ||
21690                 error "fid2path -fn failed: Expected $testresult_01 got $out1"
21691
21692         tmpout=$(echo $out2 | cut -d" " -f2)
21693         [[ "$tmpout" == "$testresult_02" ]] ||
21694                 error "fid2path -fn failed: Expected $testresult_02 got $out2"
21695
21696         tmpout=$(echo $out3 | cut -d" " -f2)
21697         [[ "$tmpout" == "$testresult_03" ]] ||
21698                 error "fid2path -fn failed: Expected $testresult_03 got $out3"
21699 }
21700 run_test 226d "verify fid2path with -n and -fn option"
21701
21702 test_226e () {
21703         (( $CLIENT_VERSION >= $(version_code 2.15.56) )) ||
21704                 skip "Need client at least version 2.15.56"
21705
21706         # Define filename with 'newline' and a space
21707         local testfile="Test"$'\n'"file 01"
21708         # Define link name with multiple 'newline' and a space
21709         local linkfile="Link"$'\n'"file "$'\n'"01"
21710         # Remove prior hard link
21711         rm -f $DIR/"$linkfile"
21712
21713         # Create file
21714         touch $DIR/"$testfile"
21715         # Create link
21716         ln $DIR/"$testfile" $DIR/"$linkfile"
21717
21718         local fid=$($LFS getstripe -F "$DIR/$testfile") ||
21719                 error "getstripe failed on $DIR/$testfile"
21720
21721         # Call with -0 option
21722         local out1=$($LFS fid2path -0 $DIR $fid | xargs --null -n1 \
21723                 echo "FILE:" | grep -c "FILE:")
21724
21725         # With -0 option the output should be exactly 2 lines.
21726         (( $out1 == 2 )) || error "fid2path -0 failed on $fid, $out1"
21727 }
21728 run_test 226e "Verify path2fid -0 option with newline and space"
21729
21730 # LU-1299 Executing or running ldd on a truncated executable does not
21731 # cause an out-of-memory condition.
21732 test_227() {
21733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21734         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
21735
21736         dd if=$(which date) of=$MOUNT/date bs=1k count=1
21737         chmod +x $MOUNT/date
21738
21739         $MOUNT/date > /dev/null
21740         ldd $MOUNT/date > /dev/null
21741         rm -f $MOUNT/date
21742 }
21743 run_test 227 "running truncated executable does not cause OOM"
21744
21745 # LU-1512 try to reuse idle OI blocks
21746 test_228a() {
21747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21748         remote_mds_nodsh && skip "remote MDS with nodsh"
21749         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21750
21751         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21752         local myDIR=$DIR/$tdir
21753
21754         mkdir -p $myDIR
21755         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21756         $LCTL set_param fail_loc=0x80001002
21757         createmany -o $myDIR/t- 10000
21758         $LCTL set_param fail_loc=0
21759         # The guard is current the largest FID holder
21760         touch $myDIR/guard
21761         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21762                     tr -d '[')
21763         local IDX=$(($SEQ % 64))
21764
21765         do_facet $SINGLEMDS sync
21766         # Make sure journal flushed.
21767         sleep 6
21768         local blk1=$(do_facet $SINGLEMDS \
21769                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21770                      grep Blockcount | awk '{print $4}')
21771
21772         # Remove old files, some OI blocks will become idle.
21773         unlinkmany $myDIR/t- 10000
21774         # Create new files, idle OI blocks should be reused.
21775         createmany -o $myDIR/t- 2000
21776         do_facet $SINGLEMDS sync
21777         # Make sure journal flushed.
21778         sleep 6
21779         local blk2=$(do_facet $SINGLEMDS \
21780                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21781                      grep Blockcount | awk '{print $4}')
21782
21783         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21784 }
21785 run_test 228a "try to reuse idle OI blocks"
21786
21787 test_228b() {
21788         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21789         remote_mds_nodsh && skip "remote MDS with nodsh"
21790         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21791
21792         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21793         local myDIR=$DIR/$tdir
21794
21795         mkdir -p $myDIR
21796         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21797         $LCTL set_param fail_loc=0x80001002
21798         createmany -o $myDIR/t- 10000
21799         $LCTL set_param fail_loc=0
21800         # The guard is current the largest FID holder
21801         touch $myDIR/guard
21802         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21803                     tr -d '[')
21804         local IDX=$(($SEQ % 64))
21805
21806         do_facet $SINGLEMDS sync
21807         # Make sure journal flushed.
21808         sleep 6
21809         local blk1=$(do_facet $SINGLEMDS \
21810                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21811                      grep Blockcount | awk '{print $4}')
21812
21813         # Remove old files, some OI blocks will become idle.
21814         unlinkmany $myDIR/t- 10000
21815
21816         # stop the MDT
21817         stop $SINGLEMDS || error "Fail to stop MDT."
21818         # remount the MDT
21819         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
21820                 error "Fail to start MDT."
21821
21822         client_up || error "Fail to df."
21823         # Create new files, idle OI blocks should be reused.
21824         createmany -o $myDIR/t- 2000
21825         do_facet $SINGLEMDS sync
21826         # Make sure journal flushed.
21827         sleep 6
21828         local blk2=$(do_facet $SINGLEMDS \
21829                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21830                      grep Blockcount | awk '{print $4}')
21831
21832         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21833 }
21834 run_test 228b "idle OI blocks can be reused after MDT restart"
21835
21836 #LU-1881
21837 test_228c() {
21838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21839         remote_mds_nodsh && skip "remote MDS with nodsh"
21840         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21841
21842         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
21843         local myDIR=$DIR/$tdir
21844
21845         mkdir -p $myDIR
21846         #define OBD_FAIL_SEQ_EXHAUST             0x1002
21847         $LCTL set_param fail_loc=0x80001002
21848         # 20000 files can guarantee there are index nodes in the OI file
21849         createmany -o $myDIR/t- 20000
21850         $LCTL set_param fail_loc=0
21851         # The guard is current the largest FID holder
21852         touch $myDIR/guard
21853         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
21854                     tr -d '[')
21855         local IDX=$(($SEQ % 64))
21856
21857         do_facet $SINGLEMDS sync
21858         # Make sure journal flushed.
21859         sleep 6
21860         local blk1=$(do_facet $SINGLEMDS \
21861                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21862                      grep Blockcount | awk '{print $4}')
21863
21864         # Remove old files, some OI blocks will become idle.
21865         unlinkmany $myDIR/t- 20000
21866         rm -f $myDIR/guard
21867         # The OI file should become empty now
21868
21869         # Create new files, idle OI blocks should be reused.
21870         createmany -o $myDIR/t- 2000
21871         do_facet $SINGLEMDS sync
21872         # Make sure journal flushed.
21873         sleep 6
21874         local blk2=$(do_facet $SINGLEMDS \
21875                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
21876                      grep Blockcount | awk '{print $4}')
21877
21878         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
21879 }
21880 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
21881
21882 test_229() { # LU-2482, LU-3448
21883         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21884         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
21885         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
21886                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
21887
21888         rm -f $DIR/$tfile
21889
21890         # Create a file with a released layout and stripe count 2.
21891         $MULTIOP $DIR/$tfile H2c ||
21892                 error "failed to create file with released layout"
21893
21894         $LFS getstripe -v $DIR/$tfile
21895
21896         local pattern=$($LFS getstripe -L $DIR/$tfile)
21897         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
21898
21899         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
21900                 error "getstripe"
21901         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
21902         stat $DIR/$tfile || error "failed to stat released file"
21903
21904         chown $RUNAS_ID $DIR/$tfile ||
21905                 error "chown $RUNAS_ID $DIR/$tfile failed"
21906
21907         chgrp $RUNAS_ID $DIR/$tfile ||
21908                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
21909
21910         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
21911         rm $DIR/$tfile || error "failed to remove released file"
21912 }
21913 run_test 229 "getstripe/stat/rm/attr changes work on released files"
21914
21915 test_230a() {
21916         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21918         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21919                 skip "Need MDS version at least 2.11.52"
21920
21921         local MDTIDX=1
21922
21923         test_mkdir $DIR/$tdir
21924         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
21925         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
21926         [ $mdt_idx -ne 0 ] &&
21927                 error "create local directory on wrong MDT $mdt_idx"
21928
21929         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
21930                         error "create remote directory failed"
21931         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
21932         [ $mdt_idx -ne $MDTIDX ] &&
21933                 error "create remote directory on wrong MDT $mdt_idx"
21934
21935         createmany -o $DIR/$tdir/test_230/t- 10 ||
21936                 error "create files on remote directory failed"
21937         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
21938         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
21939         rm -r $DIR/$tdir || error "unlink remote directory failed"
21940 }
21941 run_test 230a "Create remote directory and files under the remote directory"
21942
21943 test_230b() {
21944         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21945         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21946         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21947                 skip "Need MDS version at least 2.11.52"
21948
21949         local MDTIDX=1
21950         local mdt_index
21951         local i
21952         local file
21953         local pid
21954         local stripe_count
21955         local migrate_dir=$DIR/$tdir/migrate_dir
21956         local other_dir=$DIR/$tdir/other_dir
21957
21958         test_mkdir $DIR/$tdir
21959         test_mkdir -i0 -c1 $migrate_dir
21960         test_mkdir -i0 -c1 $other_dir
21961         for ((i=0; i<10; i++)); do
21962                 mkdir -p $migrate_dir/dir_${i}
21963                 createmany -o $migrate_dir/dir_${i}/f 10 ||
21964                         error "create files under remote dir failed $i"
21965         done
21966
21967         cp /etc/passwd $migrate_dir/$tfile
21968         cp /etc/passwd $other_dir/$tfile
21969         chattr +SAD $migrate_dir
21970         chattr +SAD $migrate_dir/$tfile
21971
21972         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
21973         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
21974         local old_dir_mode=$(stat -c%f $migrate_dir)
21975         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
21976
21977         mkdir -p $migrate_dir/dir_default_stripe2
21978         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
21979         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
21980
21981         mkdir -p $other_dir
21982         ln $migrate_dir/$tfile $other_dir/luna
21983         ln $migrate_dir/$tfile $migrate_dir/sofia
21984         ln $other_dir/$tfile $migrate_dir/david
21985         ln -s $migrate_dir/$tfile $other_dir/zachary
21986         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
21987         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
21988
21989         local len
21990         local lnktgt
21991
21992         # inline symlink
21993         for len in 58 59 60; do
21994                 lnktgt=$(str_repeat 'l' $len)
21995                 touch $migrate_dir/$lnktgt
21996                 ln -s $lnktgt $migrate_dir/${len}char_ln
21997         done
21998
21999         # PATH_MAX
22000         for len in 4094 4095; do
22001                 lnktgt=$(str_repeat 'l' $len)
22002                 ln -s $lnktgt $migrate_dir/${len}char_ln
22003         done
22004
22005         # NAME_MAX
22006         for len in 254 255; do
22007                 touch $migrate_dir/$(str_repeat 'l' $len)
22008         done
22009
22010         $LFS migrate -m $MDTIDX $migrate_dir ||
22011                 error "fails on migrating remote dir to MDT1"
22012
22013         echo "migratate to MDT1, then checking.."
22014         for ((i = 0; i < 10; i++)); do
22015                 for file in $(find $migrate_dir/dir_${i}); do
22016                         mdt_index=$($LFS getstripe -m $file)
22017                         # broken symlink getstripe will fail
22018                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22019                                 error "$file is not on MDT${MDTIDX}"
22020                 done
22021         done
22022
22023         # the multiple link file should still in MDT0
22024         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
22025         [ $mdt_index == 0 ] ||
22026                 error "$file is not on MDT${MDTIDX}"
22027
22028         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22029         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22030                 error " expect $old_dir_flag get $new_dir_flag"
22031
22032         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22033         [ "$old_file_flag" = "$new_file_flag" ] ||
22034                 error " expect $old_file_flag get $new_file_flag"
22035
22036         local new_dir_mode=$(stat -c%f $migrate_dir)
22037         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22038                 error "expect mode $old_dir_mode get $new_dir_mode"
22039
22040         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22041         [ "$old_file_mode" = "$new_file_mode" ] ||
22042                 error "expect mode $old_file_mode get $new_file_mode"
22043
22044         diff /etc/passwd $migrate_dir/$tfile ||
22045                 error "$tfile different after migration"
22046
22047         diff /etc/passwd $other_dir/luna ||
22048                 error "luna different after migration"
22049
22050         diff /etc/passwd $migrate_dir/sofia ||
22051                 error "sofia different after migration"
22052
22053         diff /etc/passwd $migrate_dir/david ||
22054                 error "david different after migration"
22055
22056         diff /etc/passwd $other_dir/zachary ||
22057                 error "zachary different after migration"
22058
22059         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22060                 error "${tfile}_ln different after migration"
22061
22062         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22063                 error "${tfile}_ln_other different after migration"
22064
22065         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
22066         [ $stripe_count = 2 ] ||
22067                 error "dir strpe_count $d != 2 after migration."
22068
22069         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
22070         [ $stripe_count = 2 ] ||
22071                 error "file strpe_count $d != 2 after migration."
22072
22073         #migrate back to MDT0
22074         MDTIDX=0
22075
22076         $LFS migrate -m $MDTIDX $migrate_dir ||
22077                 error "fails on migrating remote dir to MDT0"
22078
22079         echo "migrate back to MDT0, checking.."
22080         for file in $(find $migrate_dir); do
22081                 mdt_index=$($LFS getstripe -m $file)
22082                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
22083                         error "$file is not on MDT${MDTIDX}"
22084         done
22085
22086         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
22087         [ "$old_dir_flag" = "$new_dir_flag" ] ||
22088                 error " expect $old_dir_flag get $new_dir_flag"
22089
22090         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
22091         [ "$old_file_flag" = "$new_file_flag" ] ||
22092                 error " expect $old_file_flag get $new_file_flag"
22093
22094         local new_dir_mode=$(stat -c%f $migrate_dir)
22095         [ "$old_dir_mode" = "$new_dir_mode" ] ||
22096                 error "expect mode $old_dir_mode get $new_dir_mode"
22097
22098         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
22099         [ "$old_file_mode" = "$new_file_mode" ] ||
22100                 error "expect mode $old_file_mode get $new_file_mode"
22101
22102         diff /etc/passwd ${migrate_dir}/$tfile ||
22103                 error "$tfile different after migration"
22104
22105         diff /etc/passwd ${other_dir}/luna ||
22106                 error "luna different after migration"
22107
22108         diff /etc/passwd ${migrate_dir}/sofia ||
22109                 error "sofia different after migration"
22110
22111         diff /etc/passwd ${other_dir}/zachary ||
22112                 error "zachary different after migration"
22113
22114         diff /etc/passwd $migrate_dir/${tfile}_ln ||
22115                 error "${tfile}_ln different after migration"
22116
22117         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
22118                 error "${tfile}_ln_other different after migration"
22119
22120         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
22121         [ $stripe_count = 2 ] ||
22122                 error "dir strpe_count $d != 2 after migration."
22123
22124         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
22125         [ $stripe_count = 2 ] ||
22126                 error "file strpe_count $d != 2 after migration."
22127
22128         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22129 }
22130 run_test 230b "migrate directory"
22131
22132 test_230c() {
22133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22134         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22135         remote_mds_nodsh && skip "remote MDS with nodsh"
22136         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22137                 skip "Need MDS version at least 2.11.52"
22138
22139         local MDTIDX=1
22140         local total=3
22141         local mdt_index
22142         local file
22143         local migrate_dir=$DIR/$tdir/migrate_dir
22144
22145         #If migrating directory fails in the middle, all entries of
22146         #the directory is still accessiable.
22147         test_mkdir $DIR/$tdir
22148         test_mkdir -i0 -c1 $migrate_dir
22149         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
22150         stat $migrate_dir
22151         createmany -o $migrate_dir/f $total ||
22152                 error "create files under ${migrate_dir} failed"
22153
22154         # fail after migrating top dir, and this will fail only once, so the
22155         # first sub file migration will fail (currently f3), others succeed.
22156         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
22157         do_facet mds1 lctl set_param fail_loc=0x1801
22158         local t=$(ls $migrate_dir | wc -l)
22159         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
22160                 error "migrate should fail"
22161         local u=$(ls $migrate_dir | wc -l)
22162         [ "$u" == "$t" ] || error "$u != $t during migration"
22163
22164         # add new dir/file should succeed
22165         mkdir $migrate_dir/dir ||
22166                 error "mkdir failed under migrating directory"
22167         touch $migrate_dir/file ||
22168                 error "create file failed under migrating directory"
22169
22170         # add file with existing name should fail
22171         for file in $migrate_dir/f*; do
22172                 stat $file > /dev/null || error "stat $file failed"
22173                 $OPENFILE -f O_CREAT:O_EXCL $file &&
22174                         error "open(O_CREAT|O_EXCL) $file should fail"
22175                 $MULTIOP $file m && error "create $file should fail"
22176                 touch $DIR/$tdir/remote_dir/$tfile ||
22177                         error "touch $tfile failed"
22178                 ln $DIR/$tdir/remote_dir/$tfile $file &&
22179                         error "link $file should fail"
22180                 mdt_index=$($LFS getstripe -m $file)
22181                 if [ $mdt_index == 0 ]; then
22182                         # file failed to migrate is not allowed to rename to
22183                         mv $DIR/$tdir/remote_dir/$tfile $file &&
22184                                 error "rename to $file should fail"
22185                 else
22186                         mv $DIR/$tdir/remote_dir/$tfile $file ||
22187                                 error "rename to $file failed"
22188                 fi
22189                 echo hello >> $file || error "write $file failed"
22190         done
22191
22192         # resume migration with different options should fail
22193         $LFS migrate -m 0 $migrate_dir &&
22194                 error "migrate -m 0 $migrate_dir should fail"
22195
22196         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
22197                 error "migrate -c 2 $migrate_dir should fail"
22198
22199         # resume migration should succeed
22200         $LFS migrate -m $MDTIDX $migrate_dir ||
22201                 error "migrate $migrate_dir failed"
22202
22203         echo "Finish migration, then checking.."
22204         for file in $(find $migrate_dir); do
22205                 mdt_index=$($LFS getstripe -m $file)
22206                 [ $mdt_index == $MDTIDX ] ||
22207                         error "$file is not on MDT${MDTIDX}"
22208         done
22209
22210         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22211 }
22212 run_test 230c "check directory accessiblity if migration failed"
22213
22214 test_230d() {
22215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22216         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22217         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22218                 skip "Need MDS version at least 2.11.52"
22219         # LU-11235
22220         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
22221
22222         local migrate_dir=$DIR/$tdir/migrate_dir
22223         local old_index
22224         local new_index
22225         local old_count
22226         local new_count
22227         local new_hash
22228         local mdt_index
22229         local i
22230         local j
22231
22232         old_index=$((RANDOM % MDSCOUNT))
22233         old_count=$((MDSCOUNT - old_index))
22234         new_index=$((RANDOM % MDSCOUNT))
22235         new_count=$((MDSCOUNT - new_index))
22236         new_hash=1 # for all_char
22237
22238         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
22239         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
22240
22241         test_mkdir $DIR/$tdir
22242         test_mkdir -i $old_index -c $old_count $migrate_dir
22243
22244         for ((i=0; i<100; i++)); do
22245                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
22246                 createmany -o $migrate_dir/dir_${i}/f 100 ||
22247                         error "create files under remote dir failed $i"
22248         done
22249
22250         echo -n "Migrate from MDT$old_index "
22251         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
22252         echo -n "to MDT$new_index"
22253         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
22254         echo
22255
22256         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
22257         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
22258                 error "migrate remote dir error"
22259
22260         echo "Finish migration, then checking.."
22261         for file in $(find $migrate_dir -maxdepth 1); do
22262                 mdt_index=$($LFS getstripe -m $file)
22263                 if [ $mdt_index -lt $new_index ] ||
22264                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
22265                         error "$file is on MDT$mdt_index"
22266                 fi
22267         done
22268
22269         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22270 }
22271 run_test 230d "check migrate big directory"
22272
22273 test_230e() {
22274         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22275         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22276         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22277                 skip "Need MDS version at least 2.11.52"
22278
22279         local i
22280         local j
22281         local a_fid
22282         local b_fid
22283
22284         mkdir_on_mdt0 $DIR/$tdir
22285         mkdir $DIR/$tdir/migrate_dir
22286         mkdir $DIR/$tdir/other_dir
22287         touch $DIR/$tdir/migrate_dir/a
22288         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
22289         ls $DIR/$tdir/other_dir
22290
22291         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22292                 error "migrate dir fails"
22293
22294         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22295         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22296
22297         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22298         [ $mdt_index == 0 ] || error "a is not on MDT0"
22299
22300         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
22301                 error "migrate dir fails"
22302
22303         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
22304         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
22305
22306         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22307         [ $mdt_index == 1 ] || error "a is not on MDT1"
22308
22309         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
22310         [ $mdt_index == 1 ] || error "b is not on MDT1"
22311
22312         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22313         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
22314
22315         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
22316
22317         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22318 }
22319 run_test 230e "migrate mulitple local link files"
22320
22321 test_230f() {
22322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22323         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22324         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22325                 skip "Need MDS version at least 2.11.52"
22326
22327         local a_fid
22328         local ln_fid
22329
22330         mkdir -p $DIR/$tdir
22331         mkdir $DIR/$tdir/migrate_dir
22332         $LFS mkdir -i1 $DIR/$tdir/other_dir
22333         touch $DIR/$tdir/migrate_dir/a
22334         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
22335         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
22336         ls $DIR/$tdir/other_dir
22337
22338         # a should be migrated to MDT1, since no other links on MDT0
22339         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22340                 error "#1 migrate dir fails"
22341         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
22342         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
22343         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22344         [ $mdt_index == 1 ] || error "a is not on MDT1"
22345
22346         # a should stay on MDT1, because it is a mulitple link file
22347         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22348                 error "#2 migrate dir fails"
22349         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22350         [ $mdt_index == 1 ] || error "a is not on MDT1"
22351
22352         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
22353                 error "#3 migrate dir fails"
22354
22355         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
22356         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
22357         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
22358
22359         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
22360         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
22361
22362         # a should be migrated to MDT0, since no other links on MDT1
22363         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
22364                 error "#4 migrate dir fails"
22365         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
22366         [ $mdt_index == 0 ] || error "a is not on MDT0"
22367
22368         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22369 }
22370 run_test 230f "migrate mulitple remote link files"
22371
22372 test_230g() {
22373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22374         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22375         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22376                 skip "Need MDS version at least 2.11.52"
22377
22378         mkdir -p $DIR/$tdir/migrate_dir
22379
22380         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
22381                 error "migrating dir to non-exist MDT succeeds"
22382         true
22383 }
22384 run_test 230g "migrate dir to non-exist MDT"
22385
22386 test_230h() {
22387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22388         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22389         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22390                 skip "Need MDS version at least 2.11.52"
22391
22392         local mdt_index
22393
22394         mkdir -p $DIR/$tdir/migrate_dir
22395
22396         $LFS migrate -m1 $DIR &&
22397                 error "migrating mountpoint1 should fail"
22398
22399         $LFS migrate -m1 $DIR/$tdir/.. &&
22400                 error "migrating mountpoint2 should fail"
22401
22402         # same as mv
22403         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
22404                 error "migrating $tdir/migrate_dir/.. should fail"
22405
22406         true
22407 }
22408 run_test 230h "migrate .. and root"
22409
22410 test_230i() {
22411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22413         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
22414                 skip "Need MDS version at least 2.11.52"
22415
22416         mkdir -p $DIR/$tdir/migrate_dir
22417
22418         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
22419                 error "migration fails with a tailing slash"
22420
22421         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
22422                 error "migration fails with two tailing slashes"
22423 }
22424 run_test 230i "lfs migrate -m tolerates trailing slashes"
22425
22426 test_230j() {
22427         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22428         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
22429                 skip "Need MDS version at least 2.11.52"
22430
22431         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22432         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
22433                 error "create $tfile failed"
22434         cat /etc/passwd > $DIR/$tdir/$tfile
22435
22436         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22437
22438         cmp /etc/passwd $DIR/$tdir/$tfile ||
22439                 error "DoM file mismatch after migration"
22440 }
22441 run_test 230j "DoM file data not changed after dir migration"
22442
22443 test_230k() {
22444         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
22445         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22446                 skip "Need MDS version at least 2.11.56"
22447
22448         local total=20
22449         local files_on_starting_mdt=0
22450
22451         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
22452         $LFS getdirstripe $DIR/$tdir
22453         for i in $(seq $total); do
22454                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
22455                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22456                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22457         done
22458
22459         echo "$files_on_starting_mdt files on MDT0"
22460
22461         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
22462         $LFS getdirstripe $DIR/$tdir
22463
22464         files_on_starting_mdt=0
22465         for i in $(seq $total); do
22466                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22467                         error "file $tfile.$i mismatch after migration"
22468                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
22469                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22470         done
22471
22472         echo "$files_on_starting_mdt files on MDT1 after migration"
22473         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
22474
22475         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
22476         $LFS getdirstripe $DIR/$tdir
22477
22478         files_on_starting_mdt=0
22479         for i in $(seq $total); do
22480                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
22481                         error "file $tfile.$i mismatch after 2nd migration"
22482                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
22483                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
22484         done
22485
22486         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
22487         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
22488
22489         true
22490 }
22491 run_test 230k "file data not changed after dir migration"
22492
22493 test_230l() {
22494         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22495         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22496                 skip "Need MDS version at least 2.11.56"
22497
22498         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
22499         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
22500                 error "create files under remote dir failed $i"
22501         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
22502 }
22503 run_test 230l "readdir between MDTs won't crash"
22504
22505 test_230m() {
22506         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22507         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22508                 skip "Need MDS version at least 2.11.56"
22509
22510         local MDTIDX=1
22511         local mig_dir=$DIR/$tdir/migrate_dir
22512         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
22513         local shortstr="b"
22514         local val
22515
22516         echo "Creating files and dirs with xattrs"
22517         test_mkdir $DIR/$tdir
22518         test_mkdir -i0 -c1 $mig_dir
22519         mkdir $mig_dir/dir
22520         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
22521                 error "cannot set xattr attr1 on dir"
22522         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
22523                 error "cannot set xattr attr2 on dir"
22524         touch $mig_dir/dir/f0
22525         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
22526                 error "cannot set xattr attr1 on file"
22527         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
22528                 error "cannot set xattr attr2 on file"
22529         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22530         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22531         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
22532         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22533         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
22534         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22535         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
22536         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22537         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
22538
22539         echo "Migrating to MDT1"
22540         $LFS migrate -m $MDTIDX $mig_dir ||
22541                 error "fails on migrating dir to MDT1"
22542
22543         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
22544         echo "Checking xattrs"
22545         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
22546         [ "$val" = $longstr ] ||
22547                 error "expecting xattr1 $longstr on dir, found $val"
22548         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
22549         [ "$val" = $shortstr ] ||
22550                 error "expecting xattr2 $shortstr on dir, found $val"
22551         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
22552         [ "$val" = $longstr ] ||
22553                 error "expecting xattr1 $longstr on file, found $val"
22554         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
22555         [ "$val" = $shortstr ] ||
22556                 error "expecting xattr2 $shortstr on file, found $val"
22557 }
22558 run_test 230m "xattrs not changed after dir migration"
22559
22560 test_230n() {
22561         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
22562         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
22563                 skip "Need MDS version at least 2.13.53"
22564
22565         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
22566         cat /etc/hosts > $DIR/$tdir/$tfile
22567         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
22568         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
22569
22570         cmp /etc/hosts $DIR/$tdir/$tfile ||
22571                 error "File data mismatch after migration"
22572 }
22573 run_test 230n "Dir migration with mirrored file"
22574
22575 test_230o() {
22576         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
22577         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
22578                 skip "Need MDS version at least 2.13.52"
22579
22580         local mdts=$(comma_list $(mdts_nodes))
22581         local timeout=100
22582         local restripe_status
22583         local delta
22584         local i
22585
22586         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22587
22588         # in case "crush" hash type is not set
22589         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22590
22591         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22592                            mdt.*MDT0000.enable_dir_restripe)
22593         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22594         stack_trap "do_nodes $mdts $LCTL set_param \
22595                     mdt.*.enable_dir_restripe=$restripe_status"
22596
22597         mkdir $DIR/$tdir
22598         createmany -m $DIR/$tdir/f 100 ||
22599                 error "create files under remote dir failed $i"
22600         createmany -d $DIR/$tdir/d 100 ||
22601                 error "create dirs under remote dir failed $i"
22602
22603         for i in $(seq 2 $MDSCOUNT); do
22604                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22605                 $LFS setdirstripe -c $i $DIR/$tdir ||
22606                         error "split -c $i $tdir failed"
22607                 wait_update $HOSTNAME \
22608                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
22609                         error "dir split not finished"
22610                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22611                         awk '/migrate/ {sum += $2} END { print sum }')
22612                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
22613                 # delta is around total_files/stripe_count
22614                 (( $delta < 200 / (i - 1) + 4 )) ||
22615                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
22616         done
22617 }
22618 run_test 230o "dir split"
22619
22620 test_230p() {
22621         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22622         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22623                 skip "Need MDS version at least 2.13.52"
22624
22625         local mdts=$(comma_list $(mdts_nodes))
22626         local timeout=100
22627         local restripe_status
22628         local delta
22629         local c
22630
22631         [[ $mds1_FSTYPE == zfs ]] && timeout=300
22632
22633         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22634
22635         restripe_status=$(do_facet mds1 $LCTL get_param -n \
22636                            mdt.*MDT0000.enable_dir_restripe)
22637         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
22638         stack_trap "do_nodes $mdts $LCTL set_param \
22639                     mdt.*.enable_dir_restripe=$restripe_status"
22640
22641         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
22642         createmany -m $DIR/$tdir/f 100 ||
22643                 error "create files under remote dir failed"
22644         createmany -d $DIR/$tdir/d 100 ||
22645                 error "create dirs under remote dir failed"
22646
22647         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
22648                 local mdt_hash="crush"
22649
22650                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
22651                 $LFS setdirstripe -c $c $DIR/$tdir ||
22652                         error "split -c $c $tdir failed"
22653                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
22654                         mdt_hash="$mdt_hash,fixed"
22655                 elif [ $c -eq 1 ]; then
22656                         mdt_hash="none"
22657                 fi
22658                 wait_update $HOSTNAME \
22659                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
22660                         error "dir merge not finished"
22661                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
22662                         awk '/migrate/ {sum += $2} END { print sum }')
22663                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
22664                 # delta is around total_files/stripe_count
22665                 (( delta < 200 / c + 4 )) ||
22666                         error "$delta files migrated >= $((200 / c + 4))"
22667         done
22668 }
22669 run_test 230p "dir merge"
22670
22671 test_230q() {
22672         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
22673         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
22674                 skip "Need MDS version at least 2.13.52"
22675
22676         local mdts=$(comma_list $(mdts_nodes))
22677         local saved_threshold=$(do_facet mds1 \
22678                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
22679         local saved_delta=$(do_facet mds1 \
22680                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
22681         local threshold=100
22682         local delta=2
22683         local total=0
22684         local stripe_count=0
22685         local stripe_index
22686         local nr_files
22687         local create
22688
22689         # test with fewer files on ZFS
22690         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
22691
22692         stack_trap "do_nodes $mdts $LCTL set_param \
22693                     mdt.*.dir_split_count=$saved_threshold"
22694         stack_trap "do_nodes $mdts $LCTL set_param \
22695                     mdt.*.dir_split_delta=$saved_delta"
22696         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
22697         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
22698         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
22699         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
22700         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
22701         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
22702
22703         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
22704         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
22705
22706         create=$((threshold * 3 / 2))
22707         while [ $stripe_count -lt $MDSCOUNT ]; do
22708                 createmany -m $DIR/$tdir/f $total $create ||
22709                         error "create sub files failed"
22710                 stat $DIR/$tdir > /dev/null
22711                 total=$((total + create))
22712                 stripe_count=$((stripe_count + delta))
22713                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
22714
22715                 wait_update $HOSTNAME \
22716                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
22717                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
22718
22719                 wait_update $HOSTNAME \
22720                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
22721                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
22722
22723                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
22724                 echo "$nr_files/$total files on MDT$stripe_index after split"
22725                 # allow 10% margin of imbalance with crush hash
22726                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
22727                         error "$nr_files files on MDT$stripe_index after split"
22728
22729                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
22730                 [ $nr_files -eq $total ] ||
22731                         error "total sub files $nr_files != $total"
22732         done
22733
22734         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
22735
22736         echo "fixed layout directory won't auto split"
22737         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
22738         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
22739                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
22740         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
22741                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
22742 }
22743 run_test 230q "dir auto split"
22744
22745 test_230r() {
22746         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
22747         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
22748         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
22749                 skip "Need MDS version at least 2.13.54"
22750
22751         # maximum amount of local locks:
22752         # parent striped dir - 2 locks
22753         # new stripe in parent to migrate to - 1 lock
22754         # source and target - 2 locks
22755         # Total 5 locks for regular file
22756         mkdir -p $DIR/$tdir
22757         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
22758         touch $DIR/$tdir/dir1/eee
22759
22760         # create 4 hardlink for 4 more locks
22761         # Total: 9 locks > RS_MAX_LOCKS (8)
22762         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
22763         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
22764         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
22765         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
22766         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
22767         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
22768         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
22769         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
22770
22771         cancel_lru_locks mdc
22772
22773         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
22774                 error "migrate dir fails"
22775
22776         rm -rf $DIR/$tdir || error "rm dir failed after migration"
22777 }
22778 run_test 230r "migrate with too many local locks"
22779
22780 test_230s() {
22781         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
22782                 skip "Need MDS version at least 2.14.52"
22783
22784         local mdts=$(comma_list $(mdts_nodes))
22785         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
22786                                 mdt.*MDT0000.enable_dir_restripe)
22787
22788         stack_trap "do_nodes $mdts $LCTL set_param \
22789                     mdt.*.enable_dir_restripe=$restripe_status"
22790
22791         local st
22792         for st in 0 1; do
22793                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
22794                 test_mkdir $DIR/$tdir
22795                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
22796                         error "$LFS mkdir should return EEXIST if target exists"
22797                 rmdir $DIR/$tdir
22798         done
22799 }
22800 run_test 230s "lfs mkdir should return -EEXIST if target exists"
22801
22802 test_230t()
22803 {
22804         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
22805         (( $MDS1_VERSION >= $(version_code 2.14.50) )) ||
22806                 skip "Need MDS version at least 2.14.50"
22807
22808         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
22809         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
22810         $LFS project -p 1 -s $DIR/$tdir ||
22811                 error "set $tdir project id failed"
22812         $LFS project -p 2 -s $DIR/$tdir/subdir ||
22813                 error "set subdir project id failed"
22814         local pbefore="$($LFS project -d $DIR/$tdir)"
22815         local sbefore="$($LFS project -d $DIR/$tdir/subdir)"
22816         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
22817
22818         local pafter="$($LFS project -d $DIR/$tdir)"
22819         local safter="$($LFS project -d $DIR/$tdir/subdir)"
22820         [[ "$pbefore" == "$pafter" ]] || error "projid '$pbefore' != '$pafter'"
22821         [[ "$sbefore" == "$safter" ]] || error "projid '$sbefore' != '$safter'"
22822
22823         (( $MDS1_VERSION >= $(version_code 2.15.59.107) )) ||
22824                 { echo "Need MDS >= 2.15.59.107 for projid rename"; return 0; }
22825
22826         # check rename works, even if source parent projid differs (LU-17016)
22827         test_mkdir $DIR/$tdir.2 || error "mkdir $tdir.2 failed"
22828         local fid_before=$($LFS path2fid $DIR/$tdir/subdir)
22829
22830         $LFS project -p 2 -s $DIR/$tdir.2 || error "set $tdir.2 projid failed"
22831         mrename $DIR/$tdir/subdir $DIR/$tdir.2/subdir ||
22832                 error "subdir failed rename for different source parent projid"
22833         local fid_after=$($LFS path2fid $DIR/$tdir.2/subdir)
22834
22835         [[ "$fid_before" == "$fid_after" ]] ||
22836                 error "fid before '$fid_before' != after '$fid_after'"
22837 }
22838 run_test 230t "migrate directory with project ID set"
22839
22840 test_230u()
22841 {
22842         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22843         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22844                 skip "Need MDS version at least 2.14.53"
22845
22846         local count
22847
22848         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22849         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22850         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
22851         for i in $(seq 0 $((MDSCOUNT - 1))); do
22852                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22853                 echo "$count dirs migrated to MDT$i"
22854         done
22855         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22856         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
22857 }
22858 run_test 230u "migrate directory by QOS"
22859
22860 test_230v()
22861 {
22862         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
22863         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
22864                 skip "Need MDS version at least 2.14.53"
22865
22866         local count
22867
22868         mkdir $DIR/$tdir || error "mkdir $tdir failed"
22869         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
22870         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
22871         for i in $(seq 0 $((MDSCOUNT - 1))); do
22872                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
22873                 echo "$count subdirs migrated to MDT$i"
22874                 (( i == 3 )) && (( count > 0 )) &&
22875                         error "subdir shouldn't be migrated to MDT3"
22876         done
22877         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
22878         (( count == 3 )) || error "dirs migrated to $count MDTs"
22879 }
22880 run_test 230v "subdir migrated to the MDT where its parent is located"
22881
22882 test_230w() {
22883         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22884         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22885                 skip "Need MDS version at least 2.15.0"
22886
22887         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
22888         createmany -o $DIR/$tdir/f 10 || error "create files failed"
22889         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
22890
22891         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
22892                 error "migrate failed"
22893
22894         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
22895                 error "$tdir stripe count mismatch"
22896
22897         for i in $(seq 0 9); do
22898                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
22899                         error "d$i is striped"
22900         done
22901 }
22902 run_test 230w "non-recursive mode dir migration"
22903
22904 test_230x() {
22905         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22906         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
22907                 skip "Need MDS version at least 2.15.0"
22908
22909         mkdir -p $DIR/$tdir || error "mkdir failed"
22910         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
22911
22912         local mdt_name=$(mdtname_from_index 0)
22913         local low=$(do_facet mds2 $LCTL get_param -n \
22914                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
22915         local high=$(do_facet mds2 $LCTL get_param -n \
22916                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
22917         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
22918         local maxage=$(do_facet mds2 $LCTL get_param -n \
22919                 osp.*$mdt_name-osp-MDT0001.maxage)
22920
22921         stack_trap "do_facet mds2 $LCTL set_param -n \
22922                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
22923                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
22924         stack_trap "do_facet mds2 $LCTL set_param -n \
22925                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
22926
22927         do_facet mds2 $LCTL set_param -n \
22928                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
22929         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
22930         sleep 4
22931         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
22932                 error "migrate $tdir should fail"
22933
22934         do_facet mds2 $LCTL set_param -n \
22935                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
22936         do_facet mds2 $LCTL set_param -n \
22937                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
22938         sleep 4
22939         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
22940                 error "migrate failed"
22941         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
22942                 error "$tdir stripe count mismatch"
22943 }
22944 run_test 230x "dir migration check space"
22945
22946 test_230y() {
22947         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22948         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22949                 skip "Need MDS version at least 2.15.55.45"
22950
22951         local pid
22952
22953         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22954         $LFS getdirstripe $DIR/$tdir
22955         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22956         $LFS migrate -m 1 -c 2 $DIR/$tdir &
22957         pid=$!
22958         sleep 1
22959
22960         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22961         do_facet mds2 lctl set_param fail_loc=0x1802
22962
22963         wait $pid
22964         do_facet mds2 lctl set_param fail_loc=0
22965         $LFS getdirstripe $DIR/$tdir
22966         unlinkmany -d $DIR/$tdir/d 100 || error "unlinkmany failed"
22967         rmdir $DIR/$tdir || error "rmdir $tdir failed"
22968 }
22969 run_test 230y "unlink dir with bad hash type"
22970
22971 test_230z() {
22972         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
22973         (( MDS1_VERSION >= $(version_code 2.15.55.45) )) ||
22974                 skip "Need MDS version at least 2.15.55.45"
22975
22976         local pid
22977
22978         test_mkdir -c -1 $DIR/$tdir || error "mkdir $tdir failed"
22979         $LFS getdirstripe $DIR/$tdir
22980         createmany -d $DIR/$tdir/d 100 || error "createmany failed"
22981         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir &
22982         pid=$!
22983         sleep 1
22984
22985         #OBD_FAIL_MIGRATE_BAD_HASH      0x1802
22986         do_facet mds2 lctl set_param fail_loc=0x1802
22987
22988         wait $pid
22989         do_facet mds2 lctl set_param fail_loc=0
22990         $LFS getdirstripe $DIR/$tdir
22991
22992         # resume migration
22993         $LFS migrate -m 1 -c 2 -H fnv_1a_64 $DIR/$tdir ||
22994                 error "resume migration failed"
22995         $LFS getdirstripe $DIR/$tdir
22996         [ $($LFS getdirstripe -H $DIR/$tdir) == "fnv_1a_64,fixed" ] ||
22997                 error "migration is not finished"
22998 }
22999 run_test 230z "resume dir migration with bad hash type"
23000
23001 test_231a()
23002 {
23003         # For simplicity this test assumes that max_pages_per_rpc
23004         # is the same across all OSCs
23005         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
23006         local bulk_size=$((max_pages * PAGE_SIZE))
23007         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
23008                                        head -n 1)
23009
23010         mkdir -p $DIR/$tdir
23011         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
23012                 error "failed to set stripe with -S ${brw_size}M option"
23013         stack_trap "rm -rf $DIR/$tdir"
23014
23015         # clear the OSC stats
23016         $LCTL set_param osc.*.stats=0 &>/dev/null
23017         stop_writeback
23018
23019         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
23020         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
23021                 oflag=direct &>/dev/null || error "dd failed"
23022
23023         sync; sleep 1; sync # just to be safe
23024         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
23025         if [ x$nrpcs != "x1" ]; then
23026                 $LCTL get_param osc.*.stats
23027                 error "found $nrpcs ost_write RPCs, not 1 as expected"
23028         fi
23029
23030         start_writeback
23031         # Drop the OSC cache, otherwise we will read from it
23032         cancel_lru_locks osc
23033
23034         # clear the OSC stats
23035         $LCTL set_param osc.*.stats=0 &>/dev/null
23036
23037         # Client reads $bulk_size.
23038         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
23039                 iflag=direct &>/dev/null || error "dd failed"
23040
23041         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
23042         if [ x$nrpcs != "x1" ]; then
23043                 $LCTL get_param osc.*.stats
23044                 error "found $nrpcs ost_read RPCs, not 1 as expected"
23045         fi
23046 }
23047 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
23048
23049 test_231b() {
23050         mkdir -p $DIR/$tdir
23051         stack_trap "rm -rf $DIR/$tdir"
23052         local i
23053         for i in {0..1023}; do
23054                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
23055                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
23056                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
23057         done
23058         sync
23059 }
23060 run_test 231b "must not assert on fully utilized OST request buffer"
23061
23062 test_232a() {
23063         mkdir -p $DIR/$tdir
23064         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23065
23066         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23067         do_facet ost1 $LCTL set_param fail_loc=0x31c
23068
23069         # ignore dd failure
23070         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
23071         stack_trap "rm -f $DIR/$tdir/$tfile"
23072
23073         do_facet ost1 $LCTL set_param fail_loc=0
23074         umount_client $MOUNT || error "umount failed"
23075         mount_client $MOUNT || error "mount failed"
23076         stop ost1 || error "cannot stop ost1"
23077         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23078 }
23079 run_test 232a "failed lock should not block umount"
23080
23081 test_232b() {
23082         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
23083                 skip "Need MDS version at least 2.10.58"
23084
23085         mkdir -p $DIR/$tdir
23086         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
23087         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
23088         stack_trap "rm -f $DIR/$tdir/$tfile"
23089         sync
23090         cancel_lru_locks osc
23091
23092         #define OBD_FAIL_LDLM_OST_LVB            0x31c
23093         do_facet ost1 $LCTL set_param fail_loc=0x31c
23094
23095         # ignore failure
23096         $LFS data_version $DIR/$tdir/$tfile || true
23097
23098         do_facet ost1 $LCTL set_param fail_loc=0
23099         umount_client $MOUNT || error "umount failed"
23100         mount_client $MOUNT || error "mount failed"
23101         stop ost1 || error "cannot stop ost1"
23102         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23103 }
23104 run_test 232b "failed data version lock should not block umount"
23105
23106 test_233a() {
23107         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
23108                 skip "Need MDS version at least 2.3.64"
23109         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23110
23111         local fid=$($LFS path2fid $MOUNT)
23112
23113         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23114                 error "cannot access $MOUNT using its FID '$fid'"
23115 }
23116 run_test 233a "checking that OBF of the FS root succeeds"
23117
23118 test_233b() {
23119         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
23120                 skip "Need MDS version at least 2.5.90"
23121         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
23122
23123         local fid=$($LFS path2fid $MOUNT/.lustre)
23124
23125         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23126                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
23127
23128         fid=$($LFS path2fid $MOUNT/.lustre/fid)
23129         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
23130                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
23131 }
23132 run_test 233b "checking that OBF of the FS .lustre succeeds"
23133
23134 test_234() {
23135         local p="$TMP/sanityN-$TESTNAME.parameters"
23136         save_lustre_params client "llite.*.xattr_cache" > $p
23137         lctl set_param llite.*.xattr_cache 1 ||
23138                 skip_env "xattr cache is not supported"
23139
23140         mkdir -p $DIR/$tdir || error "mkdir failed"
23141         touch $DIR/$tdir/$tfile || error "touch failed"
23142         # OBD_FAIL_LLITE_XATTR_ENOMEM
23143         $LCTL set_param fail_loc=0x1405
23144         getfattr -n user.attr $DIR/$tdir/$tfile &&
23145                 error "getfattr should have failed with ENOMEM"
23146         $LCTL set_param fail_loc=0x0
23147         rm -rf $DIR/$tdir
23148
23149         restore_lustre_params < $p
23150         rm -f $p
23151 }
23152 run_test 234 "xattr cache should not crash on ENOMEM"
23153
23154 test_235() {
23155         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
23156                 skip "Need MDS version at least 2.4.52"
23157
23158         flock_deadlock $DIR/$tfile
23159         local RC=$?
23160         case $RC in
23161                 0)
23162                 ;;
23163                 124) error "process hangs on a deadlock"
23164                 ;;
23165                 *) error "error executing flock_deadlock $DIR/$tfile"
23166                 ;;
23167         esac
23168 }
23169 run_test 235 "LU-1715: flock deadlock detection does not work properly"
23170
23171 #LU-2935
23172 test_236() {
23173         check_swap_layouts_support
23174
23175         local ref1=/etc/passwd
23176         local ref2=/etc/group
23177         local file1=$DIR/$tdir/f1
23178         local file2=$DIR/$tdir/f2
23179
23180         test_mkdir -c1 $DIR/$tdir
23181         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
23182         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
23183         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
23184         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
23185         local fd=$(free_fd)
23186         local cmd="exec $fd<>$file2"
23187         eval $cmd
23188         rm $file2
23189         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
23190                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
23191         cmd="exec $fd>&-"
23192         eval $cmd
23193         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
23194
23195         #cleanup
23196         rm -rf $DIR/$tdir
23197 }
23198 run_test 236 "Layout swap on open unlinked file"
23199
23200 # LU-4659 linkea consistency
23201 test_238() {
23202         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
23203                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
23204                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
23205                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
23206
23207         touch $DIR/$tfile
23208         ln $DIR/$tfile $DIR/$tfile.lnk
23209         touch $DIR/$tfile.new
23210         mv $DIR/$tfile.new $DIR/$tfile
23211         local fid1=$($LFS path2fid $DIR/$tfile)
23212         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
23213         local path1=$($LFS fid2path $FSNAME "$fid1")
23214         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
23215         local path2=$($LFS fid2path $FSNAME "$fid2")
23216         [ $tfile.lnk == $path2 ] ||
23217                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
23218         rm -f $DIR/$tfile*
23219 }
23220 run_test 238 "Verify linkea consistency"
23221
23222 test_239A() { # was test_239
23223         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
23224                 skip "Need MDS version at least 2.5.60"
23225
23226         local list=$(comma_list $(mdts_nodes))
23227
23228         mkdir -p $DIR/$tdir
23229         createmany -o $DIR/$tdir/f- 5000
23230         unlinkmany $DIR/$tdir/f- 5000
23231         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
23232                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
23233         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
23234                         osp.*MDT*.sync_in_flight" | calc_sum)
23235         [ "$changes" -eq 0 ] || error "$changes not synced"
23236 }
23237 run_test 239A "osp_sync test"
23238
23239 test_239a() { #LU-5297
23240         remote_mds_nodsh && skip "remote MDS with nodsh"
23241
23242         touch $DIR/$tfile
23243         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
23244         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
23245         chgrp $RUNAS_GID $DIR/$tfile
23246         wait_delete_completed
23247 }
23248 run_test 239a "process invalid osp sync record correctly"
23249
23250 test_239b() { #LU-5297
23251         remote_mds_nodsh && skip "remote MDS with nodsh"
23252
23253         touch $DIR/$tfile1
23254         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
23255         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
23256         chgrp $RUNAS_GID $DIR/$tfile1
23257         wait_delete_completed
23258         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
23259         touch $DIR/$tfile2
23260         chgrp $RUNAS_GID $DIR/$tfile2
23261         wait_delete_completed
23262 }
23263 run_test 239b "process osp sync record with ENOMEM error correctly"
23264
23265 test_240() {
23266         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
23267         remote_mds_nodsh && skip "remote MDS with nodsh"
23268
23269         mkdir -p $DIR/$tdir
23270
23271         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
23272                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
23273         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
23274                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
23275
23276         umount_client $MOUNT || error "umount failed"
23277         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
23278         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
23279         mount_client $MOUNT || error "failed to mount client"
23280
23281         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
23282         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
23283 }
23284 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
23285
23286 test_241_bio() {
23287         local count=$1
23288         local bsize=$2
23289
23290         for LOOP in $(seq $count); do
23291                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
23292                 cancel_lru_locks $OSC || true
23293         done
23294 }
23295
23296 test_241_dio() {
23297         local count=$1
23298         local bsize=$2
23299
23300         for LOOP in $(seq $1); do
23301                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
23302                         2>/dev/null
23303         done
23304 }
23305
23306 test_241a() { # was test_241
23307         local bsize=$PAGE_SIZE
23308
23309         (( bsize < 40960 )) && bsize=40960
23310         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23311         ls -la $DIR/$tfile
23312         cancel_lru_locks $OSC
23313         test_241_bio 1000 $bsize &
23314         PID=$!
23315         test_241_dio 1000 $bsize
23316         wait $PID
23317 }
23318 run_test 241a "bio vs dio"
23319
23320 test_241b() {
23321         local bsize=$PAGE_SIZE
23322
23323         (( bsize < 40960 )) && bsize=40960
23324         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
23325         ls -la $DIR/$tfile
23326         test_241_dio 1000 $bsize &
23327         PID=$!
23328         test_241_dio 1000 $bsize
23329         wait $PID
23330 }
23331 run_test 241b "dio vs dio"
23332
23333 test_242() {
23334         remote_mds_nodsh && skip "remote MDS with nodsh"
23335
23336         mkdir_on_mdt0 $DIR/$tdir
23337         touch $DIR/$tdir/$tfile
23338
23339         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
23340         do_facet mds1 lctl set_param fail_loc=0x105
23341         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
23342
23343         do_facet mds1 lctl set_param fail_loc=0
23344         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
23345 }
23346 run_test 242 "mdt_readpage failure should not cause directory unreadable"
23347
23348 test_243()
23349 {
23350         test_mkdir $DIR/$tdir
23351         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
23352 }
23353 run_test 243 "various group lock tests"
23354
23355 test_244a()
23356 {
23357         test_mkdir $DIR/$tdir
23358         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
23359         sendfile_grouplock $DIR/$tdir/$tfile || \
23360                 error "sendfile+grouplock failed"
23361         rm -rf $DIR/$tdir
23362 }
23363 run_test 244a "sendfile with group lock tests"
23364
23365 test_244b()
23366 {
23367         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
23368
23369         local threads=50
23370         local size=$((1024*1024))
23371
23372         test_mkdir $DIR/$tdir
23373         for i in $(seq 1 $threads); do
23374                 local file=$DIR/$tdir/file_$((i / 10))
23375                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
23376                 local pids[$i]=$!
23377         done
23378         for i in $(seq 1 $threads); do
23379                 wait ${pids[$i]}
23380         done
23381 }
23382 run_test 244b "multi-threaded write with group lock"
23383
23384 test_245a() {
23385         local flagname="multi_mod_rpcs"
23386         local connect_data_name="max_mod_rpcs"
23387         local out
23388
23389         # check if multiple modify RPCs flag is set
23390         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
23391                 grep "connect_flags:")
23392         echo "$out"
23393
23394         echo "$out" | grep -qw $flagname
23395         if [ $? -ne 0 ]; then
23396                 echo "connect flag $flagname is not set"
23397                 return
23398         fi
23399
23400         # check if multiple modify RPCs data is set
23401         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
23402         echo "$out"
23403
23404         echo "$out" | grep -qw $connect_data_name ||
23405                 error "import should have connect data $connect_data_name"
23406 }
23407 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
23408
23409 test_245b() {
23410         local flagname="multi_mod_rpcs"
23411         local connect_data_name="max_mod_rpcs"
23412         local out
23413
23414         remote_mds_nodsh && skip "remote MDS with nodsh"
23415         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
23416
23417         # check if multiple modify RPCs flag is set
23418         out=$(do_facet mds1 \
23419               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
23420               grep "connect_flags:")
23421         echo "$out"
23422
23423         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
23424
23425         # check if multiple modify RPCs data is set
23426         out=$(do_facet mds1 \
23427               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
23428
23429         [[ "$out" =~ $connect_data_name ]] ||
23430                 {
23431                         echo "$out"
23432                         error "missing connect data $connect_data_name"
23433                 }
23434 }
23435 run_test 245b "check osp connection flag/data: multiple modify RPCs"
23436
23437 cleanup_247() {
23438         local submount=$1
23439
23440         trap 0
23441         umount_client $submount
23442         rmdir $submount
23443 }
23444
23445 test_247a() {
23446         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23447                 grep -q subtree ||
23448                 skip_env "Fileset feature is not supported"
23449
23450         local submount=${MOUNT}_$tdir
23451
23452         mkdir $MOUNT/$tdir
23453         mkdir -p $submount || error "mkdir $submount failed"
23454         FILESET="$FILESET/$tdir" mount_client $submount ||
23455                 error "mount $submount failed"
23456         trap "cleanup_247 $submount" EXIT
23457         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
23458         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
23459                 error "read $MOUNT/$tdir/$tfile failed"
23460         cleanup_247 $submount
23461 }
23462 run_test 247a "mount subdir as fileset"
23463
23464 test_247b() {
23465         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23466                 skip_env "Fileset feature is not supported"
23467
23468         local submount=${MOUNT}_$tdir
23469
23470         rm -rf $MOUNT/$tdir
23471         mkdir -p $submount || error "mkdir $submount failed"
23472         SKIP_FILESET=1
23473         FILESET="$FILESET/$tdir" mount_client $submount &&
23474                 error "mount $submount should fail"
23475         rmdir $submount
23476 }
23477 run_test 247b "mount subdir that dose not exist"
23478
23479 test_247c() {
23480         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23481                 skip_env "Fileset feature is not supported"
23482
23483         local submount=${MOUNT}_$tdir
23484
23485         mkdir -p $MOUNT/$tdir/dir1
23486         mkdir -p $submount || error "mkdir $submount failed"
23487         trap "cleanup_247 $submount" EXIT
23488         FILESET="$FILESET/$tdir" mount_client $submount ||
23489                 error "mount $submount failed"
23490         local fid=$($LFS path2fid $MOUNT/)
23491         $LFS fid2path $submount $fid && error "fid2path should fail"
23492         cleanup_247 $submount
23493 }
23494 run_test 247c "running fid2path outside subdirectory root"
23495
23496 test_247d() {
23497         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23498                 skip "Fileset feature is not supported"
23499
23500         local submount=${MOUNT}_$tdir
23501
23502         mkdir -p $MOUNT/$tdir/dir1
23503         mkdir -p $submount || error "mkdir $submount failed"
23504         FILESET="$FILESET/$tdir" mount_client $submount ||
23505                 error "mount $submount failed"
23506         trap "cleanup_247 $submount" EXIT
23507
23508         local td=$submount/dir1
23509         local fid=$($LFS path2fid $td)
23510         [ -z "$fid" ] && error "path2fid unable to get $td FID"
23511
23512         # check that we get the same pathname back
23513         local rootpath
23514         local found
23515         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
23516                 echo "$rootpath $fid"
23517                 found=$($LFS fid2path $rootpath "$fid")
23518                 [ -n "$found" ] || error "fid2path should succeed"
23519                 [ "$found" == "$td" ] || error "fid2path $found != $td"
23520         done
23521         # check wrong root path format
23522         rootpath=$submount"_wrong"
23523         found=$($LFS fid2path $rootpath "$fid")
23524         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
23525
23526         cleanup_247 $submount
23527 }
23528 run_test 247d "running fid2path inside subdirectory root"
23529
23530 # LU-8037
23531 test_247e() {
23532         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
23533                 grep -q subtree ||
23534                 skip "Fileset feature is not supported"
23535
23536         local submount=${MOUNT}_$tdir
23537
23538         mkdir $MOUNT/$tdir
23539         mkdir -p $submount || error "mkdir $submount failed"
23540         FILESET="$FILESET/.." mount_client $submount &&
23541                 error "mount $submount should fail"
23542         rmdir $submount
23543 }
23544 run_test 247e "mount .. as fileset"
23545
23546 test_247f() {
23547         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
23548         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
23549                 skip "Need at least version 2.14.50.162"
23550         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
23551                 skip "Fileset feature is not supported"
23552
23553         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
23554         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
23555                 error "mkdir remote failed"
23556         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
23557                 error "mkdir remote/subdir failed"
23558         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
23559                 error "mkdir striped failed"
23560         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
23561
23562         local submount=${MOUNT}_$tdir
23563
23564         mkdir -p $submount || error "mkdir $submount failed"
23565         stack_trap "rmdir $submount"
23566
23567         local dir
23568         local fileset=$FILESET
23569         local mdts=$(comma_list $(mdts_nodes))
23570
23571         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
23572         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
23573                 $tdir/striped/subdir $tdir/striped/.; do
23574                 FILESET="$fileset/$dir" mount_client $submount ||
23575                         error "mount $dir failed"
23576                 umount_client $submount
23577         done
23578 }
23579 run_test 247f "mount striped or remote directory as fileset"
23580
23581 test_subdir_mount_lock()
23582 {
23583         local testdir=$1
23584         local submount=${MOUNT}_$(basename $testdir)
23585
23586         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
23587
23588         mkdir -p $submount || error "mkdir $submount failed"
23589         stack_trap "rmdir $submount"
23590
23591         FILESET="$fileset/$testdir" mount_client $submount ||
23592                 error "mount $FILESET failed"
23593         stack_trap "umount $submount"
23594
23595         local mdts=$(comma_list $(mdts_nodes))
23596
23597         local nrpcs
23598
23599         stat $submount > /dev/null || error "stat $submount failed"
23600         cancel_lru_locks $MDC
23601         stat $submount > /dev/null || error "stat $submount failed"
23602         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23603         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
23604         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
23605         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
23606                 awk '/getattr/ {sum += $2} END {print sum}')
23607
23608         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
23609 }
23610
23611 test_247g() {
23612         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23613
23614         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
23615                 error "mkdir $tdir failed"
23616         test_subdir_mount_lock $tdir
23617 }
23618 run_test 247g "striped directory submount revalidate ROOT from cache"
23619
23620 test_247h() {
23621         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
23622         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
23623                 skip "Need MDS version at least 2.15.51"
23624
23625         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
23626         test_subdir_mount_lock $tdir
23627         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
23628         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
23629                 error "mkdir $tdir.1 failed"
23630         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
23631 }
23632 run_test 247h "remote directory submount revalidate ROOT from cache"
23633
23634 test_248a() {
23635         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
23636         [ -z "$fast_read_sav" ] && skip "no fast read support"
23637
23638         # create a large file for fast read verification
23639         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
23640
23641         # make sure the file is created correctly
23642         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
23643                 { rm -f $DIR/$tfile; skip "file creation error"; }
23644
23645         echo "Test 1: verify that fast read is 4 times faster on cache read"
23646
23647         # small read with fast read enabled
23648         $LCTL set_param -n llite.*.fast_read=1
23649         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23650                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23651                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23652         # small read with fast read disabled
23653         $LCTL set_param -n llite.*.fast_read=0
23654         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
23655                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23656                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23657
23658         # verify that fast read is 4 times faster for cache read
23659         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
23660                 error_not_in_vm "fast read was not 4 times faster: " \
23661                            "$t_fast vs $t_slow"
23662
23663         echo "Test 2: verify the performance between big and small read"
23664         $LCTL set_param -n llite.*.fast_read=1
23665
23666         # 1k non-cache read
23667         cancel_lru_locks osc
23668         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23669                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23670                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23671
23672         # 1M non-cache read
23673         cancel_lru_locks osc
23674         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
23675                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
23676                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
23677
23678         # verify that big IO is not 4 times faster than small IO
23679         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
23680                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
23681
23682         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
23683         rm -f $DIR/$tfile
23684 }
23685 run_test 248a "fast read verification"
23686
23687 test_248b() {
23688         # Default short_io_bytes=16384, try both smaller and larger sizes.
23689         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
23690         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
23691         echo "bs=53248 count=113 normal buffered write"
23692         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
23693                 error "dd of initial data file failed"
23694         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
23695
23696         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
23697         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
23698                 error "dd with sync normal writes failed"
23699         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
23700
23701         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
23702         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
23703                 error "dd with sync small writes failed"
23704         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
23705
23706         cancel_lru_locks osc
23707
23708         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
23709         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
23710         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
23711         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
23712                 iflag=direct || error "dd with O_DIRECT small read failed"
23713         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
23714         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
23715                 error "compare $TMP/$tfile.1 failed"
23716
23717         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
23718         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
23719
23720         # just to see what the maximum tunable value is, and test parsing
23721         echo "test invalid parameter 2MB"
23722         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
23723                 error "too-large short_io_bytes allowed"
23724         echo "test maximum parameter 512KB"
23725         # if we can set a larger short_io_bytes, run test regardless of version
23726         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
23727                 # older clients may not allow setting it this large, that's OK
23728                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
23729                         skip "Need at least client version 2.13.50"
23730                 error "medium short_io_bytes failed"
23731         fi
23732         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23733         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
23734
23735         echo "test large parameter 64KB"
23736         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
23737         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
23738
23739         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
23740         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
23741                 error "dd with sync large writes failed"
23742         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
23743
23744         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
23745         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
23746         num=$((113 * 4096 / PAGE_SIZE))
23747         echo "bs=$size count=$num oflag=direct large write $tfile.3"
23748         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
23749                 error "dd with O_DIRECT large writes failed"
23750         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
23751                 error "compare $DIR/$tfile.3 failed"
23752
23753         cancel_lru_locks osc
23754
23755         echo "bs=$size count=$num iflag=direct large read $tfile.2"
23756         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
23757                 error "dd with O_DIRECT large read failed"
23758         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
23759                 error "compare $TMP/$tfile.2 failed"
23760
23761         echo "bs=$size count=$num iflag=direct large read $tfile.3"
23762         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
23763                 error "dd with O_DIRECT large read failed"
23764         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
23765                 error "compare $TMP/$tfile.3 failed"
23766 }
23767 run_test 248b "test short_io read and write for both small and large sizes"
23768
23769 test_249() { # LU-7890
23770         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
23771                 skip "Need at least version 2.8.54"
23772
23773         rm -f $DIR/$tfile
23774         $LFS setstripe -c 1 $DIR/$tfile
23775         # Offset 2T == 4k * 512M
23776         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
23777                 error "dd to 2T offset failed"
23778 }
23779 run_test 249 "Write above 2T file size"
23780
23781 test_250() {
23782         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
23783          && skip "no 16TB file size limit on ZFS"
23784
23785         $LFS setstripe -c 1 $DIR/$tfile
23786         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
23787         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
23788         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
23789         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
23790                 conv=notrunc,fsync && error "append succeeded"
23791         return 0
23792 }
23793 run_test 250 "Write above 16T limit"
23794
23795 test_251() {
23796         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
23797
23798         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
23799         #Skip once - writing the first stripe will succeed
23800         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23801         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
23802                 error "short write happened"
23803
23804         $LCTL set_param fail_loc=0xa0001407 fail_val=1
23805         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
23806                 error "short read happened"
23807
23808         rm -f $DIR/$tfile
23809 }
23810 run_test 251 "Handling short read and write correctly"
23811
23812 test_252() {
23813         remote_mds_nodsh && skip "remote MDS with nodsh"
23814         remote_ost_nodsh && skip "remote OST with nodsh"
23815         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
23816                 skip_env "ldiskfs only test"
23817         fi
23818
23819         local tgt
23820         local dev
23821         local out
23822         local uuid
23823         local num
23824         local gen
23825
23826         # check lr_reader on OST0000
23827         tgt=ost1
23828         dev=$(facet_device $tgt)
23829         out=$(do_facet $tgt $LR_READER $dev)
23830         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23831         echo "$out"
23832         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
23833         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
23834                 error "Invalid uuid returned by $LR_READER on target $tgt"
23835         echo -e "uuid returned by $LR_READER is '$uuid'\n"
23836
23837         # check lr_reader -c on MDT0000
23838         tgt=mds1
23839         dev=$(facet_device $tgt)
23840         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
23841                 skip "$LR_READER does not support additional options"
23842         fi
23843         out=$(do_facet $tgt $LR_READER -c $dev)
23844         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23845         echo "$out"
23846         num=$(echo "$out" | grep -c "mdtlov")
23847         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
23848                 error "Invalid number of mdtlov clients returned by $LR_READER"
23849         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
23850
23851         # check lr_reader -cr on MDT0000
23852         out=$(do_facet $tgt $LR_READER -cr $dev)
23853         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
23854         echo "$out"
23855         echo "$out" | grep -q "^reply_data:$" ||
23856                 error "$LR_READER should have returned 'reply_data' section"
23857         num=$(echo "$out" | grep -c "client_generation")
23858         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
23859 }
23860 run_test 252 "check lr_reader tool"
23861
23862 test_253() {
23863         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23864         remote_mds_nodsh && skip "remote MDS with nodsh"
23865         remote_mgs_nodsh && skip "remote MGS with nodsh"
23866         check_set_fallocate_or_skip
23867
23868         local ostidx=0
23869         local rc=0
23870         local ost_name=$(ostname_from_index $ostidx)
23871
23872         # on the mdt's osc
23873         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
23874         do_facet $SINGLEMDS $LCTL get_param -n \
23875                 osp.$mdtosc_proc1.reserved_mb_high ||
23876                 skip  "remote MDS does not support reserved_mb_high"
23877
23878         rm -rf $DIR/$tdir
23879         wait_mds_ost_sync
23880         wait_delete_completed
23881         mkdir $DIR/$tdir
23882         stack_trap "rm -rf $DIR/$tdir"
23883
23884         pool_add $TESTNAME || error "Pool creation failed"
23885         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
23886
23887         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
23888                 error "Setstripe failed"
23889
23890         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
23891
23892         local wms=$(ost_watermarks_get $ostidx)
23893
23894         ost_watermarks_set $ostidx 60 50
23895         stack_trap "ost_watermarks_set $ostidx $wms"
23896
23897         local free_kb=$($LFS df $MOUNT | awk "/$ost_name/ { print \$4 }")
23898         local size=$((free_kb * 1024))
23899
23900         fallocate -l $size $DIR/$tdir/fill_ost$ostidx ||
23901                 error "fallocate failed"
23902         sleep_maxage
23903
23904         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23905                         osp.$mdtosc_proc1.prealloc_status)
23906         echo "prealloc_status $oa_status"
23907
23908         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
23909                 error "File creation should fail"
23910
23911         #object allocation was stopped, but we still able to append files
23912         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
23913                 oflag=append || error "Append failed"
23914
23915         rm -f $DIR/$tdir/$tfile.0
23916         rm -f $DIR/$tdir/fill_ost$ostidx
23917
23918         wait_delete_completed
23919         sleep_maxage
23920
23921         for i in $(seq 10 12); do
23922                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
23923                         2>/dev/null || error "File creation failed after rm"
23924         done
23925
23926         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
23927                         osp.$mdtosc_proc1.prealloc_status)
23928         echo "prealloc_status $oa_status"
23929
23930         if (( oa_status != 0 )); then
23931                 error "Object allocation still disable after rm"
23932         fi
23933 }
23934 run_test 253 "Check object allocation limit"
23935
23936 test_254() {
23937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23938         remote_mds_nodsh && skip "remote MDS with nodsh"
23939
23940         local mdt=$(facet_svc $SINGLEMDS)
23941
23942         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
23943                 skip "MDS does not support changelog_size"
23944
23945         local cl_user
23946
23947         changelog_register || error "changelog_register failed"
23948
23949         changelog_clear 0 || error "changelog_clear failed"
23950
23951         local size1=$(do_facet $SINGLEMDS \
23952                       $LCTL get_param -n mdd.$mdt.changelog_size)
23953         echo "Changelog size $size1"
23954
23955         rm -rf $DIR/$tdir
23956         $LFS mkdir -i 0 $DIR/$tdir
23957         # change something
23958         mkdir -p $DIR/$tdir/pics/2008/zachy
23959         touch $DIR/$tdir/pics/2008/zachy/timestamp
23960         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
23961         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
23962         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
23963         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
23964         rm $DIR/$tdir/pics/desktop.jpg
23965
23966         local size2=$(do_facet $SINGLEMDS \
23967                       $LCTL get_param -n mdd.$mdt.changelog_size)
23968         echo "Changelog size after work $size2"
23969
23970         (( $size2 > $size1 )) ||
23971                 error "new Changelog size=$size2 less than old size=$size1"
23972 }
23973 run_test 254 "Check changelog size"
23974
23975 ladvise_no_type()
23976 {
23977         local type=$1
23978         local file=$2
23979
23980         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
23981                 awk -F: '{print $2}' | grep $type > /dev/null
23982         if [ $? -ne 0 ]; then
23983                 return 0
23984         fi
23985         return 1
23986 }
23987
23988 ladvise_no_ioctl()
23989 {
23990         local file=$1
23991
23992         lfs ladvise -a willread $file > /dev/null 2>&1
23993         if [ $? -eq 0 ]; then
23994                 return 1
23995         fi
23996
23997         lfs ladvise -a willread $file 2>&1 |
23998                 grep "Inappropriate ioctl for device" > /dev/null
23999         if [ $? -eq 0 ]; then
24000                 return 0
24001         fi
24002         return 1
24003 }
24004
24005 percent() {
24006         bc <<<"scale=2; ($1 - $2) * 100 / $2"
24007 }
24008
24009 # run a random read IO workload
24010 # usage: random_read_iops <filename> <filesize> <iosize>
24011 random_read_iops() {
24012         local file=$1
24013         local fsize=$2
24014         local iosize=${3:-4096}
24015
24016         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
24017                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
24018 }
24019
24020 drop_file_oss_cache() {
24021         local file="$1"
24022         local nodes="$2"
24023
24024         $LFS ladvise -a dontneed $file 2>/dev/null ||
24025                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
24026 }
24027
24028 ladvise_willread_performance()
24029 {
24030         local repeat=10
24031         local average_origin=0
24032         local average_cache=0
24033         local average_ladvise=0
24034
24035         for ((i = 1; i <= $repeat; i++)); do
24036                 echo "Iter $i/$repeat: reading without willread hint"
24037                 cancel_lru_locks osc
24038                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24039                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
24040                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
24041                 average_origin=$(bc <<<"$average_origin + $speed_origin")
24042
24043                 cancel_lru_locks osc
24044                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
24045                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
24046                 average_cache=$(bc <<<"$average_cache + $speed_cache")
24047
24048                 cancel_lru_locks osc
24049                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
24050                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
24051                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
24052                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
24053                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
24054         done
24055         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
24056         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
24057         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
24058
24059         speedup_cache=$(percent $average_cache $average_origin)
24060         speedup_ladvise=$(percent $average_ladvise $average_origin)
24061
24062         echo "Average uncached read: $average_origin"
24063         echo "Average speedup with OSS cached read: " \
24064                 "$average_cache = +$speedup_cache%"
24065         echo "Average speedup with ladvise willread: " \
24066                 "$average_ladvise = +$speedup_ladvise%"
24067
24068         local lowest_speedup=20
24069         if (( ${average_cache%.*} < $lowest_speedup )); then
24070                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
24071                      " got $average_cache%. Skipping ladvise willread check."
24072                 return 0
24073         fi
24074
24075         # the test won't work on ZFS until it supports 'ladvise dontneed', but
24076         # it is still good to run until then to exercise 'ladvise willread'
24077         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24078                 [ "$ost1_FSTYPE" = "zfs" ] &&
24079                 echo "osd-zfs does not support dontneed or drop_caches" &&
24080                 return 0
24081
24082         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
24083         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
24084                 error_not_in_vm "Speedup with willread is less than " \
24085                         "$lowest_speedup%, got $average_ladvise%"
24086 }
24087
24088 test_255a() {
24089         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24090                 skip "lustre < 2.8.54 does not support ladvise "
24091         remote_ost_nodsh && skip "remote OST with nodsh"
24092
24093         stack_trap "rm -f $DIR/$tfile"
24094         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
24095
24096         ladvise_no_type willread $DIR/$tfile &&
24097                 skip "willread ladvise is not supported"
24098
24099         ladvise_no_ioctl $DIR/$tfile &&
24100                 skip "ladvise ioctl is not supported"
24101
24102         local size_mb=100
24103         local size=$((size_mb * 1048576))
24104         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24105                 error "dd to $DIR/$tfile failed"
24106
24107         lfs ladvise -a willread $DIR/$tfile ||
24108                 error "Ladvise failed with no range argument"
24109
24110         lfs ladvise -a willread -s 0 $DIR/$tfile ||
24111                 error "Ladvise failed with no -l or -e argument"
24112
24113         lfs ladvise -a willread -e 1 $DIR/$tfile ||
24114                 error "Ladvise failed with only -e argument"
24115
24116         lfs ladvise -a willread -l 1 $DIR/$tfile ||
24117                 error "Ladvise failed with only -l argument"
24118
24119         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
24120                 error "End offset should not be smaller than start offset"
24121
24122         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
24123                 error "End offset should not be equal to start offset"
24124
24125         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
24126                 error "Ladvise failed with overflowing -s argument"
24127
24128         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
24129                 error "Ladvise failed with overflowing -e argument"
24130
24131         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
24132                 error "Ladvise failed with overflowing -l argument"
24133
24134         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
24135                 error "Ladvise succeeded with conflicting -l and -e arguments"
24136
24137         echo "Synchronous ladvise should wait"
24138         local delay=8
24139 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
24140         do_nodes $(comma_list $(osts_nodes)) \
24141                 $LCTL set_param fail_val=$delay fail_loc=0x237
24142         stack_trap "do_nodes $(comma_list $(osts_nodes)) \
24143                 $LCTL set_param fail_loc=0"
24144
24145         local start_ts=$SECONDS
24146         lfs ladvise -a willread $DIR/$tfile ||
24147                 error "Ladvise failed with no range argument"
24148         local end_ts=$SECONDS
24149         local inteval_ts=$((end_ts - start_ts))
24150
24151         if [ $inteval_ts -lt $(($delay - 1)) ]; then
24152                 error "Synchronous advice didn't wait reply"
24153         fi
24154
24155         echo "Asynchronous ladvise shouldn't wait"
24156         local start_ts=$SECONDS
24157         lfs ladvise -a willread -b $DIR/$tfile ||
24158                 error "Ladvise failed with no range argument"
24159         local end_ts=$SECONDS
24160         local inteval_ts=$((end_ts - start_ts))
24161
24162         if [ $inteval_ts -gt $(($delay / 2)) ]; then
24163                 error "Asynchronous advice blocked"
24164         fi
24165
24166         ladvise_willread_performance
24167 }
24168 run_test 255a "check 'lfs ladvise -a willread'"
24169
24170 facet_meminfo() {
24171         local facet=$1
24172         local info=$2
24173
24174         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
24175 }
24176
24177 test_255b() {
24178         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
24179                 skip "lustre < 2.8.54 does not support ladvise "
24180         remote_ost_nodsh && skip "remote OST with nodsh"
24181
24182         stack_trap "rm -f $DIR/$tfile"
24183         lfs setstripe -c 1 -i 0 $DIR/$tfile
24184
24185         ladvise_no_type dontneed $DIR/$tfile &&
24186                 skip "dontneed ladvise is not supported"
24187
24188         ladvise_no_ioctl $DIR/$tfile &&
24189                 skip "ladvise ioctl is not supported"
24190
24191         ! $LFS ladvise -a dontneed $DIR/$tfile &&
24192                 [ "$ost1_FSTYPE" = "zfs" ] &&
24193                 skip "zfs-osd does not support 'ladvise dontneed'"
24194
24195         local size_mb=100
24196         local size=$((size_mb * 1048576))
24197         # In order to prevent disturbance of other processes, only check 3/4
24198         # of the memory usage
24199         local kibibytes=$((size_mb * 1024 * 3 / 4))
24200
24201         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
24202                 error "dd to $DIR/$tfile failed"
24203
24204         #force write to complete before dropping OST cache & checking memory
24205         sync
24206
24207         local total=$(facet_meminfo ost1 MemTotal)
24208         echo "Total memory: $total KiB"
24209
24210         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
24211         local before_read=$(facet_meminfo ost1 Cached)
24212         echo "Cache used before read: $before_read KiB"
24213
24214         lfs ladvise -a willread $DIR/$tfile ||
24215                 error "Ladvise willread failed"
24216         local after_read=$(facet_meminfo ost1 Cached)
24217         echo "Cache used after read: $after_read KiB"
24218
24219         lfs ladvise -a dontneed $DIR/$tfile ||
24220                 error "Ladvise dontneed again failed"
24221         local no_read=$(facet_meminfo ost1 Cached)
24222         echo "Cache used after dontneed ladvise: $no_read KiB"
24223
24224         if [ $total -lt $((before_read + kibibytes)) ]; then
24225                 echo "Memory is too small, abort checking"
24226                 return 0
24227         fi
24228
24229         if [ $((before_read + kibibytes)) -gt $after_read ]; then
24230                 error "Ladvise willread should use more memory" \
24231                         "than $kibibytes KiB"
24232         fi
24233
24234         if [ $((no_read + kibibytes)) -gt $after_read ]; then
24235                 error "Ladvise dontneed should release more memory" \
24236                         "than $kibibytes KiB"
24237         fi
24238 }
24239 run_test 255b "check 'lfs ladvise -a dontneed'"
24240
24241 test_255c() {
24242         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
24243                 skip "lustre < 2.10.50 does not support lockahead"
24244
24245         local ost1_imp=$(get_osc_import_name client ost1)
24246         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
24247                          cut -d'.' -f2)
24248         local count
24249         local new_count
24250         local difference
24251         local i
24252         local rc
24253
24254         test_mkdir -p $DIR/$tdir
24255         $LFS setstripe -i 0 -c 1 $DIR/$tdir
24256
24257         #test 10 returns only success/failure
24258         i=10
24259         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24260         rc=$?
24261         if [ $rc -eq 255 ]; then
24262                 error "Ladvise test${i} failed, ${rc}"
24263         fi
24264
24265         #test 11 counts lock enqueue requests, all others count new locks
24266         i=11
24267         count=$(do_facet ost1 \
24268                 $LCTL get_param -n ost.OSS.ost.stats)
24269         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
24270
24271         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24272         rc=$?
24273         if [ $rc -eq 255 ]; then
24274                 error "Ladvise test${i} failed, ${rc}"
24275         fi
24276
24277         new_count=$(do_facet ost1 \
24278                 $LCTL get_param -n ost.OSS.ost.stats)
24279         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
24280                    awk '{ print $2 }')
24281
24282         difference="$((new_count - count))"
24283         if [ $difference -ne $rc ]; then
24284                 error "Ladvise test${i}, bad enqueue count, returned " \
24285                       "${rc}, actual ${difference}"
24286         fi
24287
24288         for i in $(seq 12 21); do
24289                 # If we do not do this, we run the risk of having too many
24290                 # locks and starting lock cancellation while we are checking
24291                 # lock counts.
24292                 cancel_lru_locks osc
24293
24294                 count=$($LCTL get_param -n \
24295                        ldlm.namespaces.$imp_name.lock_unused_count)
24296
24297                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
24298                 rc=$?
24299                 if [ $rc -eq 255 ]; then
24300                         error "Ladvise test ${i} failed, ${rc}"
24301                 fi
24302
24303                 new_count=$($LCTL get_param -n \
24304                        ldlm.namespaces.$imp_name.lock_unused_count)
24305                 difference="$((new_count - count))"
24306
24307                 # Test 15 output is divided by 100 to map down to valid return
24308                 if [ $i -eq 15 ]; then
24309                         rc="$((rc * 100))"
24310                 fi
24311
24312                 if [ $difference -ne $rc ]; then
24313                         error "Ladvise test ${i}, bad lock count, returned " \
24314                               "${rc}, actual ${difference}"
24315                 fi
24316         done
24317
24318         #test 22 returns only success/failure
24319         i=22
24320         lockahead_test -d $DIR/$tdir -t $i -f $tfile
24321         rc=$?
24322         if [ $rc -eq 255 ]; then
24323                 error "Ladvise test${i} failed, ${rc}"
24324         fi
24325 }
24326 run_test 255c "suite of ladvise lockahead tests"
24327
24328 test_256() {
24329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24330         remote_mds_nodsh && skip "remote MDS with nodsh"
24331         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24332         changelog_users $SINGLEMDS | grep "^cl" &&
24333                 skip "active changelog user"
24334
24335         local cl_user
24336         local cat_sl
24337         local mdt_dev
24338
24339         mdt_dev=$(facet_device $SINGLEMDS)
24340         echo $mdt_dev
24341
24342         changelog_register || error "changelog_register failed"
24343
24344         rm -rf $DIR/$tdir
24345         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
24346
24347         changelog_clear 0 || error "changelog_clear failed"
24348
24349         # change something
24350         touch $DIR/$tdir/{1..10}
24351
24352         # stop the MDT
24353         stop $SINGLEMDS || error "Fail to stop MDT"
24354
24355         # remount the MDT
24356         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
24357                 error "Fail to start MDT"
24358
24359         #after mount new plainllog is used
24360         touch $DIR/$tdir/{11..19}
24361         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
24362         stack_trap "rm -f $tmpfile"
24363         cat_sl=$(do_facet $SINGLEMDS "sync; \
24364                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24365                  llog_reader $tmpfile | grep -c type=1064553b")
24366         do_facet $SINGLEMDS llog_reader $tmpfile
24367
24368         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
24369
24370         changelog_clear 0 || error "changelog_clear failed"
24371
24372         cat_sl=$(do_facet $SINGLEMDS "sync; \
24373                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
24374                  llog_reader $tmpfile | grep -c type=1064553b")
24375
24376         if (( cat_sl == 2 )); then
24377                 error "Empty plain llog was not deleted from changelog catalog"
24378         elif (( cat_sl != 1 )); then
24379                 error "Active plain llog shouldn't be deleted from catalog"
24380         fi
24381 }
24382 run_test 256 "Check llog delete for empty and not full state"
24383
24384 test_257() {
24385         remote_mds_nodsh && skip "remote MDS with nodsh"
24386         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
24387                 skip "Need MDS version at least 2.8.55"
24388
24389         test_mkdir $DIR/$tdir
24390
24391         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
24392                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
24393         stat $DIR/$tdir
24394
24395 #define OBD_FAIL_MDS_XATTR_REP                  0x161
24396         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
24397         local facet=mds$((mdtidx + 1))
24398         set_nodes_failloc $(facet_active_host $facet) 0x80000161
24399         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
24400
24401         stop $facet || error "stop MDS failed"
24402         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
24403                 error "start MDS fail"
24404         wait_recovery_complete $facet
24405 }
24406 run_test 257 "xattr locks are not lost"
24407
24408 # Verify we take the i_mutex when security requires it
24409 test_258a() {
24410 #define OBD_FAIL_IMUTEX_SEC 0x141c
24411         $LCTL set_param fail_loc=0x141c
24412         touch $DIR/$tfile
24413         chmod u+s $DIR/$tfile
24414         chmod a+rwx $DIR/$tfile
24415         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24416         RC=$?
24417         if [ $RC -ne 0 ]; then
24418                 error "error, failed to take i_mutex, rc=$?"
24419         fi
24420         rm -f $DIR/$tfile
24421 }
24422 run_test 258a "verify i_mutex security behavior when suid attributes is set"
24423
24424 # Verify we do NOT take the i_mutex in the normal case
24425 test_258b() {
24426 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
24427         $LCTL set_param fail_loc=0x141d
24428         touch $DIR/$tfile
24429         chmod a+rwx $DIR
24430         chmod a+rw $DIR/$tfile
24431         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
24432         RC=$?
24433         if [ $RC -ne 0 ]; then
24434                 error "error, took i_mutex unnecessarily, rc=$?"
24435         fi
24436         rm -f $DIR/$tfile
24437
24438 }
24439 run_test 258b "verify i_mutex security behavior"
24440
24441 test_259() {
24442         local file=$DIR/$tfile
24443         local before
24444         local after
24445
24446         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
24447
24448         stack_trap "rm -f $file" EXIT
24449
24450         wait_delete_completed
24451         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24452         echo "before: $before"
24453
24454         $LFS setstripe -i 0 -c 1 $file
24455         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
24456         sync_all_data
24457         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24458         echo "after write: $after"
24459
24460 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
24461         do_facet ost1 $LCTL set_param fail_loc=0x2301
24462         $TRUNCATE $file 0
24463         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24464         echo "after truncate: $after"
24465
24466         stop ost1
24467         do_facet ost1 $LCTL set_param fail_loc=0
24468         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
24469         sleep 2
24470         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
24471         echo "after restart: $after"
24472         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
24473                 error "missing truncate?"
24474
24475         return 0
24476 }
24477 run_test 259 "crash at delayed truncate"
24478
24479 test_260() {
24480 #define OBD_FAIL_MDC_CLOSE               0x806
24481         $LCTL set_param fail_loc=0x80000806
24482         touch $DIR/$tfile
24483
24484 }
24485 run_test 260 "Check mdc_close fail"
24486
24487 ### Data-on-MDT sanity tests ###
24488 test_270a() {
24489         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24490                 skip "Need MDS version at least 2.10.55 for DoM"
24491
24492         # create DoM file
24493         local dom=$DIR/$tdir/dom_file
24494         local tmp=$DIR/$tdir/tmp_file
24495
24496         mkdir_on_mdt0 $DIR/$tdir
24497
24498         # basic checks for DoM component creation
24499         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
24500                 error "Can set MDT layout to non-first entry"
24501
24502         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
24503                 error "Can define multiple entries as MDT layout"
24504
24505         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
24506
24507         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
24508         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
24509         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
24510
24511         local mdtidx=$($LFS getstripe -m $dom)
24512         local mdtname=MDT$(printf %04x $mdtidx)
24513         local facet=mds$((mdtidx + 1))
24514         local space_check=1
24515
24516         # Skip free space checks with ZFS
24517         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
24518
24519         # write
24520         sync
24521         local size_tmp=$((65536 * 3))
24522         local mdtfree1=$(do_facet $facet \
24523                          lctl get_param -n osd*.*$mdtname.kbytesfree)
24524
24525         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24526         # check also direct IO along write
24527         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
24528         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24529         sync
24530         cmp $tmp $dom || error "file data is different"
24531         [ $(stat -c%s $dom) == $size_tmp ] ||
24532                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24533         if [ $space_check == 1 ]; then
24534                 local mdtfree2=$(do_facet $facet \
24535                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
24536
24537                 # increase in usage from by $size_tmp
24538                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24539                         error "MDT free space wrong after write: " \
24540                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24541         fi
24542
24543         # truncate
24544         local size_dom=10000
24545
24546         $TRUNCATE $dom $size_dom
24547         [ $(stat -c%s $dom) == $size_dom ] ||
24548                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
24549         if [ $space_check == 1 ]; then
24550                 mdtfree1=$(do_facet $facet \
24551                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24552                 # decrease in usage from $size_tmp to new $size_dom
24553                 [ $(($mdtfree1 - $mdtfree2)) -ge \
24554                   $(((size_tmp - size_dom) / 1024)) ] ||
24555                         error "MDT free space is wrong after truncate: " \
24556                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
24557         fi
24558
24559         # append
24560         cat $tmp >> $dom
24561         sync
24562         size_dom=$((size_dom + size_tmp))
24563         [ $(stat -c%s $dom) == $size_dom ] ||
24564                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
24565         if [ $space_check == 1 ]; then
24566                 mdtfree2=$(do_facet $facet \
24567                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24568                 # increase in usage by $size_tmp from previous
24569                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
24570                         error "MDT free space is wrong after append: " \
24571                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
24572         fi
24573
24574         # delete
24575         rm $dom
24576         if [ $space_check == 1 ]; then
24577                 mdtfree1=$(do_facet $facet \
24578                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24579                 # decrease in usage by $size_dom from previous
24580                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
24581                         error "MDT free space is wrong after removal: " \
24582                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
24583         fi
24584
24585         # combined striping
24586         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
24587                 error "Can't create DoM + OST striping"
24588
24589         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
24590         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
24591         # check also direct IO along write
24592         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
24593         sync
24594         cmp $tmp $dom || error "file data is different"
24595         [ $(stat -c%s $dom) == $size_tmp ] ||
24596                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
24597         rm $dom $tmp
24598
24599         return 0
24600 }
24601 run_test 270a "DoM: basic functionality tests"
24602
24603 test_270b() {
24604         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24605                 skip "Need MDS version at least 2.10.55"
24606
24607         local dom=$DIR/$tdir/dom_file
24608         local max_size=1048576
24609
24610         mkdir -p $DIR/$tdir
24611         $LFS setstripe -E $max_size -L mdt $dom
24612
24613         # truncate over the limit
24614         $TRUNCATE $dom $(($max_size + 1)) &&
24615                 error "successful truncate over the maximum size"
24616         # write over the limit
24617         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
24618                 error "successful write over the maximum size"
24619         # append over the limit
24620         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
24621         echo "12345" >> $dom && error "successful append over the maximum size"
24622         rm $dom
24623
24624         return 0
24625 }
24626 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
24627
24628 test_270c() {
24629         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24630                 skip "Need MDS version at least 2.10.55"
24631
24632         mkdir -p $DIR/$tdir
24633         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24634
24635         # check files inherit DoM EA
24636         touch $DIR/$tdir/first
24637         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
24638                 error "bad pattern"
24639         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
24640                 error "bad stripe count"
24641         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
24642                 error "bad stripe size"
24643
24644         # check directory inherits DoM EA and uses it as default
24645         mkdir $DIR/$tdir/subdir
24646         touch $DIR/$tdir/subdir/second
24647         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
24648                 error "bad pattern in sub-directory"
24649         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
24650                 error "bad stripe count in sub-directory"
24651         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
24652                 error "bad stripe size in sub-directory"
24653         return 0
24654 }
24655 run_test 270c "DoM: DoM EA inheritance tests"
24656
24657 test_270d() {
24658         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24659                 skip "Need MDS version at least 2.10.55"
24660
24661         mkdir -p $DIR/$tdir
24662         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
24663
24664         # inherit default DoM striping
24665         mkdir $DIR/$tdir/subdir
24666         touch $DIR/$tdir/subdir/f1
24667
24668         # change default directory striping
24669         $LFS setstripe -c 1 $DIR/$tdir/subdir
24670         touch $DIR/$tdir/subdir/f2
24671         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
24672                 error "wrong default striping in file 2"
24673         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
24674                 error "bad pattern in file 2"
24675         return 0
24676 }
24677 run_test 270d "DoM: change striping from DoM to RAID0"
24678
24679 test_270e() {
24680         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24681                 skip "Need MDS version at least 2.10.55"
24682
24683         mkdir -p $DIR/$tdir/dom
24684         mkdir -p $DIR/$tdir/norm
24685         DOMFILES=20
24686         NORMFILES=10
24687         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
24688         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
24689
24690         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
24691         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
24692
24693         # find DoM files by layout
24694         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
24695         [ $NUM -eq  $DOMFILES ] ||
24696                 error "lfs find -L: found $NUM, expected $DOMFILES"
24697         echo "Test 1: lfs find 20 DOM files by layout: OK"
24698
24699         # there should be 1 dir with default DOM striping
24700         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
24701         [ $NUM -eq  1 ] ||
24702                 error "lfs find -L: found $NUM, expected 1 dir"
24703         echo "Test 2: lfs find 1 DOM dir by layout: OK"
24704
24705         # find DoM files by stripe size
24706         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
24707         [ $NUM -eq  $DOMFILES ] ||
24708                 error "lfs find -S: found $NUM, expected $DOMFILES"
24709         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
24710
24711         # find files by stripe offset except DoM files
24712         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
24713         [ $NUM -eq  $NORMFILES ] ||
24714                 error "lfs find -i: found $NUM, expected $NORMFILES"
24715         echo "Test 5: lfs find no DOM files by stripe index: OK"
24716         return 0
24717 }
24718 run_test 270e "DoM: lfs find with DoM files test"
24719
24720 test_270f() {
24721         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24722                 skip "Need MDS version at least 2.10.55"
24723
24724         local mdtname=${FSNAME}-MDT0000-mdtlov
24725         local dom=$DIR/$tdir/dom_file
24726         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
24727                                                 lod.$mdtname.dom_stripesize)
24728         local dom_limit=131072
24729
24730         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
24731         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24732                                                 lod.$mdtname.dom_stripesize)
24733         [ ${dom_limit} -eq ${dom_current} ] ||
24734                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
24735
24736         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24737         $LFS setstripe -d $DIR/$tdir
24738         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
24739                 error "Can't set directory default striping"
24740
24741         # exceed maximum stripe size
24742         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24743                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
24744         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
24745                 error "Able to create DoM component size more than LOD limit"
24746
24747         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24748         dom_current=$(do_facet mds1 $LCTL get_param -n \
24749                                                 lod.$mdtname.dom_stripesize)
24750         [ 0 -eq ${dom_current} ] ||
24751                 error "Can't set zero DoM stripe limit"
24752         rm $dom
24753
24754         # attempt to create DoM file on server with disabled DoM should
24755         # remove DoM entry from layout and be succeed
24756         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
24757                 error "Can't create DoM file (DoM is disabled)"
24758         [ $($LFS getstripe -L $dom) == "mdt" ] &&
24759                 error "File has DoM component while DoM is disabled"
24760         rm $dom
24761
24762         # attempt to create DoM file with only DoM stripe should return error
24763         $LFS setstripe -E $dom_limit -L mdt $dom &&
24764                 error "Able to create DoM-only file while DoM is disabled"
24765
24766         # too low values to be aligned with smallest stripe size 64K
24767         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
24768         dom_current=$(do_facet mds1 $LCTL get_param -n \
24769                                                 lod.$mdtname.dom_stripesize)
24770         [ 30000 -eq ${dom_current} ] &&
24771                 error "Can set too small DoM stripe limit"
24772
24773         # 64K is a minimal stripe size in Lustre, expect limit of that size
24774         [ 65536 -eq ${dom_current} ] ||
24775                 error "Limit is not set to 64K but ${dom_current}"
24776
24777         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
24778         dom_current=$(do_facet mds1 $LCTL get_param -n \
24779                                                 lod.$mdtname.dom_stripesize)
24780         echo $dom_current
24781         [ 2147483648 -eq ${dom_current} ] &&
24782                 error "Can set too large DoM stripe limit"
24783
24784         do_facet mds1 $LCTL set_param -n \
24785                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
24786         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
24787                 error "Can't create DoM component size after limit change"
24788         do_facet mds1 $LCTL set_param -n \
24789                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
24790         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
24791                 error "Can't create DoM file after limit decrease"
24792         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
24793                 error "Can create big DoM component after limit decrease"
24794         touch ${dom}_def ||
24795                 error "Can't create file with old default layout"
24796
24797         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
24798         return 0
24799 }
24800 run_test 270f "DoM: maximum DoM stripe size checks"
24801
24802 test_270g() {
24803         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
24804                 skip "Need MDS version at least 2.13.52"
24805         local dom=$DIR/$tdir/$tfile
24806
24807         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24808         local lodname=${FSNAME}-MDT0000-mdtlov
24809
24810         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24811         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
24812         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
24813         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24814
24815         local dom_limit=1024
24816         local dom_threshold="50%"
24817
24818         $LFS setstripe -d $DIR/$tdir
24819         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
24820                 error "Can't set directory default striping"
24821
24822         do_facet mds1 $LCTL set_param -n \
24823                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
24824         # set 0 threshold and create DOM file to change tunable stripesize
24825         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
24826         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24827                 error "Failed to create $dom file"
24828         # now tunable dom_cur_stripesize should reach maximum
24829         local dom_current=$(do_facet mds1 $LCTL get_param -n \
24830                                         lod.${lodname}.dom_stripesize_cur_kb)
24831         [[ $dom_current == $dom_limit ]] ||
24832                 error "Current DOM stripesize is not maximum"
24833         rm $dom
24834
24835         # set threshold for further tests
24836         do_facet mds1 $LCTL set_param -n \
24837                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
24838         echo "DOM threshold is $dom_threshold free space"
24839         local dom_def
24840         local dom_set
24841         # Spoof bfree to exceed threshold
24842         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
24843         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
24844         for spfree in 40 20 0 15 30 55; do
24845                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
24846                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
24847                         error "Failed to create $dom file"
24848                 dom_def=$(do_facet mds1 $LCTL get_param -n \
24849                                         lod.${lodname}.dom_stripesize_cur_kb)
24850                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
24851                 [[ $dom_def != $dom_current ]] ||
24852                         error "Default stripe size was not changed"
24853                 if (( spfree > 0 )) ; then
24854                         dom_set=$($LFS getstripe -S $dom)
24855                         (( dom_set == dom_def * 1024 )) ||
24856                                 error "DOM component size is still old"
24857                 else
24858                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24859                                 error "DoM component is set with no free space"
24860                 fi
24861                 rm $dom
24862                 dom_current=$dom_def
24863         done
24864 }
24865 run_test 270g "DoM: default DoM stripe size depends on free space"
24866
24867 test_270h() {
24868         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
24869                 skip "Need MDS version at least 2.13.53"
24870
24871         local mdtname=${FSNAME}-MDT0000-mdtlov
24872         local dom=$DIR/$tdir/$tfile
24873         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
24874
24875         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
24876         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
24877
24878         $LFS mkdir -i 0 -c 1 $DIR/$tdir
24879         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
24880                 error "can't create OST file"
24881         # mirrored file with DOM entry in the second mirror
24882         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
24883                 error "can't create mirror with DoM component"
24884
24885         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
24886
24887         # DOM component in the middle and has other enries in the same mirror,
24888         # should succeed but lost DoM component
24889         $LFS setstripe --copy=${dom}_1 $dom ||
24890                 error "Can't create file from OST|DOM mirror layout"
24891         # check new file has no DoM layout after all
24892         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
24893                 error "File has DoM component while DoM is disabled"
24894 }
24895 run_test 270h "DoM: DoM stripe removal when disabled on server"
24896
24897 test_270i() {
24898         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
24899                 skip "Need MDS version at least 2.14.54"
24900
24901         mkdir $DIR/$tdir
24902         # DoM with plain layout
24903         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
24904                 error "default plain layout with DoM must fail"
24905         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
24906                 error "setstripe plain file layout with DoM must fail"
24907         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
24908                 error "default DoM layout with bad striping must fail"
24909         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
24910                 error "setstripe to DoM layout with bad striping must fail"
24911         return 0
24912 }
24913 run_test 270i "DoM: setting invalid DoM striping should fail"
24914
24915 test_270j() {
24916         (( $MDS1_VERSION >= $(version_code 2.15.55.203) )) ||
24917                 skip "Need MDS version at least 2.15.55.203"
24918
24919         local dom=$DIR/$tdir/$tfile
24920         local odv
24921         local ndv
24922
24923         mkdir -p $DIR/$tdir
24924
24925         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24926
24927         odv=$($LFS data_version $dom)
24928         chmod 666 $dom
24929         mv $dom ${dom}_moved
24930         link ${dom}_moved $dom
24931         setfattr -n user.attrx -v "some_attr" $dom
24932         ndv=$($LFS data_version $dom)
24933         (( $ndv == $odv )) ||
24934                 error "data version was changed by metadata operations"
24935
24936         dd if=/dev/urandom of=$dom bs=1M count=1 ||
24937                 error "failed to write data into $dom"
24938         cancel_lru_locks mdc
24939         ndv=$($LFS data_version $dom)
24940         (( $ndv != $odv )) ||
24941                 error "data version wasn't changed on write"
24942
24943         odv=$ndv
24944         $TRUNCATE $dom 1000 || error "failed to truncate $dom"
24945         ndv=$($LFS data_version $dom)
24946         (( $ndv != $odv )) ||
24947                 error "data version wasn't changed on truncate down"
24948
24949         odv=$ndv
24950         $TRUNCATE $dom 25000
24951         ndv=$($LFS data_version $dom)
24952         (( $ndv != $odv )) ||
24953                 error "data version wasn't changed on truncate up"
24954
24955         # check also fallocate for ldiskfs
24956         if [[ "$mds1_FSTYPE" == ldiskfs ]]; then
24957                 odv=$ndv
24958                 fallocate -l 1048576 $dom
24959                 ndv=$($LFS data_version $dom)
24960                 (( $ndv != $odv )) ||
24961                         error "data version wasn't changed on fallocate"
24962
24963                 odv=$ndv
24964                 fallocate -p --offset 4096 -l 4096 $dom
24965                 ndv=$($LFS data_version $dom)
24966                 (( $ndv != $odv )) ||
24967                         error "data version wasn't changed on fallocate punch"
24968         fi
24969 }
24970 run_test 270j "DoM migration: DOM file to the OST-striped file (plain)"
24971
24972 test_271a() {
24973         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24974                 skip "Need MDS version at least 2.10.55"
24975
24976         local dom=$DIR/$tdir/dom
24977
24978         mkdir -p $DIR/$tdir
24979
24980         $LFS setstripe -E 1024K -L mdt $dom
24981
24982         lctl set_param -n mdc.*.stats=clear
24983         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
24984         cat $dom > /dev/null
24985         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
24986         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
24987         ls $dom
24988         rm -f $dom
24989 }
24990 run_test 271a "DoM: data is cached for read after write"
24991
24992 test_271b() {
24993         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
24994                 skip "Need MDS version at least 2.10.55"
24995
24996         local dom=$DIR/$tdir/dom
24997
24998         mkdir -p $DIR/$tdir
24999
25000         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25001
25002         lctl set_param -n mdc.*.stats=clear
25003         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
25004         cancel_lru_locks mdc
25005         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
25006         # second stat to check size is cached on client
25007         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
25008         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25009         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
25010         rm -f $dom
25011 }
25012 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
25013
25014 test_271ba() {
25015         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25016                 skip "Need MDS version at least 2.10.55"
25017
25018         local dom=$DIR/$tdir/dom
25019
25020         mkdir -p $DIR/$tdir
25021
25022         $LFS setstripe -E 1024K -L mdt -E EOF $dom
25023
25024         lctl set_param -n mdc.*.stats=clear
25025         lctl set_param -n osc.*.stats=clear
25026         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
25027         cancel_lru_locks mdc
25028         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25029         # second stat to check size is cached on client
25030         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
25031         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
25032         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
25033         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
25034         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
25035         rm -f $dom
25036 }
25037 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
25038
25039
25040 get_mdc_stats() {
25041         local mdtidx=$1
25042         local param=$2
25043         local mdt=MDT$(printf %04x $mdtidx)
25044
25045         if [ -z $param ]; then
25046                 lctl get_param -n mdc.*$mdt*.stats
25047         else
25048                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
25049         fi
25050 }
25051
25052 test_271c() {
25053         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
25054                 skip "Need MDS version at least 2.10.55"
25055
25056         local dom=$DIR/$tdir/dom
25057
25058         mkdir -p $DIR/$tdir
25059
25060         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25061
25062         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
25063         local facet=mds$((mdtidx + 1))
25064
25065         cancel_lru_locks mdc
25066         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
25067         createmany -o $dom 1000
25068         lctl set_param -n mdc.*.stats=clear
25069         smalliomany -w $dom 1000 200
25070         get_mdc_stats $mdtidx
25071         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25072         # Each file has 1 open, 1 IO enqueues, total 2000
25073         # but now we have also +1 getxattr for security.capability, total 3000
25074         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
25075         unlinkmany $dom 1000
25076
25077         cancel_lru_locks mdc
25078         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
25079         createmany -o $dom 1000
25080         lctl set_param -n mdc.*.stats=clear
25081         smalliomany -w $dom 1000 200
25082         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
25083         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
25084         # for OPEN and IO lock.
25085         [ $((enq - enq_2)) -ge 1000 ] ||
25086                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
25087         unlinkmany $dom 1000
25088         return 0
25089 }
25090 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
25091
25092 cleanup_271def_tests() {
25093         trap 0
25094         rm -f $1
25095 }
25096
25097 test_271d() {
25098         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25099                 skip "Need MDS version at least 2.10.57"
25100
25101         local dom=$DIR/$tdir/dom
25102         local tmp=$TMP/$tfile
25103         trap "cleanup_271def_tests $tmp" EXIT
25104
25105         mkdir -p $DIR/$tdir
25106
25107         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25108
25109         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25110
25111         cancel_lru_locks mdc
25112         dd if=/dev/urandom of=$tmp bs=1000 count=1
25113         dd if=$tmp of=$dom bs=1000 count=1
25114         cancel_lru_locks mdc
25115
25116         cat /etc/hosts >> $tmp
25117         lctl set_param -n mdc.*.stats=clear
25118
25119         # append data to the same file it should update local page
25120         echo "Append to the same page"
25121         cat /etc/hosts >> $dom
25122         local num=$(get_mdc_stats $mdtidx ost_read)
25123         local ra=$(get_mdc_stats $mdtidx req_active)
25124         local rw=$(get_mdc_stats $mdtidx req_waittime)
25125
25126         [ -z $num ] || error "$num READ RPC occured"
25127         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25128         echo "... DONE"
25129
25130         # compare content
25131         cmp $tmp $dom || error "file miscompare"
25132
25133         cancel_lru_locks mdc
25134         lctl set_param -n mdc.*.stats=clear
25135
25136         echo "Open and read file"
25137         cat $dom > /dev/null
25138         local num=$(get_mdc_stats $mdtidx ost_read)
25139         local ra=$(get_mdc_stats $mdtidx req_active)
25140         local rw=$(get_mdc_stats $mdtidx req_waittime)
25141
25142         [ -z $num ] || error "$num READ RPC occured"
25143         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25144         echo "... DONE"
25145
25146         # compare content
25147         cmp $tmp $dom || error "file miscompare"
25148
25149         return 0
25150 }
25151 run_test 271d "DoM: read on open (1K file in reply buffer)"
25152
25153 test_271f() {
25154         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
25155                 skip "Need MDS version at least 2.10.57"
25156
25157         local dom=$DIR/$tdir/dom
25158         local tmp=$TMP/$tfile
25159         trap "cleanup_271def_tests $tmp" EXIT
25160
25161         mkdir -p $DIR/$tdir
25162
25163         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
25164
25165         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
25166
25167         cancel_lru_locks mdc
25168         dd if=/dev/urandom of=$tmp bs=265000 count=1
25169         dd if=$tmp of=$dom bs=265000 count=1
25170         cancel_lru_locks mdc
25171         cat /etc/hosts >> $tmp
25172         lctl set_param -n mdc.*.stats=clear
25173
25174         echo "Append to the same page"
25175         cat /etc/hosts >> $dom
25176         local num=$(get_mdc_stats $mdtidx ost_read)
25177         local ra=$(get_mdc_stats $mdtidx req_active)
25178         local rw=$(get_mdc_stats $mdtidx req_waittime)
25179
25180         [ -z $num ] || error "$num READ RPC occured"
25181         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25182         echo "... DONE"
25183
25184         # compare content
25185         cmp $tmp $dom || error "file miscompare"
25186
25187         cancel_lru_locks mdc
25188         lctl set_param -n mdc.*.stats=clear
25189
25190         echo "Open and read file"
25191         cat $dom > /dev/null
25192         local num=$(get_mdc_stats $mdtidx ost_read)
25193         local ra=$(get_mdc_stats $mdtidx req_active)
25194         local rw=$(get_mdc_stats $mdtidx req_waittime)
25195
25196         [ -z $num ] && num=0
25197         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
25198         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
25199         echo "... DONE"
25200
25201         # compare content
25202         cmp $tmp $dom || error "file miscompare"
25203
25204         return 0
25205 }
25206 run_test 271f "DoM: read on open (200K file and read tail)"
25207
25208 test_271g() {
25209         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
25210                 skip "Skipping due to old client or server version"
25211
25212         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
25213         # to get layout
25214         $CHECKSTAT -t file $DIR1/$tfile
25215
25216         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
25217         MULTIOP_PID=$!
25218         sleep 1
25219         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
25220         $LCTL set_param fail_loc=0x80000314
25221         rm $DIR1/$tfile || error "Unlink fails"
25222         RC=$?
25223         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
25224         [ $RC -eq 0 ] || error "Failed write to stale object"
25225 }
25226 run_test 271g "Discard DoM data vs client flush race"
25227
25228 test_272a() {
25229         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25230                 skip "Need MDS version at least 2.11.50"
25231
25232         local dom=$DIR/$tdir/dom
25233         mkdir -p $DIR/$tdir
25234
25235         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
25236         dd if=/dev/urandom of=$dom bs=512K count=1 ||
25237                 error "failed to write data into $dom"
25238         local old_md5=$(md5sum $dom)
25239
25240         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
25241                 error "failed to migrate to the same DoM component"
25242
25243         local new_md5=$(md5sum $dom)
25244
25245         [ "$old_md5" == "$new_md5" ] ||
25246                 error "md5sum differ: $old_md5, $new_md5"
25247
25248         [ $($LFS getstripe -c $dom) -eq 2 ] ||
25249                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
25250 }
25251 run_test 272a "DoM migration: new layout with the same DOM component"
25252
25253 test_272b() {
25254         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25255                 skip "Need MDS version at least 2.11.50"
25256
25257         local dom=$DIR/$tdir/dom
25258         mkdir -p $DIR/$tdir
25259         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25260         stack_trap "rm -rf $DIR/$tdir"
25261
25262         local mdtidx=$($LFS getstripe -m $dom)
25263         local mdtname=MDT$(printf %04x $mdtidx)
25264         local facet=mds$((mdtidx + 1))
25265
25266         local mdtfree1=$(do_facet $facet \
25267                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25268         dd if=/dev/urandom of=$dom bs=2M count=1 ||
25269                 error "failed to write data into $dom"
25270         local old_md5=$(md5sum $dom)
25271         cancel_lru_locks mdc
25272         local mdtfree1=$(do_facet $facet \
25273                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25274
25275         $LFS migrate -c2 $dom ||
25276                 error "failed to migrate to the new composite layout"
25277         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25278                 error "MDT stripe was not removed"
25279         ! getfattr -n trusted.dataver $dom &> /dev/null ||
25280                 error "$dir1 shouldn't have DATAVER EA"
25281
25282         cancel_lru_locks mdc
25283         local new_md5=$(md5sum $dom)
25284         [ "$old_md5" == "$new_md5" ] ||
25285                 error "$old_md5 != $new_md5"
25286
25287         # Skip free space checks with ZFS
25288         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25289                 local mdtfree2=$(do_facet $facet \
25290                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25291                 [ $mdtfree2 -gt $mdtfree1 ] ||
25292                         error "MDT space is not freed after migration"
25293         fi
25294         return 0
25295 }
25296 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
25297
25298 test_272c() {
25299         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25300                 skip "Need MDS version at least 2.11.50"
25301
25302         local dom=$DIR/$tdir/$tfile
25303         mkdir -p $DIR/$tdir
25304         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25305         stack_trap "rm -rf $DIR/$tdir"
25306
25307         local mdtidx=$($LFS getstripe -m $dom)
25308         local mdtname=MDT$(printf %04x $mdtidx)
25309         local facet=mds$((mdtidx + 1))
25310
25311         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25312                 error "failed to write data into $dom"
25313         local old_md5=$(md5sum $dom)
25314         cancel_lru_locks mdc
25315         local mdtfree1=$(do_facet $facet \
25316                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25317
25318         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
25319                 error "failed to migrate to the new composite layout"
25320         [[ $($LFS getstripe --component-start=0 -L $dom) != 'mdt' ]] ||
25321                 error "MDT stripe was not removed"
25322
25323         cancel_lru_locks mdc
25324         local new_md5=$(md5sum $dom)
25325         [ "$old_md5" == "$new_md5" ] ||
25326                 error "$old_md5 != $new_md5"
25327
25328         # Skip free space checks with ZFS
25329         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25330                 local mdtfree2=$(do_facet $facet \
25331                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25332                 [ $mdtfree2 -gt $mdtfree1 ] ||
25333                         error "MDS space is not freed after migration"
25334         fi
25335         return 0
25336 }
25337 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
25338
25339 test_272d() {
25340         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25341                 skip "Need MDS version at least 2.12.55"
25342
25343         local dom=$DIR/$tdir/$tfile
25344         mkdir -p $DIR/$tdir
25345         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
25346
25347         local mdtidx=$($LFS getstripe -m $dom)
25348         local mdtname=MDT$(printf %04x $mdtidx)
25349         local facet=mds$((mdtidx + 1))
25350
25351         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25352                 error "failed to write data into $dom"
25353         local old_md5=$(md5sum $dom)
25354         cancel_lru_locks mdc
25355         local mdtfree1=$(do_facet $facet \
25356                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25357
25358         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
25359                 error "failed mirroring to the new composite layout"
25360         $LFS mirror resync $dom ||
25361                 error "failed mirror resync"
25362         $LFS mirror split --mirror-id 1 -d $dom ||
25363                 error "failed mirror split"
25364
25365         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
25366                 error "MDT stripe was not removed"
25367
25368         cancel_lru_locks mdc
25369         local new_md5=$(md5sum $dom)
25370         [ "$old_md5" == "$new_md5" ] ||
25371                 error "$old_md5 != $new_md5"
25372
25373         # Skip free space checks with ZFS
25374         if [ "$(facet_fstype $facet)" != "zfs" ]; then
25375                 local mdtfree2=$(do_facet $facet \
25376                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
25377                 [ $mdtfree2 -gt $mdtfree1 ] ||
25378                         error "MDS space is not freed after DOM mirror deletion"
25379         fi
25380         return 0
25381 }
25382 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
25383
25384 test_272e() {
25385         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25386                 skip "Need MDS version at least 2.12.55"
25387
25388         local dom=$DIR/$tdir/$tfile
25389         mkdir -p $DIR/$tdir
25390         $LFS setstripe -c 2 $dom
25391
25392         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25393                 error "failed to write data into $dom"
25394         local old_md5=$(md5sum $dom)
25395         cancel_lru_locks
25396
25397         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
25398                 error "failed mirroring to the DOM layout"
25399         $LFS mirror resync $dom ||
25400                 error "failed mirror resync"
25401         $LFS mirror split --mirror-id 1 -d $dom ||
25402                 error "failed mirror split"
25403
25404         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25405                 error "MDT stripe wasn't set"
25406
25407         cancel_lru_locks
25408         local new_md5=$(md5sum $dom)
25409         [ "$old_md5" == "$new_md5" ] ||
25410                 error "$old_md5 != $new_md5"
25411
25412         return 0
25413 }
25414 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
25415
25416 test_272f() {
25417         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
25418                 skip "Need MDS version at least 2.12.55"
25419
25420         local dom=$DIR/$tdir/$tfile
25421         mkdir -p $DIR/$tdir
25422         $LFS setstripe -c 2 $dom
25423
25424         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
25425                 error "failed to write data into $dom"
25426         local old_md5=$(md5sum $dom)
25427         cancel_lru_locks
25428
25429         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
25430                 error "failed migrating to the DOM file"
25431
25432         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
25433                 error "MDT stripe wasn't set"
25434
25435         cancel_lru_locks
25436         local new_md5=$(md5sum $dom)
25437         [ "$old_md5" != "$new_md5" ] &&
25438                 error "$old_md5 != $new_md5"
25439
25440         return 0
25441 }
25442 run_test 272f "DoM migration: OST-striped file to DOM file"
25443
25444 test_273a() {
25445         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
25446                 skip "Need MDS version at least 2.11.50"
25447
25448         # Layout swap cannot be done if either file has DOM component,
25449         # this will never be supported, migration should be used instead
25450
25451         local dom=$DIR/$tdir/$tfile
25452         mkdir -p $DIR/$tdir
25453
25454         $LFS setstripe -c2 ${dom}_plain
25455         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
25456         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
25457                 error "can swap layout with DoM component"
25458         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
25459                 error "can swap layout with DoM component"
25460
25461         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
25462         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
25463                 error "can swap layout with DoM component"
25464         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
25465                 error "can swap layout with DoM component"
25466         return 0
25467 }
25468 run_test 273a "DoM: layout swapping should fail with DOM"
25469
25470 test_273b() {
25471         mkdir -p $DIR/$tdir
25472         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
25473
25474 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
25475         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
25476
25477         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25478 }
25479 run_test 273b "DoM: race writeback and object destroy"
25480
25481 test_273c() {
25482         mkdir -p $DIR/$tdir
25483         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
25484
25485         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
25486         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
25487
25488         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
25489 }
25490 run_test 273c "race writeback and object destroy"
25491
25492 test_275() {
25493         remote_ost_nodsh && skip "remote OST with nodsh"
25494         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
25495                 skip "Need OST version >= 2.10.57"
25496
25497         local file=$DIR/$tfile
25498         local oss
25499
25500         oss=$(comma_list $(osts_nodes))
25501
25502         dd if=/dev/urandom of=$file bs=1M count=2 ||
25503                 error "failed to create a file"
25504         stack_trap "rm -f $file"
25505         cancel_lru_locks osc
25506
25507         #lock 1
25508         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25509                 error "failed to read a file"
25510
25511 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
25512         $LCTL set_param fail_loc=0x8000031f
25513
25514         cancel_lru_locks osc &
25515         sleep 1
25516
25517 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
25518         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
25519         #IO takes another lock, but matches the PENDING one
25520         #and places it to the IO RPC
25521         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
25522                 error "failed to read a file with PENDING lock"
25523 }
25524 run_test 275 "Read on a canceled duplicate lock"
25525
25526 test_276() {
25527         remote_ost_nodsh && skip "remote OST with nodsh"
25528         local pid
25529
25530         do_facet ost1 "(while true; do \
25531                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
25532                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
25533         pid=$!
25534
25535         for LOOP in $(seq 20); do
25536                 stop ost1
25537                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
25538         done
25539         kill -9 $pid
25540         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
25541                 rm $TMP/sanity_276_pid"
25542 }
25543 run_test 276 "Race between mount and obd_statfs"
25544
25545 test_277() {
25546         $LCTL set_param ldlm.namespaces.*.lru_size=0
25547         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25548         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25549                           awk '/^used_mb/ { print $2 }')
25550         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
25551         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
25552                 oflag=direct conv=notrunc
25553         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
25554                     awk '/^used_mb/ { print $2 }')
25555         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
25556 }
25557 run_test 277 "Direct IO shall drop page cache"
25558
25559 test_278() {
25560         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
25561         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25562         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
25563                 skip "needs the same host for mdt1 mdt2" && return
25564
25565         local pid1
25566         local pid2
25567
25568 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
25569         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
25570         stop mds2 &
25571         pid2=$!
25572
25573         stop mds1
25574
25575         echo "Starting MDTs"
25576         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
25577         wait $pid2
25578 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
25579 #will return NULL
25580         do_facet mds2 $LCTL set_param fail_loc=0
25581
25582         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
25583         wait_recovery_complete mds2
25584 }
25585 run_test 278 "Race starting MDS between MDTs stop/start"
25586
25587 test_280() {
25588         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
25589                 skip "Need MGS version at least 2.13.52"
25590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25591         combined_mgs_mds || skip "needs combined MGS/MDT"
25592
25593         umount_client $MOUNT
25594 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
25595         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
25596
25597         mount_client $MOUNT &
25598         sleep 1
25599         stop mgs || error "stop mgs failed"
25600         #for a race mgs would crash
25601         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
25602         # make sure we unmount client before remounting
25603         wait
25604         umount_client $MOUNT
25605         mount_client $MOUNT || error "mount client failed"
25606 }
25607 run_test 280 "Race between MGS umount and client llog processing"
25608
25609 cleanup_test_300() {
25610         trap 0
25611         umask $SAVE_UMASK
25612 }
25613 test_striped_dir() {
25614         local mdt_index=$1
25615         local stripe_count
25616         local stripe_index
25617
25618         mkdir -p $DIR/$tdir
25619
25620         SAVE_UMASK=$(umask)
25621         trap cleanup_test_300 RETURN EXIT
25622
25623         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
25624                                                 $DIR/$tdir/striped_dir ||
25625                 error "set striped dir error"
25626
25627         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
25628         [ "$mode" = "755" ] || error "expect 755 got $mode"
25629
25630         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
25631                 error "getdirstripe failed"
25632         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
25633         if [ "$stripe_count" != "2" ]; then
25634                 error "1:stripe_count is $stripe_count, expect 2"
25635         fi
25636         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
25637         if [ "$stripe_count" != "2" ]; then
25638                 error "2:stripe_count is $stripe_count, expect 2"
25639         fi
25640
25641         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
25642         if [ "$stripe_index" != "$mdt_index" ]; then
25643                 error "stripe_index is $stripe_index, expect $mdt_index"
25644         fi
25645
25646         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25647                 error "nlink error after create striped dir"
25648
25649         mkdir $DIR/$tdir/striped_dir/a
25650         mkdir $DIR/$tdir/striped_dir/b
25651
25652         stat $DIR/$tdir/striped_dir/a ||
25653                 error "create dir under striped dir failed"
25654         stat $DIR/$tdir/striped_dir/b ||
25655                 error "create dir under striped dir failed"
25656
25657         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
25658                 error "nlink error after mkdir"
25659
25660         rmdir $DIR/$tdir/striped_dir/a
25661         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
25662                 error "nlink error after rmdir"
25663
25664         rmdir $DIR/$tdir/striped_dir/b
25665         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
25666                 error "nlink error after rmdir"
25667
25668         chattr +i $DIR/$tdir/striped_dir
25669         createmany -o $DIR/$tdir/striped_dir/f 10 &&
25670                 error "immutable flags not working under striped dir!"
25671         chattr -i $DIR/$tdir/striped_dir
25672
25673         rmdir $DIR/$tdir/striped_dir ||
25674                 error "rmdir striped dir error"
25675
25676         cleanup_test_300
25677
25678         true
25679 }
25680
25681 test_300a() {
25682         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25683                 skip "skipped for lustre < 2.7.0"
25684         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25685         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25686
25687         test_striped_dir 0 || error "failed on striped dir on MDT0"
25688         test_striped_dir 1 || error "failed on striped dir on MDT0"
25689 }
25690 run_test 300a "basic striped dir sanity test"
25691
25692 test_300b() {
25693         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25694                 skip "skipped for lustre < 2.7.0"
25695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25696         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25697
25698         local i
25699         local mtime1
25700         local mtime2
25701         local mtime3
25702
25703         test_mkdir $DIR/$tdir || error "mkdir fail"
25704         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25705                 error "set striped dir error"
25706         for i in {0..9}; do
25707                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
25708                 sleep 1
25709                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
25710                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
25711                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
25712                 sleep 1
25713                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
25714                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
25715                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
25716         done
25717         true
25718 }
25719 run_test 300b "check ctime/mtime for striped dir"
25720
25721 test_300c() {
25722         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25723                 skip "skipped for lustre < 2.7.0"
25724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25725         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25726
25727         local file_count
25728
25729         mkdir_on_mdt0 $DIR/$tdir
25730         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
25731                 error "set striped dir error"
25732
25733         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
25734                 error "chown striped dir failed"
25735
25736         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
25737                 error "create 5k files failed"
25738
25739         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
25740
25741         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
25742
25743         rm -rf $DIR/$tdir
25744 }
25745 run_test 300c "chown && check ls under striped directory"
25746
25747 test_300d() {
25748         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
25749                 skip "skipped for lustre < 2.7.0"
25750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25751         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25752
25753         local stripe_count
25754         local file
25755
25756         mkdir -p $DIR/$tdir
25757         $LFS setstripe -c 2 $DIR/$tdir
25758
25759         #local striped directory
25760         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25761                 error "set striped dir error"
25762         #look at the directories for debug purposes
25763         ls -l $DIR/$tdir
25764         $LFS getdirstripe $DIR/$tdir
25765         ls -l $DIR/$tdir/striped_dir
25766         $LFS getdirstripe $DIR/$tdir/striped_dir
25767         createmany -o $DIR/$tdir/striped_dir/f 10 ||
25768                 error "create 10 files failed"
25769
25770         #remote striped directory
25771         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
25772                 error "set striped dir error"
25773         #look at the directories for debug purposes
25774         ls -l $DIR/$tdir
25775         $LFS getdirstripe $DIR/$tdir
25776         ls -l $DIR/$tdir/remote_striped_dir
25777         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
25778         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
25779                 error "create 10 files failed"
25780
25781         for file in $(find $DIR/$tdir); do
25782                 stripe_count=$($LFS getstripe -c $file)
25783                 [ $stripe_count -eq 2 ] ||
25784                         error "wrong stripe $stripe_count for $file"
25785         done
25786
25787         rm -rf $DIR/$tdir
25788 }
25789 run_test 300d "check default stripe under striped directory"
25790
25791 test_300e() {
25792         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25793                 skip "Need MDS version at least 2.7.55"
25794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25795         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25796
25797         local stripe_count
25798         local file
25799
25800         mkdir -p $DIR/$tdir
25801
25802         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25803                 error "set striped dir error"
25804
25805         touch $DIR/$tdir/striped_dir/a
25806         touch $DIR/$tdir/striped_dir/b
25807         touch $DIR/$tdir/striped_dir/c
25808
25809         mkdir $DIR/$tdir/striped_dir/dir_a
25810         mkdir $DIR/$tdir/striped_dir/dir_b
25811         mkdir $DIR/$tdir/striped_dir/dir_c
25812
25813         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
25814                 error "set striped adir under striped dir error"
25815
25816         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
25817                 error "set striped bdir under striped dir error"
25818
25819         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
25820                 error "set striped cdir under striped dir error"
25821
25822         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
25823                 error "rename dir under striped dir fails"
25824
25825         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
25826                 error "rename dir under different stripes fails"
25827
25828         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
25829                 error "rename file under striped dir should succeed"
25830
25831         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
25832                 error "rename dir under striped dir should succeed"
25833
25834         rm -rf $DIR/$tdir
25835 }
25836 run_test 300e "check rename under striped directory"
25837
25838 test_300f() {
25839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25840         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25841         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25842                 skip "Need MDS version at least 2.7.55"
25843
25844         local stripe_count
25845         local file
25846
25847         rm -rf $DIR/$tdir
25848         mkdir -p $DIR/$tdir
25849
25850         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
25851                 error "set striped dir error"
25852
25853         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
25854                 error "set striped dir error"
25855
25856         touch $DIR/$tdir/striped_dir/a
25857         mkdir $DIR/$tdir/striped_dir/dir_a
25858         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
25859                 error "create striped dir under striped dir fails"
25860
25861         touch $DIR/$tdir/striped_dir1/b
25862         mkdir $DIR/$tdir/striped_dir1/dir_b
25863         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
25864                 error "create striped dir under striped dir fails"
25865
25866         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
25867                 error "rename dir under different striped dir should fail"
25868
25869         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
25870                 error "rename striped dir under diff striped dir should fail"
25871
25872         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
25873                 error "rename file under diff striped dirs fails"
25874
25875         rm -rf $DIR/$tdir
25876 }
25877 run_test 300f "check rename cross striped directory"
25878
25879 test_300_check_default_striped_dir()
25880 {
25881         local dirname=$1
25882         local default_count=$2
25883         local default_index=$3
25884         local stripe_count
25885         local stripe_index
25886         local dir_stripe_index
25887         local dir
25888
25889         echo "checking $dirname $default_count $default_index"
25890         $LFS setdirstripe -D -c $default_count -i $default_index \
25891                                 -H all_char $DIR/$tdir/$dirname ||
25892                 error "set default stripe on striped dir error"
25893         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
25894         [ $stripe_count -eq $default_count ] ||
25895                 error "expect $default_count get $stripe_count for $dirname"
25896
25897         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
25898         [ $stripe_index -eq $default_index ] ||
25899                 error "expect $default_index get $stripe_index for $dirname"
25900
25901         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
25902                                                 error "create dirs failed"
25903
25904         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
25905         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
25906         for dir in $(find $DIR/$tdir/$dirname/*); do
25907                 stripe_count=$($LFS getdirstripe -c $dir)
25908                 (( $stripe_count == $default_count )) ||
25909                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
25910                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
25911                 error "stripe count $default_count != $stripe_count for $dir"
25912
25913                 stripe_index=$($LFS getdirstripe -i $dir)
25914                 [ $default_index -eq -1 ] ||
25915                         [ $stripe_index -eq $default_index ] ||
25916                         error "$stripe_index != $default_index for $dir"
25917
25918                 #check default stripe
25919                 stripe_count=$($LFS getdirstripe -D -c $dir)
25920                 [ $stripe_count -eq $default_count ] ||
25921                 error "default count $default_count != $stripe_count for $dir"
25922
25923                 stripe_index=$($LFS getdirstripe -D -i $dir)
25924                 [ $stripe_index -eq $default_index ] ||
25925                 error "default index $default_index != $stripe_index for $dir"
25926         done
25927         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
25928 }
25929
25930 test_300g() {
25931         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25932         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25933                 skip "Need MDS version at least 2.7.55"
25934
25935         local dir
25936         local stripe_count
25937         local stripe_index
25938
25939         mkdir_on_mdt0 $DIR/$tdir
25940         mkdir $DIR/$tdir/normal_dir
25941
25942         #Checking when client cache stripe index
25943         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
25944         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
25945                 error "create striped_dir failed"
25946
25947         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
25948                 error "create dir0 fails"
25949         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
25950         [ $stripe_index -eq 0 ] ||
25951                 error "dir0 expect index 0 got $stripe_index"
25952
25953         mkdir $DIR/$tdir/striped_dir/dir1 ||
25954                 error "create dir1 fails"
25955         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
25956         [ $stripe_index -eq 1 ] ||
25957                 error "dir1 expect index 1 got $stripe_index"
25958
25959         #check default stripe count/stripe index
25960         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
25961         test_300_check_default_striped_dir normal_dir 1 0
25962         test_300_check_default_striped_dir normal_dir -1 1
25963         test_300_check_default_striped_dir normal_dir 2 -1
25964
25965         #delete default stripe information
25966         echo "delete default stripeEA"
25967         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
25968                 error "set default stripe on striped dir error"
25969
25970         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
25971         for dir in $(find $DIR/$tdir/normal_dir/*); do
25972                 stripe_count=$($LFS getdirstripe -c $dir)
25973                 [ $stripe_count -eq 0 ] ||
25974                         error "expect 1 get $stripe_count for $dir"
25975         done
25976 }
25977 run_test 300g "check default striped directory for normal directory"
25978
25979 test_300h() {
25980         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25981         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25982                 skip "Need MDS version at least 2.7.55"
25983
25984         local dir
25985         local stripe_count
25986
25987         mkdir $DIR/$tdir
25988         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
25989                 error "set striped dir error"
25990
25991         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
25992         test_300_check_default_striped_dir striped_dir 1 0
25993         test_300_check_default_striped_dir striped_dir -1 1
25994         test_300_check_default_striped_dir striped_dir 2 -1
25995
25996         #delete default stripe information
25997         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
25998                 error "set default stripe on striped dir error"
25999
26000         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
26001         for dir in $(find $DIR/$tdir/striped_dir/*); do
26002                 stripe_count=$($LFS getdirstripe -c $dir)
26003                 [ $stripe_count -eq 0 ] ||
26004                         error "expect 1 get $stripe_count for $dir"
26005         done
26006 }
26007 run_test 300h "check default striped directory for striped directory"
26008
26009 test_300i() {
26010         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
26011         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
26012         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
26013                 skip "Need MDS version at least 2.7.55"
26014
26015         local stripe_count
26016         local file
26017
26018         mkdir $DIR/$tdir
26019
26020         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26021                 error "set striped dir error"
26022
26023         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26024                 error "create files under striped dir failed"
26025
26026         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
26027                 error "set striped hashdir error"
26028
26029         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
26030                 error "create dir0 under hash dir failed"
26031         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
26032                 error "create dir1 under hash dir failed"
26033         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
26034                 error "create dir2 under hash dir failed"
26035
26036         # unfortunately, we need to umount to clear dir layout cache for now
26037         # once we fully implement dir layout, we can drop this
26038         umount_client $MOUNT || error "umount failed"
26039         mount_client $MOUNT || error "mount failed"
26040
26041         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
26042         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
26043         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
26044
26045         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
26046                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
26047                         error "create crush2 dir $tdir/hashdir/d3 failed"
26048                 $LFS find -H crush2 $DIR/$tdir/hashdir
26049                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
26050                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
26051
26052                 # mkdir with an invalid hash type (hash=fail_val) from client
26053                 # should be replaced on MDS with a valid (default) hash type
26054                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26055                 $LCTL set_param fail_loc=0x1901 fail_val=99
26056                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
26057
26058                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
26059                 local expect=$(do_facet mds1 \
26060                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
26061                 [[ $hash == $expect ]] ||
26062                         error "d99 hash '$hash' != expected hash '$expect'"
26063         fi
26064
26065         #set the stripe to be unknown hash type on read
26066         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
26067         $LCTL set_param fail_loc=0x1901 fail_val=99
26068         for ((i = 0; i < 10; i++)); do
26069                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
26070                         error "stat f-$i failed"
26071                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
26072         done
26073
26074         touch $DIR/$tdir/striped_dir/f0 &&
26075                 error "create under striped dir with unknown hash should fail"
26076
26077         $LCTL set_param fail_loc=0
26078
26079         umount_client $MOUNT || error "umount failed"
26080         mount_client $MOUNT || error "mount failed"
26081
26082         return 0
26083 }
26084 run_test 300i "client handle unknown hash type striped directory"
26085
26086 test_300j() {
26087         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26089         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26090                 skip "Need MDS version at least 2.7.55"
26091
26092         local stripe_count
26093         local file
26094
26095         mkdir $DIR/$tdir
26096
26097         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
26098         $LCTL set_param fail_loc=0x1702
26099         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
26100                 error "set striped dir error"
26101
26102         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
26103                 error "create files under striped dir failed"
26104
26105         $LCTL set_param fail_loc=0
26106
26107         rm -rf $DIR/$tdir || error "unlink striped dir fails"
26108
26109         return 0
26110 }
26111 run_test 300j "test large update record"
26112
26113 test_300k() {
26114         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26115         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26116         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26117                 skip "Need MDS version at least 2.7.55"
26118
26119         # this test needs a huge transaction
26120         local kb
26121         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26122              osd*.$FSNAME-MDT0000.kbytestotal")
26123         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
26124
26125         local stripe_count
26126         local file
26127
26128         mkdir $DIR/$tdir
26129
26130         #define OBD_FAIL_LARGE_STRIPE   0x1703
26131         $LCTL set_param fail_loc=0x1703
26132         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
26133                 error "set striped dir error"
26134         $LCTL set_param fail_loc=0
26135
26136         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26137                 error "getstripeddir fails"
26138         rm -rf $DIR/$tdir/striped_dir ||
26139                 error "unlink striped dir fails"
26140
26141         return 0
26142 }
26143 run_test 300k "test large striped directory"
26144
26145 test_300l() {
26146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26147         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26148         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26149                 skip "Need MDS version at least 2.7.55"
26150
26151         local stripe_index
26152
26153         test_mkdir -p $DIR/$tdir/striped_dir
26154         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
26155                         error "chown $RUNAS_ID failed"
26156         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
26157                 error "set default striped dir failed"
26158
26159         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
26160         $LCTL set_param fail_loc=0x80000158
26161         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
26162
26163         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
26164         [ $stripe_index -eq 1 ] ||
26165                 error "expect 1 get $stripe_index for $dir"
26166 }
26167 run_test 300l "non-root user to create dir under striped dir with stale layout"
26168
26169 test_300m() {
26170         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26171         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
26172         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26173                 skip "Need MDS version at least 2.7.55"
26174
26175         mkdir -p $DIR/$tdir/striped_dir
26176         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
26177                 error "set default stripes dir error"
26178
26179         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
26180
26181         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
26182         [ $stripe_count -eq 0 ] ||
26183                         error "expect 0 get $stripe_count for a"
26184
26185         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
26186                 error "set default stripes dir error"
26187
26188         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
26189
26190         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
26191         [ $stripe_count -eq 0 ] ||
26192                         error "expect 0 get $stripe_count for b"
26193
26194         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
26195                 error "set default stripes dir error"
26196
26197         mkdir $DIR/$tdir/striped_dir/c &&
26198                 error "default stripe_index is invalid, mkdir c should fails"
26199
26200         rm -rf $DIR/$tdir || error "rmdir fails"
26201 }
26202 run_test 300m "setstriped directory on single MDT FS"
26203
26204 cleanup_300n() {
26205         local list=$(comma_list $(mdts_nodes))
26206
26207         trap 0
26208         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26209 }
26210
26211 test_300n() {
26212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26213         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26214         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26215                 skip "Need MDS version at least 2.7.55"
26216         remote_mds_nodsh && skip "remote MDS with nodsh"
26217
26218         local stripe_index
26219         local list=$(comma_list $(mdts_nodes))
26220
26221         trap cleanup_300n RETURN EXIT
26222         mkdir -p $DIR/$tdir
26223         chmod 777 $DIR/$tdir
26224         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
26225                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26226                 error "create striped dir succeeds with gid=0"
26227
26228         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26229         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
26230                 error "create striped dir fails with gid=-1"
26231
26232         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26233         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
26234                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
26235                 error "set default striped dir succeeds with gid=0"
26236
26237
26238         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
26239         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
26240                 error "set default striped dir fails with gid=-1"
26241
26242
26243         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
26244         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
26245                                         error "create test_dir fails"
26246         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
26247                                         error "create test_dir1 fails"
26248         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
26249                                         error "create test_dir2 fails"
26250         cleanup_300n
26251 }
26252 run_test 300n "non-root user to create dir under striped dir with default EA"
26253
26254 test_300o() {
26255         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26256         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26257         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26258                 skip "Need MDS version at least 2.7.55"
26259
26260         local numfree1
26261         local numfree2
26262
26263         mkdir -p $DIR/$tdir
26264
26265         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
26266         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
26267         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
26268                 skip "not enough free inodes $numfree1 $numfree2"
26269         fi
26270
26271         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
26272         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
26273         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
26274                 skip "not enough free space $numfree1 $numfree2"
26275         fi
26276
26277         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
26278                 error "setdirstripe fails"
26279
26280         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
26281                 error "create dirs fails"
26282
26283         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
26284         ls $DIR/$tdir/striped_dir > /dev/null ||
26285                 error "ls striped dir fails"
26286         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
26287                 error "unlink big striped dir fails"
26288 }
26289 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
26290
26291 test_300p() {
26292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26293         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26294         remote_mds_nodsh && skip "remote MDS with nodsh"
26295
26296         mkdir_on_mdt0 $DIR/$tdir
26297
26298         #define OBD_FAIL_OUT_ENOSPC     0x1704
26299         do_facet mds2 lctl set_param fail_loc=0x80001704
26300         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
26301                  && error "create striped directory should fail"
26302
26303         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
26304
26305         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
26306         true
26307 }
26308 run_test 300p "create striped directory without space"
26309
26310 test_300q() {
26311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26312         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26313
26314         local fd=$(free_fd)
26315         local cmd="exec $fd<$tdir"
26316         cd $DIR
26317         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
26318         eval $cmd
26319         cmd="exec $fd<&-"
26320         trap "eval $cmd" EXIT
26321         cd $tdir || error "cd $tdir fails"
26322         rmdir  ../$tdir || error "rmdir $tdir fails"
26323         mkdir local_dir && error "create dir succeeds"
26324         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
26325         eval $cmd
26326         return 0
26327 }
26328 run_test 300q "create remote directory under orphan directory"
26329
26330 test_300r() {
26331         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26332                 skip "Need MDS version at least 2.7.55" && return
26333         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26334
26335         mkdir $DIR/$tdir
26336
26337         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
26338                 error "set striped dir error"
26339
26340         $LFS getdirstripe $DIR/$tdir/striped_dir ||
26341                 error "getstripeddir fails"
26342
26343         local stripe_count
26344         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
26345                       awk '/lmv_stripe_count:/ { print $2 }')
26346
26347         [ $MDSCOUNT -ne $stripe_count ] &&
26348                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
26349
26350         rm -rf $DIR/$tdir/striped_dir ||
26351                 error "unlink striped dir fails"
26352 }
26353 run_test 300r "test -1 striped directory"
26354
26355 test_300s_helper() {
26356         local count=$1
26357
26358         local stripe_dir=$DIR/$tdir/striped_dir.$count
26359
26360         $LFS mkdir -c $count $stripe_dir ||
26361                 error "lfs mkdir -c error"
26362
26363         $LFS getdirstripe $stripe_dir ||
26364                 error "lfs getdirstripe fails"
26365
26366         local stripe_count
26367         stripe_count=$($LFS getdirstripe $stripe_dir |
26368                       awk '/lmv_stripe_count:/ { print $2 }')
26369
26370         [ $count -ne $stripe_count ] &&
26371                 error_noexit "bad stripe count $stripe_count expected $count"
26372
26373         local dupe_stripes
26374         dupe_stripes=$($LFS getdirstripe $stripe_dir |
26375                 awk '/0x/ {count[$1] += 1}; END {
26376                         for (idx in count) {
26377                                 if (count[idx]>1) {
26378                                         print "index " idx " count " count[idx]
26379                                 }
26380                         }
26381                 }')
26382
26383         if [[ -n "$dupe_stripes" ]] ; then
26384                 lfs getdirstripe $stripe_dir
26385                 error_noexit "Dupe MDT above: $dupe_stripes "
26386         fi
26387
26388         rm -rf $stripe_dir ||
26389                 error_noexit "unlink $stripe_dir fails"
26390 }
26391
26392 test_300s() {
26393         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
26394                 skip "Need MDS version at least 2.7.55" && return
26395         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
26396
26397         mkdir $DIR/$tdir
26398         for count in $(seq 2 $MDSCOUNT); do
26399                 test_300s_helper $count
26400         done
26401 }
26402 run_test 300s "test lfs mkdir -c without -i"
26403
26404 test_300t() {
26405         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
26406                 skip "need MDS 2.14.55 or later"
26407         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
26408
26409         local testdir="$DIR/$tdir/striped_dir"
26410         local dir1=$testdir/dir1
26411         local dir2=$testdir/dir2
26412
26413         mkdir -p $testdir
26414
26415         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
26416                 error "failed to set default stripe count for $testdir"
26417
26418         mkdir $dir1
26419         local stripe_count=$($LFS getdirstripe -c $dir1)
26420
26421         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
26422
26423         local max_count=$((MDSCOUNT - 1))
26424         local mdts=$(comma_list $(mdts_nodes))
26425
26426         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
26427         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
26428
26429         mkdir $dir2
26430         stripe_count=$($LFS getdirstripe -c $dir2)
26431
26432         (( $stripe_count == $max_count )) || error "wrong stripe count"
26433 }
26434 run_test 300t "test max_mdt_stripecount"
26435
26436 prepare_remote_file() {
26437         mkdir $DIR/$tdir/src_dir ||
26438                 error "create remote source failed"
26439
26440         cp /etc/hosts $DIR/$tdir/src_dir/a ||
26441                  error "cp to remote source failed"
26442         touch $DIR/$tdir/src_dir/a
26443
26444         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
26445                 error "create remote target dir failed"
26446
26447         touch $DIR/$tdir/tgt_dir/b
26448
26449         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
26450                 error "rename dir cross MDT failed!"
26451
26452         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
26453                 error "src_child still exists after rename"
26454
26455         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
26456                 error "missing file(a) after rename"
26457
26458         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
26459                 error "diff after rename"
26460 }
26461
26462 test_310a() {
26463         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26465
26466         local remote_file=$DIR/$tdir/tgt_dir/b
26467
26468         mkdir -p $DIR/$tdir
26469
26470         prepare_remote_file || error "prepare remote file failed"
26471
26472         #open-unlink file
26473         $OPENUNLINK $remote_file $remote_file ||
26474                 error "openunlink $remote_file failed"
26475         $CHECKSTAT -a $remote_file || error "$remote_file exists"
26476 }
26477 run_test 310a "open unlink remote file"
26478
26479 test_310b() {
26480         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
26481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26482
26483         local remote_file=$DIR/$tdir/tgt_dir/b
26484
26485         mkdir -p $DIR/$tdir
26486
26487         prepare_remote_file || error "prepare remote file failed"
26488
26489         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26490         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
26491         $CHECKSTAT -t file $remote_file || error "check file failed"
26492 }
26493 run_test 310b "unlink remote file with multiple links while open"
26494
26495 test_310c() {
26496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26497         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
26498
26499         local remote_file=$DIR/$tdir/tgt_dir/b
26500
26501         mkdir -p $DIR/$tdir
26502
26503         prepare_remote_file || error "prepare remote file failed"
26504
26505         ln $remote_file $DIR/$tfile || error "link failed for remote file"
26506         multiop_bg_pause $remote_file O_uc ||
26507                         error "mulitop failed for remote file"
26508         MULTIPID=$!
26509         $MULTIOP $DIR/$tfile Ouc
26510         kill -USR1 $MULTIPID
26511         wait $MULTIPID
26512 }
26513 run_test 310c "open-unlink remote file with multiple links"
26514
26515 #LU-4825
26516 test_311() {
26517         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26518         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26519         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
26520                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
26521         remote_mds_nodsh && skip "remote MDS with nodsh"
26522
26523         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26524         local mdts=$(comma_list $(mdts_nodes))
26525
26526         mkdir -p $DIR/$tdir
26527         $LFS setstripe -i 0 -c 1 $DIR/$tdir
26528         createmany -o $DIR/$tdir/$tfile. 1000
26529
26530         # statfs data is not real time, let's just calculate it
26531         old_iused=$((old_iused + 1000))
26532
26533         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26534                         osp.*OST0000*MDT0000.create_count")
26535         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
26536                                 osp.*OST0000*MDT0000.max_create_count")
26537         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
26538
26539         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
26540         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
26541         [ $index -ne 0 ] || error "$tfile stripe index is 0"
26542
26543         unlinkmany $DIR/$tdir/$tfile. 1000
26544
26545         do_nodes $mdts "$LCTL set_param -n \
26546                         osp.*OST0000*.max_create_count=$max_count"
26547         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
26548                 do_nodes $mdts "$LCTL set_param -n \
26549                                 osp.*OST0000*.create_count=$count"
26550         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
26551                         grep "=0" && error "create_count is zero"
26552
26553         local new_iused
26554         for i in $(seq 120); do
26555                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
26556                 # system may be too busy to destroy all objs in time, use
26557                 # a somewhat small value to not fail autotest
26558                 [ $((old_iused - new_iused)) -gt 400 ] && break
26559                 sleep 1
26560         done
26561
26562         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
26563         [ $((old_iused - new_iused)) -gt 400 ] ||
26564                 error "objs not destroyed after unlink"
26565 }
26566 run_test 311 "disable OSP precreate, and unlink should destroy objs"
26567
26568 zfs_get_objid()
26569 {
26570         local ost=$1
26571         local tf=$2
26572         local fid=($($LFS getstripe $tf | grep 0x))
26573         local seq=${fid[3]#0x}
26574         local objid=${fid[1]}
26575
26576         local vdevdir=$(dirname $(facet_vdevice $ost))
26577         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
26578         local zfs_zapid=$(do_facet $ost $cmd |
26579                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
26580                           awk '/Object/{getline; print $1}')
26581         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
26582                           awk "/$objid = /"'{printf $3}')
26583
26584         echo $zfs_objid
26585 }
26586
26587 zfs_object_blksz() {
26588         local ost=$1
26589         local objid=$2
26590
26591         local vdevdir=$(dirname $(facet_vdevice $ost))
26592         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
26593         local blksz=$(do_facet $ost $cmd $objid |
26594                       awk '/dblk/{getline; printf $4}')
26595
26596         case "${blksz: -1}" in
26597                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
26598                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
26599                 *) ;;
26600         esac
26601
26602         echo $blksz
26603 }
26604
26605 test_312() { # LU-4856
26606         remote_ost_nodsh && skip "remote OST with nodsh"
26607         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
26608
26609         local max_blksz=$(do_facet ost1 \
26610                           $ZFS get -p recordsize $(facet_device ost1) |
26611                           awk '!/VALUE/{print $3}')
26612         local tf=$DIR/$tfile
26613
26614         $LFS setstripe -c1 $tf
26615         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
26616
26617         # Get ZFS object id
26618         local zfs_objid=$(zfs_get_objid $facet $tf)
26619         # block size change by sequential overwrite
26620         local bs
26621
26622         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
26623                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
26624
26625                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
26626                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
26627         done
26628         rm -f $tf
26629
26630         $LFS setstripe -c1 $tf
26631         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26632
26633         # block size change by sequential append write
26634         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
26635         zfs_objid=$(zfs_get_objid $facet $tf)
26636         local count
26637
26638         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
26639                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
26640                         oflag=sync conv=notrunc
26641
26642                 blksz=$(zfs_object_blksz $facet $zfs_objid)
26643                 (( $blksz == 2 * count * PAGE_SIZE )) ||
26644                         error "blksz error, actual $blksz, " \
26645                                 "expected: 2 * $count * $PAGE_SIZE"
26646         done
26647         rm -f $tf
26648
26649         # random write
26650         $LFS setstripe -c1 $tf
26651         facet="ost$(($($LFS getstripe -i $tf) + 1))"
26652         zfs_objid=$(zfs_get_objid $facet $tf)
26653
26654         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
26655         blksz=$(zfs_object_blksz $facet $zfs_objid)
26656         (( blksz == PAGE_SIZE )) ||
26657                 error "blksz error: $blksz, expected: $PAGE_SIZE"
26658
26659         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
26660         blksz=$(zfs_object_blksz $facet $zfs_objid)
26661         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
26662
26663         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
26664         blksz=$(zfs_object_blksz $facet $zfs_objid)
26665         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
26666 }
26667 run_test 312 "make sure ZFS adjusts its block size by write pattern"
26668
26669 test_313() {
26670         remote_ost_nodsh && skip "remote OST with nodsh"
26671
26672         local file=$DIR/$tfile
26673
26674         rm -f $file
26675         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
26676
26677         # define OBD_FAIL_TGT_RCVD_EIO           0x720
26678         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26679         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
26680                 error "write should failed"
26681         do_facet ost1 "$LCTL set_param fail_loc=0"
26682         rm -f $file
26683 }
26684 run_test 313 "io should fail after last_rcvd update fail"
26685
26686 test_314() {
26687         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
26688
26689         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
26690         do_facet ost1 "$LCTL set_param fail_loc=0x720"
26691         rm -f $DIR/$tfile
26692         wait_delete_completed
26693         do_facet ost1 "$LCTL set_param fail_loc=0"
26694 }
26695 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
26696
26697 test_315() { # LU-618
26698         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
26699
26700         local file=$DIR/$tfile
26701         rm -f $file
26702
26703         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
26704                 error "multiop file write failed"
26705         $MULTIOP $file oO_RDONLY:r4063232_c &
26706         PID=$!
26707
26708         sleep 2
26709
26710         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
26711         kill -USR1 $PID
26712
26713         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
26714         rm -f $file
26715 }
26716 run_test 315 "read should be accounted"
26717
26718 test_316() {
26719         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26720         large_xattr_enabled || skip "ea_inode feature disabled"
26721
26722         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
26723         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
26724         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
26725         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
26726
26727         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
26728 }
26729 run_test 316 "lfs migrate of file with large_xattr enabled"
26730
26731 test_317() {
26732         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
26733                 skip "Need MDS version at least 2.11.53"
26734         if [ "$ost1_FSTYPE" == "zfs" ]; then
26735                 skip "LU-10370: no implementation for ZFS"
26736         fi
26737
26738         local trunc_sz
26739         local grant_blk_size
26740
26741         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
26742                         awk '/grant_block_size:/ { print $2; exit; }')
26743         #
26744         # Create File of size 5M. Truncate it to below size's and verify
26745         # blocks count.
26746         #
26747         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
26748                 error "Create file $DIR/$tfile failed"
26749         stack_trap "rm -f $DIR/$tfile" EXIT
26750
26751         for trunc_sz in 2097152 4097 4000 509 0; do
26752                 $TRUNCATE $DIR/$tfile $trunc_sz ||
26753                         error "truncate $tfile to $trunc_sz failed"
26754                 local sz=$(stat --format=%s $DIR/$tfile)
26755                 local blk=$(stat --format=%b $DIR/$tfile)
26756                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
26757                                      grant_blk_size) * 8))
26758
26759                 if [[ $blk -ne $trunc_blk ]]; then
26760                         $(which stat) $DIR/$tfile
26761                         error "Expected Block $trunc_blk got $blk for $tfile"
26762                 fi
26763
26764                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26765                         error "Expected Size $trunc_sz got $sz for $tfile"
26766         done
26767
26768         #
26769         # sparse file test
26770         # Create file with a hole and write actual 65536 bytes which aligned
26771         # with 4K and 64K PAGE_SIZE. Block count must be 128.
26772         #
26773         local bs=65536
26774         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
26775                 error "Create file : $DIR/$tfile"
26776
26777         #
26778         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
26779         # blocks. The block count must drop to 8.
26780         #
26781         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
26782                 ((bs - grant_blk_size) + 1)))
26783         $TRUNCATE $DIR/$tfile $trunc_sz ||
26784                 error "truncate $tfile to $trunc_sz failed"
26785
26786         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
26787         sz=$(stat --format=%s $DIR/$tfile)
26788         blk=$(stat --format=%b $DIR/$tfile)
26789
26790         if [[ $blk -ne $trunc_bsz ]]; then
26791                 $(which stat) $DIR/$tfile
26792                 error "Expected Block $trunc_bsz got $blk for $tfile"
26793         fi
26794
26795         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
26796                 error "Expected Size $trunc_sz got $sz for $tfile"
26797 }
26798 run_test 317 "Verify blocks get correctly update after truncate"
26799
26800 test_318() {
26801         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
26802         local old_max_active=$($LCTL get_param -n \
26803                             ${llite_name}.max_read_ahead_async_active \
26804                             2>/dev/null)
26805
26806         $LCTL set_param llite.*.max_read_ahead_async_active=256
26807         local max_active=$($LCTL get_param -n \
26808                            ${llite_name}.max_read_ahead_async_active \
26809                            2>/dev/null)
26810         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
26811
26812         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
26813                 error "set max_read_ahead_async_active should succeed"
26814
26815         $LCTL set_param llite.*.max_read_ahead_async_active=512
26816         max_active=$($LCTL get_param -n \
26817                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
26818         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
26819
26820         # restore @max_active
26821         [ $old_max_active -ne 0 ] && $LCTL set_param \
26822                 llite.*.max_read_ahead_async_active=$old_max_active
26823
26824         local old_threshold=$($LCTL get_param -n \
26825                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26826         local max_per_file_mb=$($LCTL get_param -n \
26827                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
26828
26829         local invalid=$(($max_per_file_mb + 1))
26830         $LCTL set_param \
26831                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
26832                         && error "set $invalid should fail"
26833
26834         local valid=$(($invalid - 1))
26835         $LCTL set_param \
26836                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
26837                         error "set $valid should succeed"
26838         local threshold=$($LCTL get_param -n \
26839                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
26840         [ $threshold -eq $valid ] || error \
26841                 "expect threshold $valid got $threshold"
26842         $LCTL set_param \
26843                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
26844 }
26845 run_test 318 "Verify async readahead tunables"
26846
26847 test_319() {
26848         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
26849
26850         local before=$(date +%s)
26851         local evict
26852         local mdir=$DIR/$tdir
26853         local file=$mdir/xxx
26854
26855         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
26856         touch $file
26857
26858 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
26859         $LCTL set_param fail_val=5 fail_loc=0x8000032c
26860         $LFS migrate -m1 $mdir &
26861
26862         sleep 1
26863         dd if=$file of=/dev/null
26864         wait
26865         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
26866           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
26867
26868         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
26869 }
26870 run_test 319 "lost lease lock on migrate error"
26871
26872 test_360() {
26873         (( $OST1_VERSION >= $(version_code 2.15.58.96) )) ||
26874                 skip "Need OST version at least 2.15.58.96"
26875         [[ "$ost1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
26876
26877         check_set_fallocate_or_skip
26878         local param="osd-ldiskfs.delayed_unlink_mb"
26879         local old=($(do_facet ost1 "$LCTL get_param -n $param"))
26880
26881         do_facet ost1 "$LCTL set_param $param=1MiB"
26882         stack_trap "do_facet ost1 $LCTL set_param $param=${old[0]}"
26883
26884         mkdir $DIR/$tdir/
26885         do_facet ost1 $LCTL set_param debug=+inode
26886         do_facet ost1 $LCTL clear
26887         local files=100
26888
26889         for ((i = 0; i < $files; i++)); do
26890                 fallocate -l 1280k $DIR/$tdir/$tfile.$i ||
26891                         error "fallocate 1280k $DIR/$tdir/$tfile.$i failed"
26892         done
26893         local min=$(($($LFS find $DIR/$tdir --ost 0 | wc -l) / 2))
26894
26895         for ((i = 0; i < $files; i++)); do
26896                 unlink $DIR/$tdir/$tfile.$i ||
26897                         error "unlink $DIR/$tdir/$tfile.$i failed"
26898         done
26899
26900         local count=0
26901         local loop
26902
26903         for (( loop = 0; loop < 30 && count < min; loop++)); do
26904                 sleep 1
26905                 (( count += $(do_facet ost1 $LCTL dk | grep -c "delayed iput")))
26906                 echo "Count[$loop]: $count"
26907         done
26908         (( count >= min )) || error "$count < $min delayed iput after $loop s"
26909 }
26910 run_test 360 "ldiskfs unlink in a separate thread"
26911
26912 test_398a() { # LU-4198
26913         local ost1_imp=$(get_osc_import_name client ost1)
26914         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26915                          cut -d'.' -f2)
26916
26917         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26918         stack_trap "rm -f $DIR/$tfile"
26919         $LCTL set_param ldlm.namespaces.*.lru_size=clear
26920
26921         # request a new lock on client
26922         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
26923
26924         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26925         local lock_count=$($LCTL get_param -n \
26926                            ldlm.namespaces.$imp_name.lru_size)
26927         [[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
26928
26929         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26930
26931         # no lock cached, should use lockless DIO and not enqueue new lock
26932         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
26933         lock_count=$($LCTL get_param -n \
26934                      ldlm.namespaces.$imp_name.lru_size)
26935         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
26936
26937         $LCTL set_param ldlm.namespaces.$imp_name.lru_size=clear
26938
26939         # no lock cached, should use locked DIO append
26940         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
26941                 conv=notrunc || error "DIO append failed"
26942         lock_count=$($LCTL get_param -n \
26943                      ldlm.namespaces.$imp_name.lru_size)
26944         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
26945 }
26946 run_test 398a "direct IO should cancel lock otherwise lockless"
26947
26948 test_398b() { # LU-4198
26949         local before=$(date +%s)
26950         local njobs=4
26951         local size=48
26952
26953         which fio || skip_env "no fio installed"
26954         $LFS setstripe -c -1 -S 1M $DIR/$tfile
26955         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
26956
26957         # Single page, multiple pages, stripe size, 4*stripe size
26958         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
26959                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
26960                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
26961                         --numjobs=$njobs --fallocate=none \
26962                         --iodepth=16 --allow_file_create=0 \
26963                         --size=$((size/njobs))M \
26964                         --filename=$DIR/$tfile &
26965                 bg_pid=$!
26966
26967                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
26968                 fio --name=rand-rw --rw=randrw --bs=$bsize \
26969                         --numjobs=$njobs --fallocate=none \
26970                         --iodepth=16 --allow_file_create=0 \
26971                         --size=$((size/njobs))M \
26972                         --filename=$DIR/$tfile || true
26973                 wait $bg_pid
26974         done
26975
26976         evict=$(do_facet client $LCTL get_param \
26977                 osc.$FSNAME-OST*-osc-*/state |
26978             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
26979
26980         [ -z "$evict" ] || [[ $evict -le $before ]] ||
26981                 (do_facet client $LCTL get_param \
26982                         osc.$FSNAME-OST*-osc-*/state;
26983                     error "eviction happened: $evict before:$before")
26984
26985         rm -f $DIR/$tfile
26986 }
26987 run_test 398b "DIO and buffer IO race"
26988
26989 test_398c() { # LU-4198
26990         local ost1_imp=$(get_osc_import_name client ost1)
26991         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
26992                          cut -d'.' -f2)
26993
26994         which fio || skip_env "no fio installed"
26995
26996         saved_debug=$($LCTL get_param -n debug)
26997         $LCTL set_param debug=0
26998
26999         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
27000         ((size /= 1024)) # by megabytes
27001         ((size /= 2)) # write half of the OST at most
27002         [ $size -gt 40 ] && size=40 #reduce test time anyway
27003
27004         $LFS setstripe -c 1 $DIR/$tfile
27005
27006         # it seems like ldiskfs reserves more space than necessary if the
27007         # writing blocks are not mapped, so it extends the file firstly
27008         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
27009         cancel_lru_locks osc
27010
27011         # clear and verify rpc_stats later
27012         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
27013
27014         local njobs=4
27015         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
27016         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
27017                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27018                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27019                 --filename=$DIR/$tfile
27020         [ $? -eq 0 ] || error "fio write error"
27021
27022         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
27023                 error "Locks were requested while doing AIO"
27024
27025         # get the percentage of 1-page I/O
27026         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
27027                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
27028                 awk '{print $7}')
27029         (( $pct <= 50 )) || {
27030                 $LCTL get_param osc.${imp_name}.rpc_stats
27031                 error "$pct% of I/O are 1-page"
27032         }
27033
27034         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
27035         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
27036                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
27037                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
27038                 --filename=$DIR/$tfile
27039         [ $? -eq 0 ] || error "fio mixed read write error"
27040
27041         echo "AIO with large block size ${size}M"
27042         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
27043                 --numjobs=1 --fallocate=none --ioengine=libaio \
27044                 --iodepth=16 --allow_file_create=0 --size=${size}M \
27045                 --filename=$DIR/$tfile
27046         [ $? -eq 0 ] || error "fio large block size failed"
27047
27048         rm -f $DIR/$tfile
27049         $LCTL set_param debug="$saved_debug"
27050 }
27051 run_test 398c "run fio to test AIO"
27052
27053 test_398d() { #  LU-13846
27054         which aiocp || skip_env "no aiocp installed"
27055         local aio_file=$DIR/$tfile.aio
27056
27057         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27058
27059         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
27060         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
27061         stack_trap "rm -f $DIR/$tfile $aio_file"
27062
27063         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27064
27065         # test memory unaligned aio
27066         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file ||
27067                 error "unaligned aio failed"
27068         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
27069
27070         rm -f $DIR/$tfile $aio_file
27071 }
27072 run_test 398d "run aiocp to verify block size > stripe size"
27073
27074 test_398e() {
27075         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
27076         touch $DIR/$tfile.new
27077         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
27078 }
27079 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
27080
27081 test_398f() { #  LU-14687
27082         which aiocp || skip_env "no aiocp installed"
27083         local aio_file=$DIR/$tfile.aio
27084
27085         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
27086
27087         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
27088         stack_trap "rm -f $DIR/$tfile $aio_file"
27089
27090         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27091         $LCTL set_param fail_loc=0x1418
27092         # make sure we don't crash and fail properly
27093         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
27094                 error "aio with page allocation failure succeeded"
27095         $LCTL set_param fail_loc=0
27096         diff $DIR/$tfile $aio_file
27097         [[ $? != 0 ]] || error "no diff after failed aiocp"
27098 }
27099 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
27100
27101 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
27102 # stripe and i/o size must be > stripe size
27103 # Old style synchronous DIO waits after submitting each chunk, resulting in a
27104 # single RPC in flight.  This test shows async DIO submission is working by
27105 # showing multiple RPCs in flight.
27106 test_398g() { #  LU-13798
27107         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27108
27109         # We need to do some i/o first to acquire enough grant to put our RPCs
27110         # in flight; otherwise a new connection may not have enough grant
27111         # available
27112         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27113                 error "parallel dio failed"
27114         stack_trap "rm -f $DIR/$tfile"
27115
27116         # Reduce RPC size to 1M to avoid combination in to larger RPCs
27117         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27118         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27119         stack_trap "$LCTL set_param -n $pages_per_rpc"
27120
27121         # Recreate file so it's empty
27122         rm -f $DIR/$tfile
27123         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
27124         #Pause rpc completion to guarantee we see multiple rpcs in flight
27125         #define OBD_FAIL_OST_BRW_PAUSE_BULK
27126         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
27127         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27128
27129         # Clear rpc stats
27130         $LCTL set_param osc.*.rpc_stats=c
27131
27132         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27133                 error "parallel dio failed"
27134         stack_trap "rm -f $DIR/$tfile"
27135
27136         $LCTL get_param osc.*-OST0000-*.rpc_stats
27137         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27138                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27139                 grep "8:" | awk '{print $8}')
27140         # We look at the "8 rpcs in flight" field, and verify A) it is present
27141         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
27142         # as expected for an 8M DIO to a file with 1M stripes.
27143         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
27144
27145         # Verify turning off parallel dio works as expected
27146         # Clear rpc stats
27147         $LCTL set_param osc.*.rpc_stats=c
27148         $LCTL set_param llite.*.parallel_dio=0
27149         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
27150
27151         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
27152                 error "dio with parallel dio disabled failed"
27153
27154         # Ideally, we would see only one RPC in flight here, but there is an
27155         # unavoidable race between i/o completion and RPC in flight counting,
27156         # so while only 1 i/o is in flight at a time, the RPC in flight counter
27157         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
27158         # So instead we just verify it's always < 8.
27159         $LCTL get_param osc.*-OST0000-*.rpc_stats
27160         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
27161                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
27162                 grep '^$' -B1 | grep . | awk '{print $1}')
27163         [ $ret != "8:" ] ||
27164                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
27165 }
27166 run_test 398g "verify parallel dio async RPC submission"
27167
27168 test_398h() { #  LU-13798
27169         local dio_file=$DIR/$tfile.dio
27170
27171         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27172
27173         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27174         stack_trap "rm -f $DIR/$tfile $dio_file"
27175
27176         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
27177                 error "parallel dio failed"
27178         diff $DIR/$tfile $dio_file
27179         [[ $? == 0 ]] || error "file diff after aiocp"
27180 }
27181 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
27182
27183 test_398i() { #  LU-13798
27184         local dio_file=$DIR/$tfile.dio
27185
27186         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
27187
27188         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27189         stack_trap "rm -f $DIR/$tfile $dio_file"
27190
27191         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
27192         $LCTL set_param fail_loc=0x1418
27193         # make sure we don't crash and fail properly
27194         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
27195                 error "parallel dio page allocation failure succeeded"
27196         diff $DIR/$tfile $dio_file
27197         [[ $? != 0 ]] || error "no diff after failed aiocp"
27198 }
27199 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
27200
27201 test_398j() { #  LU-13798
27202         # Stripe size > RPC size but less than i/o size tests split across
27203         # stripes and RPCs for individual i/o op
27204         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
27205
27206         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
27207         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
27208         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
27209         stack_trap "$LCTL set_param -n $pages_per_rpc"
27210
27211         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27212                 error "parallel dio write failed"
27213         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
27214
27215         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
27216                 error "parallel dio read failed"
27217         diff $DIR/$tfile $DIR/$tfile.2
27218         [[ $? == 0 ]] || error "file diff after parallel dio read"
27219 }
27220 run_test 398j "test parallel dio where stripe size > rpc_size"
27221
27222 test_398k() { #  LU-13798
27223         wait_delete_completed
27224         wait_mds_ost_sync
27225
27226         # 4 stripe file; we will cause out of space on OST0
27227         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27228
27229         # Fill OST0 (if it's not too large)
27230         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27231                    head -n1)
27232         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27233                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27234         fi
27235         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27236         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27237                 error "dd should fill OST0"
27238         stack_trap "rm -f $DIR/$tfile.1"
27239
27240         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
27241         err=$?
27242
27243         ls -la $DIR/$tfile
27244         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
27245                 error "file is not 0 bytes in size"
27246
27247         # dd above should not succeed, but don't error until here so we can
27248         # get debug info above
27249         [[ $err != 0 ]] ||
27250                 error "parallel dio write with enospc succeeded"
27251         stack_trap "rm -f $DIR/$tfile"
27252 }
27253 run_test 398k "test enospc on first stripe"
27254
27255 test_398l() { #  LU-13798
27256         wait_delete_completed
27257         wait_mds_ost_sync
27258
27259         # 4 stripe file; we will cause out of space on OST0
27260         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
27261         # happens on the second i/o chunk we issue
27262         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
27263
27264         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
27265         stack_trap "rm -f $DIR/$tfile"
27266
27267         # Fill OST0 (if it's not too large)
27268         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
27269                    head -n1)
27270         if [[ $ORIGFREE -gt $MAXFREE ]]; then
27271                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
27272         fi
27273         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
27274         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
27275                 error "dd should fill OST0"
27276         stack_trap "rm -f $DIR/$tfile.1"
27277
27278         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
27279         err=$?
27280         stack_trap "rm -f $DIR/$tfile.2"
27281
27282         # Check that short write completed as expected
27283         ls -la $DIR/$tfile.2
27284         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
27285                 error "file is not 1M in size"
27286
27287         # dd above should not succeed, but don't error until here so we can
27288         # get debug info above
27289         [[ $err != 0 ]] ||
27290                 error "parallel dio write with enospc succeeded"
27291
27292         # Truncate source file to same length as output file and diff them
27293         $TRUNCATE $DIR/$tfile 1048576
27294         diff $DIR/$tfile $DIR/$tfile.2
27295         [[ $? == 0 ]] || error "data incorrect after short write"
27296 }
27297 run_test 398l "test enospc on intermediate stripe/RPC"
27298
27299 test_398m() { #  LU-13798
27300         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
27301
27302         # Set up failure on OST0, the first stripe:
27303         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
27304         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
27305         # OST0 is on ost1, OST1 is on ost2.
27306         # So this fail_val specifies OST0
27307         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
27308         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
27309
27310         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27311                 error "parallel dio write with failure on first stripe succeeded"
27312         stack_trap "rm -f $DIR/$tfile"
27313         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27314
27315         # Place data in file for read
27316         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27317                 error "parallel dio write failed"
27318
27319         # Fail read on OST0, first stripe
27320         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27321         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
27322         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27323                 error "parallel dio read with error on first stripe succeeded"
27324         rm -f $DIR/$tfile.2
27325         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
27326
27327         # Switch to testing on OST1, second stripe
27328         # Clear file contents, maintain striping
27329         echo > $DIR/$tfile
27330         # Set up failure on OST1, second stripe:
27331         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
27332         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
27333
27334         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
27335                 error "parallel dio write with failure on second stripe succeeded"
27336         stack_trap "rm -f $DIR/$tfile"
27337         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27338
27339         # Place data in file for read
27340         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
27341                 error "parallel dio write failed"
27342
27343         # Fail read on OST1, second stripe
27344         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
27345         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
27346         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
27347                 error "parallel dio read with error on second stripe succeeded"
27348         rm -f $DIR/$tfile.2
27349         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
27350 }
27351 run_test 398m "test RPC failures with parallel dio"
27352
27353 # Parallel submission of DIO should not cause problems for append, but it's
27354 # important to verify.
27355 test_398n() { #  LU-13798
27356         $LFS setstripe -C 2 -S 1M $DIR/$tfile
27357
27358         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
27359                 error "dd to create source file failed"
27360         stack_trap "rm -f $DIR/$tfile"
27361
27362         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
27363                 error "parallel dio write with failure on second stripe succeeded"
27364         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
27365         diff $DIR/$tfile $DIR/$tfile.1
27366         [[ $? == 0 ]] || error "data incorrect after append"
27367
27368 }
27369 run_test 398n "test append with parallel DIO"
27370
27371 test_398o() {
27372         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
27373 }
27374 run_test 398o "right kms with DIO"
27375
27376 test_398p()
27377 {
27378         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27379         which aiocp || skip_env "no aiocp installed"
27380
27381         local stripe_size=$((1024 * 1024)) #1 MiB
27382         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27383         local file_size=$((25 * stripe_size))
27384
27385         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27386         stack_trap "rm -f $DIR/$tfile*"
27387         # Just a bit bigger than the largest size in the test set below
27388         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27389                 error "buffered i/o to create file failed"
27390
27391         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27392                 $((stripe_size * 4)); do
27393
27394                 $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27395
27396                 echo "bs: $bs, file_size $file_size"
27397                 aiocp -a $PAGE_SIZE -b $bs -s $file_size -f O_DIRECT \
27398                         $DIR/$tfile.1 $DIR/$tfile.2 &
27399                 pid_dio1=$!
27400                 # Buffered I/O with similar but not the same block size
27401                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27402                         conv=notrunc &
27403                 pid_bio2=$!
27404                 wait $pid_dio1
27405                 rc1=$?
27406                 wait $pid_bio2
27407                 rc2=$?
27408                 if (( rc1 != 0 )); then
27409                         error "aio copy 1 w/bsize $bs failed: $rc1"
27410                 fi
27411                 if (( rc2 != 0 )); then
27412                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27413                 fi
27414
27415                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27416                         error "size incorrect"
27417                 cmp --verbose $DIR/$tfile.1 $DIR/$tfile.2 ||
27418                         error "files differ, bsize $bs"
27419                 rm -f $DIR/$tfile.2
27420         done
27421 }
27422 run_test 398p "race aio with buffered i/o"
27423
27424 test_398q()
27425 {
27426         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
27427
27428         local stripe_size=$((1024 * 1024)) #1 MiB
27429         # Max i/o below is ~ 4 * stripe_size, so this gives ~5 i/os
27430         local file_size=$((25 * stripe_size))
27431
27432         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.1
27433         $LFS setstripe -c 2 -S $stripe_size $DIR/$tfile.2
27434
27435         # Just a bit bigger than the largest size in the test set below
27436         dd if=/dev/urandom bs=$file_size count=1 of=$DIR/$tfile.1 ||
27437                 error "buffered i/o to create file failed"
27438
27439         for bs in $PAGE_SIZE $((PAGE_SIZE * 4)) $stripe_size \
27440                 $((stripe_size * 4)); do
27441
27442                 echo "bs: $bs, file_size $file_size"
27443                 dd if=$DIR/$tfile.1 bs=$((bs *2 )) of=$DIR/$tfile.2 \
27444                         conv=notrunc oflag=direct iflag=direct &
27445                 pid_dio1=$!
27446                 # Buffered I/O with similar but not the same block size
27447                 dd if=$DIR/$tfile.1 bs=$((bs * 2)) of=$DIR/$tfile.2 \
27448                         conv=notrunc &
27449                 pid_bio2=$!
27450                 wait $pid_dio1
27451                 rc1=$?
27452                 wait $pid_bio2
27453                 rc2=$?
27454                 if (( rc1 != 0 )); then
27455                         error "dio copy 1 w/bsize $bs failed: $rc1"
27456                 fi
27457                 if (( rc2 != 0 )); then
27458                         error "buffered copy 2 w/bsize $bs failed: $rc2"
27459                 fi
27460
27461                 $CHECKSTAT -t file -s $file_size $DIR/$tfile.2 ||
27462                         error "size incorrect"
27463                 diff $DIR/$tfile.1 $DIR/$tfile.2 ||
27464                         error "files differ, bsize $bs"
27465         done
27466
27467         rm -f $DIR/$tfile*
27468 }
27469 run_test 398q "race dio with buffered i/o"
27470
27471 test_fake_rw() {
27472         local read_write=$1
27473         if [ "$read_write" = "write" ]; then
27474                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
27475         elif [ "$read_write" = "read" ]; then
27476                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
27477         else
27478                 error "argument error"
27479         fi
27480
27481         # turn off debug for performance testing
27482         local saved_debug=$($LCTL get_param -n debug)
27483         $LCTL set_param debug=0
27484
27485         $LFS setstripe -c 1 -i 0 $DIR/$tfile
27486
27487         # get ost1 size - $FSNAME-OST0000
27488         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
27489         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
27490         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
27491
27492         if [ "$read_write" = "read" ]; then
27493                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
27494         fi
27495
27496         local start_time=$(date +%s.%N)
27497         $dd_cmd bs=1M count=$blocks oflag=sync ||
27498                 error "real dd $read_write error"
27499         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
27500
27501         if [ "$read_write" = "write" ]; then
27502                 rm -f $DIR/$tfile
27503         fi
27504
27505         # define OBD_FAIL_OST_FAKE_RW           0x238
27506         do_facet ost1 $LCTL set_param fail_loc=0x238
27507
27508         local start_time=$(date +%s.%N)
27509         $dd_cmd bs=1M count=$blocks oflag=sync ||
27510                 error "fake dd $read_write error"
27511         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
27512
27513         if [ "$read_write" = "write" ]; then
27514                 # verify file size
27515                 cancel_lru_locks osc
27516                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
27517                         error "$tfile size not $blocks MB"
27518         fi
27519         do_facet ost1 $LCTL set_param fail_loc=0
27520
27521         echo "fake $read_write $duration_fake vs. normal $read_write" \
27522                 "$duration in seconds"
27523         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
27524                 error_not_in_vm "fake write is slower"
27525
27526         $LCTL set_param -n debug="$saved_debug"
27527         rm -f $DIR/$tfile
27528 }
27529 test_399a() { # LU-7655 for OST fake write
27530         remote_ost_nodsh && skip "remote OST with nodsh"
27531
27532         test_fake_rw write
27533 }
27534 run_test 399a "fake write should not be slower than normal write"
27535
27536 test_399b() { # LU-8726 for OST fake read
27537         remote_ost_nodsh && skip "remote OST with nodsh"
27538         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
27539                 skip_env "ldiskfs only test"
27540         fi
27541
27542         test_fake_rw read
27543 }
27544 run_test 399b "fake read should not be slower than normal read"
27545
27546 test_400a() { # LU-1606, was conf-sanity test_74
27547         if ! which $CC > /dev/null 2>&1; then
27548                 skip_env "$CC is not installed"
27549         fi
27550
27551         local extra_flags=''
27552         local out=$TMP/$tfile
27553         local prefix=/usr/include/lustre
27554         local prog
27555
27556         # Oleg removes .c files in his test rig so test if any c files exist
27557         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
27558                 skip_env "Needed .c test files are missing"
27559
27560         if ! [[ -d $prefix ]]; then
27561                 # Assume we're running in tree and fixup the include path.
27562                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
27563                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
27564                 extra_flags+=" -L$LUSTRE/utils/.libs"
27565         fi
27566
27567         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
27568                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
27569                         error "client api broken"
27570         done
27571         rm -f $out
27572 }
27573 run_test 400a "Lustre client api program can compile and link"
27574
27575 test_400b() { # LU-1606, LU-5011
27576         local header
27577         local out=$TMP/$tfile
27578         local prefix=/usr/include/linux/lustre
27579
27580         # We use a hard coded prefix so that this test will not fail
27581         # when run in tree. There are headers in lustre/include/lustre/
27582         # that are not packaged (like lustre_idl.h) and have more
27583         # complicated include dependencies (like config.h and lnet/types.h).
27584         # Since this test about correct packaging we just skip them when
27585         # they don't exist (see below) rather than try to fixup cppflags.
27586
27587         if ! which $CC > /dev/null 2>&1; then
27588                 skip_env "$CC is not installed"
27589         fi
27590
27591         for header in $prefix/*.h; do
27592                 if ! [[ -f "$header" ]]; then
27593                         continue
27594                 fi
27595
27596                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
27597                         continue # lustre_ioctl.h is internal header
27598                 fi
27599
27600                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
27601                         error "cannot compile '$header'"
27602         done
27603         rm -f $out
27604 }
27605 run_test 400b "packaged headers can be compiled"
27606
27607 test_401a() { #LU-7437
27608         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
27609         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
27610
27611         #count the number of parameters by "list_param -R"
27612         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
27613         #count the number of parameters by listing proc files
27614         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
27615         echo "proc_dirs='$proc_dirs'"
27616         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
27617         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
27618                       sort -u | wc -l)
27619
27620         [ $params -eq $procs ] ||
27621                 error "found $params parameters vs. $procs proc files"
27622
27623         # test the list_param -D option only returns directories
27624         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
27625         #count the number of parameters by listing proc directories
27626         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
27627                 sort -u | wc -l)
27628
27629         [ $params -eq $procs ] ||
27630                 error "found $params parameters vs. $procs proc files"
27631 }
27632 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
27633
27634 test_401b() {
27635         # jobid_var may not allow arbitrary values, so use jobid_name
27636         # if available
27637         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27638                 local testname=jobid_name tmp='testing%p'
27639         else
27640                 local testname=jobid_var tmp=testing
27641         fi
27642
27643         local save=$($LCTL get_param -n $testname)
27644
27645         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
27646                 error "no error returned when setting bad parameters"
27647
27648         local jobid_new=$($LCTL get_param -n foe $testname baz)
27649         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
27650
27651         $LCTL set_param -n fog=bam $testname=$save bat=fog
27652         local jobid_old=$($LCTL get_param -n foe $testname bag)
27653         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
27654 }
27655 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
27656
27657 test_401c() {
27658         # jobid_var may not allow arbitrary values, so use jobid_name
27659         # if available
27660         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27661                 local testname=jobid_name
27662         else
27663                 local testname=jobid_var
27664         fi
27665
27666         local jobid_var_old=$($LCTL get_param -n $testname)
27667         local jobid_var_new
27668
27669         $LCTL set_param $testname= &&
27670                 error "no error returned for 'set_param a='"
27671
27672         jobid_var_new=$($LCTL get_param -n $testname)
27673         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27674                 error "$testname was changed by setting without value"
27675
27676         $LCTL set_param $testname &&
27677                 error "no error returned for 'set_param a'"
27678
27679         jobid_var_new=$($LCTL get_param -n $testname)
27680         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
27681                 error "$testname was changed by setting without value"
27682 }
27683 run_test 401c "Verify 'lctl set_param' without value fails in either format."
27684
27685 test_401d() {
27686         # jobid_var may not allow arbitrary values, so use jobid_name
27687         # if available
27688         if $LCTL list_param jobid_name > /dev/null 2>&1; then
27689                 local testname=jobid_name new_value='foo=bar%p'
27690         else
27691                 local testname=jobid_var new_valuie=foo=bar
27692         fi
27693
27694         local jobid_var_old=$($LCTL get_param -n $testname)
27695         local jobid_var_new
27696
27697         $LCTL set_param $testname=$new_value ||
27698                 error "'set_param a=b' did not accept a value containing '='"
27699
27700         jobid_var_new=$($LCTL get_param -n $testname)
27701         [[ "$jobid_var_new" == "$new_value" ]] ||
27702                 error "'set_param a=b' failed on a value containing '='"
27703
27704         # Reset the $testname to test the other format
27705         $LCTL set_param $testname=$jobid_var_old
27706         jobid_var_new=$($LCTL get_param -n $testname)
27707         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27708                 error "failed to reset $testname"
27709
27710         $LCTL set_param $testname $new_value ||
27711                 error "'set_param a b' did not accept a value containing '='"
27712
27713         jobid_var_new=$($LCTL get_param -n $testname)
27714         [[ "$jobid_var_new" == "$new_value" ]] ||
27715                 error "'set_param a b' failed on a value containing '='"
27716
27717         $LCTL set_param $testname $jobid_var_old
27718         jobid_var_new=$($LCTL get_param -n $testname)
27719         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
27720                 error "failed to reset $testname"
27721 }
27722 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
27723
27724 test_401e() { # LU-14779
27725         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
27726                 error "lctl list_param MGC* failed"
27727         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
27728         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
27729                 error "lctl get_param lru_size failed"
27730 }
27731 run_test 401e "verify 'lctl get_param' works with NID in parameter"
27732
27733 test_402() {
27734         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
27735         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
27736                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
27737         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
27738                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
27739                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
27740         remote_mds_nodsh && skip "remote MDS with nodsh"
27741
27742         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
27743 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
27744         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
27745         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
27746                 echo "Touch failed - OK"
27747 }
27748 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
27749
27750 test_403() {
27751         local file1=$DIR/$tfile.1
27752         local file2=$DIR/$tfile.2
27753         local tfile=$TMP/$tfile
27754
27755         rm -f $file1 $file2 $tfile
27756
27757         touch $file1
27758         ln $file1 $file2
27759
27760         # 30 sec OBD_TIMEOUT in ll_getattr()
27761         # right before populating st_nlink
27762         $LCTL set_param fail_loc=0x80001409
27763         stat -c %h $file1 > $tfile &
27764
27765         # create an alias, drop all locks and reclaim the dentry
27766         < $file2
27767         cancel_lru_locks mdc
27768         cancel_lru_locks osc
27769         sysctl -w vm.drop_caches=2
27770
27771         wait
27772
27773         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
27774
27775         rm -f $tfile $file1 $file2
27776 }
27777 run_test 403 "i_nlink should not drop to zero due to aliasing"
27778
27779 test_404() { # LU-6601
27780         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
27781                 skip "Need server version newer than 2.8.52"
27782         remote_mds_nodsh && skip "remote MDS with nodsh"
27783
27784         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
27785                 awk '/osp .*-osc-MDT/ { print $4}')
27786
27787         local osp
27788         for osp in $mosps; do
27789                 echo "Deactivate: " $osp
27790                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
27791                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27792                         awk -vp=$osp '$4 == p { print $2 }')
27793                 [ $stat = IN ] || {
27794                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27795                         error "deactivate error"
27796                 }
27797                 echo "Activate: " $osp
27798                 do_facet $SINGLEMDS $LCTL --device %$osp activate
27799                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
27800                         awk -vp=$osp '$4 == p { print $2 }')
27801                 [ $stat = UP ] || {
27802                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
27803                         error "activate error"
27804                 }
27805         done
27806 }
27807 run_test 404 "validate manual {de}activated works properly for OSPs"
27808
27809 test_405() {
27810         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
27811         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
27812                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
27813                         skip "Layout swap lock is not supported"
27814
27815         check_swap_layouts_support
27816         check_swap_layout_no_dom $DIR
27817
27818         test_mkdir $DIR/$tdir
27819         swap_lock_test -d $DIR/$tdir ||
27820                 error "One layout swap locked test failed"
27821 }
27822 run_test 405 "Various layout swap lock tests"
27823
27824 test_406() {
27825         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27826         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
27827         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
27828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27829         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
27830                 skip "Need MDS version at least 2.8.50"
27831
27832         local def_stripe_size=$($LFS getstripe -S $MOUNT)
27833         local test_pool=$TESTNAME
27834
27835         pool_add $test_pool || error "pool_add failed"
27836         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
27837                 error "pool_add_targets failed"
27838
27839         save_layout_restore_at_exit $MOUNT
27840
27841         # parent set default stripe count only, child will stripe from both
27842         # parent and fs default
27843         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
27844                 error "setstripe $MOUNT failed"
27845         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
27846         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
27847         for i in $(seq 10); do
27848                 local f=$DIR/$tdir/$tfile.$i
27849                 touch $f || error "touch failed"
27850                 local count=$($LFS getstripe -c $f)
27851                 [ $count -eq $OSTCOUNT ] ||
27852                         error "$f stripe count $count != $OSTCOUNT"
27853                 local offset=$($LFS getstripe -i $f)
27854                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
27855                 local size=$($LFS getstripe -S $f)
27856                 [ $size -eq $((def_stripe_size * 2)) ] ||
27857                         error "$f stripe size $size != $((def_stripe_size * 2))"
27858                 local pool=$($LFS getstripe -p $f)
27859                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
27860         done
27861
27862         # change fs default striping, delete parent default striping, now child
27863         # will stripe from new fs default striping only
27864         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
27865                 error "change $MOUNT default stripe failed"
27866         $LFS setstripe -c 0 $DIR/$tdir ||
27867                 error "delete $tdir default stripe failed"
27868         for i in $(seq 11 20); do
27869                 local f=$DIR/$tdir/$tfile.$i
27870                 touch $f || error "touch $f failed"
27871                 local count=$($LFS getstripe -c $f)
27872                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
27873                 local offset=$($LFS getstripe -i $f)
27874                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
27875                 local size=$($LFS getstripe -S $f)
27876                 [ $size -eq $def_stripe_size ] ||
27877                         error "$f stripe size $size != $def_stripe_size"
27878                 local pool=$($LFS getstripe -p $f)
27879                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
27880         done
27881
27882         unlinkmany $DIR/$tdir/$tfile. 1 20
27883
27884         local f=$DIR/$tdir/$tfile
27885         pool_remove_all_targets $test_pool $f
27886         pool_remove $test_pool $f
27887 }
27888 run_test 406 "DNE support fs default striping"
27889
27890 test_407() {
27891         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27892         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
27893                 skip "Need MDS version at least 2.8.55"
27894         remote_mds_nodsh && skip "remote MDS with nodsh"
27895
27896         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
27897                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
27898         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
27899                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
27900         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
27901
27902         #define OBD_FAIL_DT_TXN_STOP    0x2019
27903         for idx in $(seq $MDSCOUNT); do
27904                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
27905         done
27906         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
27907         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
27908                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
27909         true
27910 }
27911 run_test 407 "transaction fail should cause operation fail"
27912
27913 test_408() {
27914         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
27915
27916         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
27917         lctl set_param fail_loc=0x8000040a
27918         # let ll_prepare_partial_page() fail
27919         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
27920
27921         rm -f $DIR/$tfile
27922
27923         # create at least 100 unused inodes so that
27924         # shrink_icache_memory(0) should not return 0
27925         touch $DIR/$tfile-{0..100}
27926         rm -f $DIR/$tfile-{0..100}
27927         sync
27928
27929         echo 2 > /proc/sys/vm/drop_caches
27930 }
27931 run_test 408 "drop_caches should not hang due to page leaks"
27932
27933 test_409()
27934 {
27935         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27936
27937         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
27938         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
27939         touch $DIR/$tdir/guard || error "(2) Fail to create"
27940
27941         local PREFIX=$(str_repeat 'A' 128)
27942         echo "Create 1K hard links start at $(date)"
27943         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27944                 error "(3) Fail to hard link"
27945
27946         echo "Links count should be right although linkEA overflow"
27947         stat $DIR/$tdir/guard || error "(4) Fail to stat"
27948         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
27949         [ $linkcount -eq 1001 ] ||
27950                 error "(5) Unexpected hard links count: $linkcount"
27951
27952         echo "List all links start at $(date)"
27953         ls -l $DIR/$tdir/foo > /dev/null ||
27954                 error "(6) Fail to list $DIR/$tdir/foo"
27955
27956         echo "Unlink hard links start at $(date)"
27957         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
27958                 error "(7) Fail to unlink"
27959         echo "Unlink hard links finished at $(date)"
27960 }
27961 run_test 409 "Large amount of cross-MDTs hard links on the same file"
27962
27963 test_410()
27964 {
27965         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
27966                 skip "Need client version at least 2.9.59"
27967         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
27968                 skip "Need MODULES build"
27969
27970         # Create a file, and stat it from the kernel
27971         local testfile=$DIR/$tfile
27972         touch $testfile
27973
27974         local run_id=$RANDOM
27975         local my_ino=$(stat --format "%i" $testfile)
27976
27977         # Try to insert the module. This will always fail as the
27978         # module is designed to not be inserted.
27979         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
27980             &> /dev/null
27981
27982         # Anything but success is a test failure
27983         dmesg | grep -q \
27984             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
27985             error "no inode match"
27986 }
27987 run_test 410 "Test inode number returned from kernel thread"
27988
27989 cleanup_test411_cgroup() {
27990         trap 0
27991         cat $1/memory.stat
27992         rmdir "$1"
27993 }
27994
27995 test_411a() {
27996         local cg_basedir=/sys/fs/cgroup/memory
27997         # LU-9966
27998         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
27999                 skip "no setup for cgroup"
28000
28001         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
28002                 error "test file creation failed"
28003         cancel_lru_locks osc
28004
28005         # Create a very small memory cgroup to force a slab allocation error
28006         local cgdir=$cg_basedir/osc_slab_alloc
28007         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28008         trap "cleanup_test411_cgroup $cgdir" EXIT
28009         echo 2M > $cgdir/memory.kmem.limit_in_bytes
28010         echo 1M > $cgdir/memory.limit_in_bytes
28011
28012         # Should not LBUG, just be killed by oom-killer
28013         # dd will return 0 even allocation failure in some environment.
28014         # So don't check return value
28015         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
28016         cleanup_test411_cgroup $cgdir
28017
28018         return 0
28019 }
28020 run_test 411a "Slab allocation error with cgroup does not LBUG"
28021
28022 test_411b() {
28023         local cg_basedir=/sys/fs/cgroup/memory
28024         # LU-9966
28025         [ -e "$cg_basedir/memory.kmem.limit_in_bytes" ] ||
28026                 skip "no setup for cgroup"
28027         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28028         # (x86) testing suggests we can't reliably avoid OOM with a 64M-256M
28029         # limit, so we have 384M in cgroup
28030         # (arm) this seems to hit OOM more often than x86, so 1024M
28031         if [[ $(uname -m) = aarch64 ]]; then
28032                 local memlimit_mb=1024
28033         else
28034                 local memlimit_mb=384
28035         fi
28036
28037         # Create a cgroup and set memory limit
28038         # (tfile is used as an easy way to get a recognizable cgroup name)
28039         local cgdir=$cg_basedir/$tfile
28040         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
28041         stack_trap "cleanup_test411_cgroup $cgdir" EXIT
28042         echo $((memlimit_mb * 1024 * 1024)) > $cgdir/memory.limit_in_bytes
28043
28044         echo "writing first file"
28045         # Write a file 4x the memory limit in size
28046         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=1M count=$((memlimit_mb * 4))" ||
28047                 error "(1) failed to write successfully"
28048
28049         sync
28050         cancel_lru_locks osc
28051
28052         rm -f $DIR/$tfile
28053         $LFS setstripe -c 2 $DIR/$tfile || error "unable to setstripe"
28054
28055         # Try writing at a larger block size
28056         # NB: if block size is >= 1/2 cgroup size, we sometimes get OOM killed
28057         # so test with 1/4 cgroup size (this seems reasonable to me - we do
28058         # need *some* memory to do IO in)
28059         echo "writing at larger block size"
28060         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile bs=64M count=$((memlimit_mb * 4 / 128))" ||
28061                 error "(3) failed to write successfully"
28062
28063         sync
28064         cancel_lru_locks osc
28065         rm -f $DIR/$tfile
28066         $LFS setstripe -c 2 $DIR/$tfile.{1..4} || error "unable to setstripe"
28067
28068         # Try writing multiple files at once
28069         echo "writing multiple files"
28070         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.1 bs=32M count=$((memlimit_mb * 4 / 64))" &
28071         local pid1=$!
28072         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.2 bs=32M count=$((memlimit_mb * 4 / 64))" &
28073         local pid2=$!
28074         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.3 bs=32M count=$((memlimit_mb * 4 / 64))" &
28075         local pid3=$!
28076         bash -c "echo \$$ > $cgdir/tasks && dd if=/dev/zero of=$DIR/$tfile.4 bs=32M count=$((memlimit_mb * 4 / 64))" &
28077         local pid4=$!
28078
28079         wait $pid1
28080         local rc1=$?
28081         wait $pid2
28082         local rc2=$?
28083         wait $pid3
28084         local rc3=$?
28085         wait $pid4
28086         local rc4=$?
28087         if (( rc1 != 0)); then
28088                 error "error $rc1 writing to file from $pid1"
28089         fi
28090         if (( rc2 != 0)); then
28091                 error "error $rc2 writing to file from $pid2"
28092         fi
28093         if (( rc3 != 0)); then
28094                 error "error $rc3 writing to file from $pid3"
28095         fi
28096         if (( rc4 != 0)); then
28097                 error "error $rc4 writing to file from $pid4"
28098         fi
28099
28100         sync
28101         cancel_lru_locks osc
28102
28103         # These files can be large-ish (~1 GiB total), so delete them rather
28104         # than leave for later cleanup
28105         rm -f $DIR/$tfile.*
28106         return 0
28107 }
28108 run_test 411b "confirm Lustre can avoid OOM with reasonable cgroups limits"
28109
28110 test_412() {
28111         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28112         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
28113                 skip "Need server version at least 2.10.55"
28114
28115         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
28116                 error "mkdir failed"
28117         $LFS getdirstripe $DIR/$tdir
28118         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
28119         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
28120                 error "expect $((MDSCOUT - 1)) get $stripe_index"
28121         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
28122         [ $stripe_count -eq 2 ] ||
28123                 error "expect 2 get $stripe_count"
28124
28125         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
28126
28127         local index
28128         local index2
28129
28130         # subdirs should be on the same MDT as parent
28131         for i in $(seq 0 $((MDSCOUNT - 1))); do
28132                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
28133                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
28134                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
28135                 (( index == i )) || error "mdt$i/sub on MDT$index"
28136         done
28137
28138         # stripe offset -1, ditto
28139         for i in {1..10}; do
28140                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
28141                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
28142                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
28143                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
28144                 (( index == index2 )) ||
28145                         error "qos$i on MDT$index, sub on MDT$index2"
28146         done
28147
28148         local testdir=$DIR/$tdir/inherit
28149
28150         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
28151         # inherit 2 levels
28152         for i in 1 2; do
28153                 testdir=$testdir/s$i
28154                 mkdir $testdir || error "mkdir $testdir failed"
28155                 index=$($LFS getstripe -m $testdir)
28156                 (( index == 1 )) ||
28157                         error "$testdir on MDT$index"
28158         done
28159
28160         # not inherit any more
28161         testdir=$testdir/s3
28162         mkdir $testdir || error "mkdir $testdir failed"
28163         getfattr -d -m dmv $testdir | grep dmv &&
28164                 error "default LMV set on $testdir" || true
28165 }
28166 run_test 412 "mkdir on specific MDTs"
28167
28168 TEST413_COUNT=${TEST413_COUNT:-200}
28169
28170 #
28171 # set_maxage() is used by test_413 only.
28172 # This is a helper function to set maxage. Does not return any value.
28173 # Input: maxage to set
28174 #
28175 set_maxage() {
28176         local lmv_qos_maxage
28177         local lod_qos_maxage
28178         local new_maxage=$1
28179
28180         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28181         $LCTL set_param lmv.*.qos_maxage=$new_maxage
28182         stack_trap "$LCTL set_param \
28183                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28184         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28185                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28186         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28187                 lod.*.mdt_qos_maxage=$new_maxage
28188         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28189                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
28190 }
28191
28192 generate_uneven_mdts() {
28193         local threshold=$1
28194         local ffree
28195         local bavail
28196         local max
28197         local min
28198         local max_index
28199         local min_index
28200         local tmp
28201         local i
28202
28203         echo
28204         echo "Check for uneven MDTs: "
28205
28206         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28207         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28208         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28209
28210         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28211         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28212         max_index=0
28213         min_index=0
28214         for ((i = 1; i < ${#ffree[@]}; i++)); do
28215                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28216                 if [ $tmp -gt $max ]; then
28217                         max=$tmp
28218                         max_index=$i
28219                 fi
28220                 if [ $tmp -lt $min ]; then
28221                         min=$tmp
28222                         min_index=$i
28223                 fi
28224         done
28225
28226         (( min > 0 )) || skip "low space on MDT$min_index"
28227         (( ${ffree[min_index]} > 0 )) ||
28228                 skip "no free files on MDT$min_index"
28229         (( ${ffree[min_index]} < 10000000 )) ||
28230                 skip "too many free files on MDT$min_index"
28231
28232         # Check if we need to generate uneven MDTs
28233         local diff=$(((max - min) * 100 / min))
28234         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
28235         local testdir # individual folder within $testdirp
28236         local start
28237         local cmd
28238
28239         # fallocate is faster to consume space on MDT, if available
28240         if check_fallocate_supported mds$((min_index + 1)); then
28241                 cmd="fallocate -l 128K "
28242         else
28243                 cmd="dd if=/dev/zero bs=128K count=1 of="
28244         fi
28245
28246         echo "using cmd $cmd"
28247         for (( i = 0; diff < threshold; i++ )); do
28248                 testdir=${testdirp}/$i
28249                 [ -d $testdir ] && continue
28250
28251                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
28252
28253                 mkdir -p $testdirp
28254                 # generate uneven MDTs, create till $threshold% diff
28255                 echo -n "weight diff=$diff% must be > $threshold% ..."
28256                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
28257                 $LFS mkdir -i $min_index $testdir ||
28258                         error "mkdir $testdir failed"
28259                 $LFS setstripe -E 1M -L mdt $testdir ||
28260                         error "setstripe $testdir failed"
28261                 start=$SECONDS
28262                 for (( f = 0; f < TEST413_COUNT; f++ )); do
28263                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
28264                 done
28265                 sync; sleep 1; sync
28266
28267                 # wait for QOS to update
28268                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
28269
28270                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
28271                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
28272                 max=$(((${ffree[max_index]} >> 8) *
28273                         (${bavail[max_index]} * bsize >> 16)))
28274                 min=$(((${ffree[min_index]} >> 8) *
28275                         (${bavail[min_index]} * bsize >> 16)))
28276                 (( min > 0 )) || skip "low space on MDT$min_index"
28277                 diff=$(((max - min) * 100 / min))
28278         done
28279
28280         echo "MDT filesfree available: ${ffree[*]}"
28281         echo "MDT blocks available: ${bavail[*]}"
28282         echo "weight diff=$diff%"
28283 }
28284
28285 test_qos_mkdir() {
28286         local mkdir_cmd=$1
28287         local stripe_count=$2
28288         local mdts=$(comma_list $(mdts_nodes))
28289
28290         local testdir
28291         local lmv_qos_prio_free
28292         local lmv_qos_threshold_rr
28293         local lod_qos_prio_free
28294         local lod_qos_threshold_rr
28295         local total
28296         local count
28297         local i
28298
28299         # @total is total directories created if it's testing plain
28300         # directories, otherwise it's total stripe object count for
28301         # striped directories test.
28302         # remote/striped directory unlinking is slow on zfs and may
28303         # timeout, test with fewer directories
28304         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
28305
28306         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
28307         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
28308         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28309                 head -n1)
28310         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
28311         stack_trap "$LCTL set_param \
28312                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
28313         stack_trap "$LCTL set_param \
28314                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
28315
28316         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
28317                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
28318         lod_qos_prio_free=${lod_qos_prio_free%%%}
28319         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
28320                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
28321         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
28322         stack_trap "do_nodes $mdts $LCTL set_param \
28323                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
28324         stack_trap "do_nodes $mdts $LCTL set_param \
28325                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
28326
28327         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28328         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
28329
28330         testdir=$DIR/$tdir-s$stripe_count/rr
28331
28332         local stripe_index=$($LFS getstripe -m $testdir)
28333         local test_mkdir_rr=true
28334
28335         getfattr -d -m dmv -e hex $testdir | grep dmv
28336         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
28337                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
28338                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
28339                         test_mkdir_rr=false
28340         fi
28341
28342         echo
28343         $test_mkdir_rr &&
28344                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
28345                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
28346
28347         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28348         for (( i = 0; i < total / stripe_count; i++ )); do
28349                 eval $mkdir_cmd $testdir/subdir$i ||
28350                         error "$mkdir_cmd subdir$i failed"
28351         done
28352
28353         for (( i = 0; i < $MDSCOUNT; i++ )); do
28354                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28355                 echo "$count directories created on MDT$i"
28356                 if $test_mkdir_rr; then
28357                         (( count == total / stripe_count / MDSCOUNT )) ||
28358                                 error "subdirs are not evenly distributed"
28359                 elif (( i == stripe_index )); then
28360                         (( count == total / stripe_count )) ||
28361                                 error "$count subdirs created on MDT$i"
28362                 else
28363                         (( count == 0 )) ||
28364                                 error "$count subdirs created on MDT$i"
28365                 fi
28366
28367                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
28368                         count=$($LFS getdirstripe $testdir/* |
28369                                 grep -c -P "^\s+$i\t")
28370                         echo "$count stripes created on MDT$i"
28371                         # deviation should < 5% of average
28372                         delta=$((count - total / MDSCOUNT))
28373                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
28374                                 error "stripes are not evenly distributed"
28375                 fi
28376         done
28377
28378         echo
28379         echo "Check for uneven MDTs: "
28380
28381         local ffree
28382         local bavail
28383         local max
28384         local min
28385         local max_index
28386         local min_index
28387         local tmp
28388
28389         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28390         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28391         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28392
28393         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28394         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28395         max_index=0
28396         min_index=0
28397         for ((i = 1; i < ${#ffree[@]}; i++)); do
28398                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28399                 if [ $tmp -gt $max ]; then
28400                         max=$tmp
28401                         max_index=$i
28402                 fi
28403                 if [ $tmp -lt $min ]; then
28404                         min=$tmp
28405                         min_index=$i
28406                 fi
28407         done
28408         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
28409
28410         (( min > 0 )) || skip "low space on MDT$min_index"
28411         (( ${ffree[min_index]} < 10000000 )) ||
28412                 skip "too many free files on MDT$min_index"
28413
28414         generate_uneven_mdts 120
28415
28416         echo "MDT filesfree available: ${ffree[*]}"
28417         echo "MDT blocks available: ${bavail[*]}"
28418         echo "weight diff=$(((max - min) * 100 / min))%"
28419         echo
28420         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
28421
28422         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
28423         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
28424         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
28425         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
28426         # decrease statfs age, so that it can be updated in time
28427         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
28428         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
28429
28430         sleep 1
28431
28432         testdir=$DIR/$tdir-s$stripe_count/qos
28433
28434         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
28435         for (( i = 0; i < total / stripe_count; i++ )); do
28436                 eval $mkdir_cmd $testdir/subdir$i ||
28437                         error "$mkdir_cmd subdir$i failed"
28438         done
28439
28440         max=0
28441         for (( i = 0; i < $MDSCOUNT; i++ )); do
28442                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
28443                 (( count > max )) && max=$count
28444                 echo "$count directories created on MDT$i : curmax=$max"
28445         done
28446
28447         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
28448
28449         # D-value should > 10% of average
28450         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
28451                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
28452
28453         # ditto for stripes
28454         if (( stripe_count > 1 )); then
28455                 max=0
28456                 for (( i = 0; i < $MDSCOUNT; i++ )); do
28457                         count=$($LFS getdirstripe $testdir/* |
28458                                 grep -c -P "^\s+$i\t")
28459                         (( count > max )) && max=$count
28460                         echo "$count stripes created on MDT$i"
28461                 done
28462
28463                 min=$($LFS getdirstripe $testdir/* |
28464                         grep -c -P "^\s+$min_index\t")
28465                 (( max - min > total / MDSCOUNT / 10 )) ||
28466                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
28467         fi
28468 }
28469
28470 most_full_mdt() {
28471         local ffree
28472         local bavail
28473         local bsize
28474         local min
28475         local min_index
28476         local tmp
28477
28478         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
28479         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
28480         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
28481
28482         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
28483         min_index=0
28484         for ((i = 1; i < ${#ffree[@]}; i++)); do
28485                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
28486                 (( tmp < min )) && min=$tmp && min_index=$i
28487         done
28488
28489         echo -n $min_index
28490 }
28491
28492 test_413a() {
28493         [ $MDSCOUNT -lt 2 ] &&
28494                 skip "We need at least 2 MDTs for this test"
28495
28496         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28497                 skip "Need server version at least 2.12.52"
28498
28499         local stripe_max=$((MDSCOUNT - 1))
28500         local stripe_count
28501
28502         # let caller set maxage for latest result
28503         set_maxage 1
28504
28505         # fill MDT unevenly
28506         generate_uneven_mdts 120
28507
28508         # test 4-stripe directory at most, otherwise it's too slow
28509         # We are being very defensive. Although Autotest uses 4 MDTs.
28510         # We make sure stripe_max does not go over 4.
28511         (( stripe_max > 4 )) && stripe_max=4
28512         # unlinking striped directory is slow on zfs, and may timeout, only test
28513         # plain directory
28514         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28515         for stripe_count in $(seq 1 $stripe_max); do
28516                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
28517                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
28518                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
28519                         error "mkdir failed"
28520                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
28521         done
28522 }
28523 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
28524
28525 test_413b() {
28526         [ $MDSCOUNT -lt 2 ] &&
28527                 skip "We need at least 2 MDTs for this test"
28528
28529         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
28530                 skip "Need server version at least 2.12.52"
28531
28532         local stripe_max=$((MDSCOUNT - 1))
28533         local testdir
28534         local stripe_count
28535
28536         # let caller set maxage for latest result
28537         set_maxage 1
28538
28539         # fill MDT unevenly
28540         generate_uneven_mdts 120
28541
28542         # test 4-stripe directory at most, otherwise it's too slow
28543         # We are being very defensive. Although Autotest uses 4 MDTs.
28544         # We make sure stripe_max does not go over 4.
28545         (( stripe_max > 4 )) && stripe_max=4
28546         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
28547         for stripe_count in $(seq 1 $stripe_max); do
28548                 testdir=$DIR/$tdir-s$stripe_count
28549                 mkdir $testdir || error "mkdir $testdir failed"
28550                 mkdir $testdir/rr || error "mkdir rr failed"
28551                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
28552                         error "mkdir qos failed"
28553                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
28554                         $testdir/rr || error "setdirstripe rr failed"
28555                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
28556                         error "setdirstripe failed"
28557                 test_qos_mkdir "mkdir" $stripe_count
28558         done
28559 }
28560 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
28561
28562 test_413c() {
28563         (( $MDSCOUNT >= 2 )) ||
28564                 skip "We need at least 2 MDTs for this test"
28565
28566         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
28567                 skip "Need server version at least 2.14.51"
28568
28569         local testdir
28570         local inherit
28571         local inherit_rr
28572         local lmv_qos_maxage
28573         local lod_qos_maxage
28574
28575         # let caller set maxage for latest result
28576         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28577         $LCTL set_param lmv.*.qos_maxage=1
28578         stack_trap "$LCTL set_param \
28579                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
28580         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
28581                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
28582         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28583                 lod.*.mdt_qos_maxage=1
28584         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
28585                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
28586
28587         # fill MDT unevenly
28588         generate_uneven_mdts 120
28589
28590         testdir=$DIR/${tdir}-s1
28591         mkdir $testdir || error "mkdir $testdir failed"
28592         mkdir $testdir/rr || error "mkdir rr failed"
28593         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
28594         # default max_inherit is -1, default max_inherit_rr is 0
28595         $LFS setdirstripe -D -c 1 $testdir/rr ||
28596                 error "setdirstripe rr failed"
28597         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
28598                 error "setdirstripe qos failed"
28599         test_qos_mkdir "mkdir" 1
28600
28601         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
28602         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
28603         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
28604         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
28605         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
28606
28607         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
28608         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
28609         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
28610         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
28611         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
28612         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
28613         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
28614                 error "level2 shouldn't have default LMV" || true
28615 }
28616 run_test 413c "mkdir with default LMV max inherit rr"
28617
28618 test_413d() {
28619         (( MDSCOUNT >= 2 )) ||
28620                 skip "We need at least 2 MDTs for this test"
28621
28622         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
28623                 skip "Need server version at least 2.14.51"
28624
28625         local lmv_qos_threshold_rr
28626
28627         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
28628                 head -n1)
28629         stack_trap "$LCTL set_param \
28630                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
28631
28632         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
28633         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28634         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
28635                 error "$tdir shouldn't have default LMV"
28636         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
28637                 error "mkdir sub failed"
28638
28639         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
28640
28641         (( count == 100 )) || error "$count subdirs on MDT0"
28642 }
28643 run_test 413d "inherit ROOT default LMV"
28644
28645 test_413e() {
28646         (( MDSCOUNT >= 2 )) ||
28647                 skip "We need at least 2 MDTs for this test"
28648         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28649                 skip "Need server version at least 2.14.55"
28650
28651         local testdir=$DIR/$tdir
28652         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
28653         local max_inherit
28654         local sub_max_inherit
28655
28656         mkdir -p $testdir || error "failed to create $testdir"
28657
28658         # set default max-inherit to -1 if stripe count is 0 or 1
28659         $LFS setdirstripe -D -c 1 $testdir ||
28660                 error "failed to set default LMV"
28661         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28662         (( max_inherit == -1 )) ||
28663                 error "wrong max_inherit value $max_inherit"
28664
28665         # set default max_inherit to a fixed value if stripe count is not 0 or 1
28666         $LFS setdirstripe -D -c -1 $testdir ||
28667                 error "failed to set default LMV"
28668         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28669         (( max_inherit > 0 )) ||
28670                 error "wrong max_inherit value $max_inherit"
28671
28672         # and the subdir will decrease the max_inherit by 1
28673         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
28674         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
28675         (( sub_max_inherit == max_inherit - 1)) ||
28676                 error "wrong max-inherit of subdir $sub_max_inherit"
28677
28678         # check specified --max-inherit and warning message
28679         stack_trap "rm -f $tmpfile"
28680         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
28681                 error "failed to set default LMV"
28682         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
28683         (( max_inherit == -1 )) ||
28684                 error "wrong max_inherit value $max_inherit"
28685
28686         # check the warning messages
28687         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
28688                 error "failed to detect warning string"
28689         fi
28690 }
28691 run_test 413e "check default max-inherit value"
28692
28693 test_fs_dmv_inherit()
28694 {
28695         local testdir=$DIR/$tdir
28696
28697         local count
28698         local inherit
28699         local inherit_rr
28700
28701         for i in 1 2; do
28702                 mkdir $testdir || error "mkdir $testdir failed"
28703                 count=$($LFS getdirstripe -D -c $testdir)
28704                 (( count == 1 )) ||
28705                         error "$testdir default LMV count mismatch $count != 1"
28706                 inherit=$($LFS getdirstripe -D -X $testdir)
28707                 (( inherit == 3 - i )) ||
28708                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
28709                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28710                 (( inherit_rr == 3 - i )) ||
28711                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
28712                 testdir=$testdir/sub
28713         done
28714
28715         mkdir $testdir || error "mkdir $testdir failed"
28716         count=$($LFS getdirstripe -D -c $testdir)
28717         (( count == 0 )) ||
28718                 error "$testdir default LMV count not zero: $count"
28719 }
28720
28721 test_413f() {
28722         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28723
28724         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28725                 skip "Need server version at least 2.14.55"
28726
28727         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28728                 error "dump $DIR default LMV failed"
28729         stack_trap "setfattr --restore=$TMP/dmv.ea"
28730
28731         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28732                 error "set $DIR default LMV failed"
28733
28734         test_fs_dmv_inherit
28735 }
28736 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
28737
28738 test_413g() {
28739         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
28740
28741         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
28742         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28743                 error "dump $DIR default LMV failed"
28744         stack_trap "setfattr --restore=$TMP/dmv.ea"
28745
28746         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
28747                 error "set $DIR default LMV failed"
28748
28749         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
28750                 error "mount $MOUNT2 failed"
28751         stack_trap "umount_client $MOUNT2"
28752
28753         local saved_DIR=$DIR
28754
28755         export DIR=$MOUNT2
28756
28757         stack_trap "export DIR=$saved_DIR"
28758
28759         # first check filesystem-wide default LMV inheritance
28760         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
28761
28762         # then check subdirs are spread to all MDTs
28763         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
28764
28765         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
28766
28767         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
28768 }
28769 run_test 413g "enforce ROOT default LMV on subdir mount"
28770
28771 test_413h() {
28772         (( MDSCOUNT >= 2 )) ||
28773                 skip "We need at least 2 MDTs for this test"
28774
28775         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
28776                 skip "Need server version at least 2.15.50.6"
28777
28778         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
28779
28780         stack_trap "$LCTL set_param \
28781                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
28782         $LCTL set_param lmv.*.qos_maxage=1
28783
28784         local depth=5
28785         local rr_depth=4
28786         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
28787         local count=$((MDSCOUNT * 20))
28788
28789         generate_uneven_mdts 50
28790
28791         mkdir -p $dir || error "mkdir $dir failed"
28792         stack_trap "rm -rf $dir"
28793         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
28794                 --max-inherit-rr=$rr_depth $dir
28795
28796         for ((d=0; d < depth + 2; d++)); do
28797                 log "dir=$dir:"
28798                 for ((sub=0; sub < count; sub++)); do
28799                         mkdir $dir/d$sub
28800                 done
28801                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
28802                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
28803                 # subdirs within $rr_depth should be created round-robin
28804                 if (( d < rr_depth )); then
28805                         (( ${num[0]} != count )) ||
28806                                 error "all objects created on MDT ${num[1]}"
28807                 fi
28808
28809                 dir=$dir/d0
28810         done
28811 }
28812 run_test 413h "don't stick to parent for round-robin dirs"
28813
28814 test_413i() {
28815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
28816
28817         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
28818                 skip "Need server version at least 2.14.55"
28819
28820         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
28821                 error "dump $DIR default LMV failed"
28822         stack_trap "setfattr --restore=$TMP/dmv.ea"
28823
28824         local testdir=$DIR/$tdir
28825         local def_max_rr=1
28826         local def_max=3
28827         local count
28828
28829         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
28830                 --max-inherit-rr=$def_max_rr $DIR ||
28831                 error "set $DIR default LMV failed"
28832
28833         for i in $(seq 2 3); do
28834                 def_max=$((def_max - 1))
28835                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
28836
28837                 mkdir $testdir
28838                 # RR is decremented and keeps zeroed once exhausted
28839                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
28840                 (( count == def_max_rr )) ||
28841                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
28842
28843                 # max-inherit is decremented
28844                 count=$($LFS getdirstripe -D --max-inherit $testdir)
28845                 (( count == def_max )) ||
28846                         error_noexit "$testdir: max-inherit $count != $def_max"
28847
28848                 testdir=$testdir/d$i
28849         done
28850
28851         # d3 is the last inherited from ROOT, no inheritance anymore
28852         # i.e. no the default layout anymore
28853         mkdir -p $testdir/d4/d5
28854         count=$($LFS getdirstripe -D --max-inherit $testdir)
28855         (( count == -1 )) ||
28856                 error_noexit "$testdir: max-inherit $count != -1"
28857
28858         local p_count=$($LFS getdirstripe -i $testdir)
28859
28860         for i in $(seq 4 5); do
28861                 testdir=$testdir/d$i
28862
28863                 # the root default layout is not applied once exhausted
28864                 count=$($LFS getdirstripe -i $testdir)
28865                 (( count == p_count )) ||
28866                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
28867         done
28868
28869         $LFS setdirstripe -i 0 $DIR/d2
28870         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
28871         (( count == -1 )) ||
28872                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
28873 }
28874 run_test 413i "check default layout inheritance"
28875
28876 test_413j()
28877 {
28878         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
28879
28880         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
28881         $LFS setdirstripe -D -c2 --max-inherit=2 $DIR/$tdir ||
28882                 error "setdirstripe $tdir failed"
28883
28884         local value=$(getfattr -n trusted.dmv $DIR/$tdir | \
28885                       grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28886
28887         mkdir -p $DIR/$tdir/sub || error "mkdir sub failed"
28888         # setfattr dmv calls setdirstripe -D
28889         setfattr -n trusted.dmv -v $value $DIR/$tdir/sub ||
28890                 error "setfattr sub failed"
28891         local value2=$(getfattr -n trusted.dmv $DIR/$tdir/sub | \
28892                        grep "trusted.dmv" |sed -e 's/[^=]\+=//')
28893
28894         [ $value == $value2 ] || error "dmv mismatch"
28895
28896         (( MDS1_VERSION >= $(version_code 2.15.58) )) || return 0
28897
28898         # do not allow remove dmv by setfattr -x
28899         do_nodes $(comma_list $(mdts_nodes)) \
28900                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28901         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28902         getfattr -n trusted.dmv $DIR/$tdir/sub || error "default LMV deleted"
28903
28904         # allow remove dmv by setfattr -x
28905         do_nodes $(comma_list $(mdts_nodes)) \
28906                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=1"
28907         setfattr -x trusted.dmv $DIR/$tdir/sub || error "setfattr sub failed"
28908         getfattr -n trusted.dmv $DIR/$tdir/sub && error "default LMV exists"
28909         do_nodes $(comma_list $(mdts_nodes)) \
28910                 "$LCTL set_param -n mdt.*MDT*.enable_dmv_xattr=0"
28911 }
28912 run_test 413j "set default LMV by setxattr"
28913
28914 test_413z() {
28915         local pids=""
28916         local subdir
28917         local pid
28918
28919         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
28920                 unlinkmany $subdir/f. $TEST413_COUNT &
28921                 pids="$pids $!"
28922         done
28923
28924         for pid in $pids; do
28925                 wait $pid
28926         done
28927
28928         true
28929 }
28930 run_test 413z "413 test cleanup"
28931
28932 test_414() {
28933 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
28934         $LCTL set_param fail_loc=0x80000521
28935         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28936         rm -f $DIR/$tfile
28937 }
28938 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
28939
28940 test_415() {
28941         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
28942         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
28943                 skip "Need server version at least 2.11.52"
28944
28945         # LU-11102
28946         local total=500
28947         local max=120
28948
28949         # this test may be slow on ZFS
28950         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
28951
28952         # though this test is designed for striped directory, let's test normal
28953         # directory too since lock is always saved as CoS lock.
28954         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28955         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
28956         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
28957         # if looping with ONLY_REPEAT, wait for previous deletions to finish
28958         wait_delete_completed_mds
28959
28960         # run a loop without concurrent touch to measure rename duration.
28961         # only for test debug/robustness, NOT part of COS functional test.
28962         local start_time=$SECONDS
28963         for ((i = 0; i < total; i++)); do
28964                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
28965                         > /dev/null
28966         done
28967         local baseline=$((SECONDS - start_time))
28968         echo "rename $total files without 'touch' took $baseline sec"
28969
28970         (
28971                 while true; do
28972                         touch $DIR/$tdir
28973                 done
28974         ) &
28975         local setattr_pid=$!
28976
28977         # rename files back to original name so unlinkmany works
28978         start_time=$SECONDS
28979         for ((i = 0; i < total; i++)); do
28980                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
28981                         > /dev/null
28982         done
28983         local duration=$((SECONDS - start_time))
28984
28985         kill -9 $setattr_pid
28986
28987         echo "rename $total files with 'touch' took $duration sec"
28988         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
28989         (( duration <= max )) ||
28990                 error_not_in_vm "rename took $duration > $max sec"
28991 }
28992 run_test 415 "lock revoke is not missing"
28993
28994 test_416() {
28995         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
28996                 skip "Need server version at least 2.11.55"
28997
28998         # define OBD_FAIL_OSD_TXN_START    0x19a
28999         do_facet mds1 lctl set_param fail_loc=0x19a
29000
29001         lfs mkdir -c $MDSCOUNT $DIR/$tdir
29002
29003         true
29004 }
29005 run_test 416 "transaction start failure won't cause system hung"
29006
29007 cleanup_417() {
29008         trap 0
29009         do_nodes $(comma_list $(mdts_nodes)) \
29010                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
29011         do_nodes $(comma_list $(mdts_nodes)) \
29012                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
29013         do_nodes $(comma_list $(mdts_nodes)) \
29014                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
29015 }
29016
29017 test_417() {
29018         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29019         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
29020                 skip "Need MDS version at least 2.11.56"
29021
29022         trap cleanup_417 RETURN EXIT
29023
29024         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
29025         do_nodes $(comma_list $(mdts_nodes)) \
29026                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
29027         $LFS migrate -m 0 $DIR/$tdir.1 &&
29028                 error "migrate dir $tdir.1 should fail"
29029
29030         do_nodes $(comma_list $(mdts_nodes)) \
29031                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
29032         $LFS mkdir -i 1 $DIR/$tdir.2 &&
29033                 error "create remote dir $tdir.2 should fail"
29034
29035         do_nodes $(comma_list $(mdts_nodes)) \
29036                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
29037         $LFS mkdir -c 2 $DIR/$tdir.3 &&
29038                 error "create striped dir $tdir.3 should fail"
29039         true
29040 }
29041 run_test 417 "disable remote dir, striped dir and dir migration"
29042
29043 # Checks that the outputs of df [-i] and lfs df [-i] match
29044 #
29045 # usage: check_lfs_df <blocks | inodes> <mountpoint>
29046 check_lfs_df() {
29047         local dir=$2
29048         local inodes
29049         local df_out
29050         local lfs_df_out
29051         local count
29052         local passed=false
29053
29054         # blocks or inodes
29055         [ "$1" == "blocks" ] && inodes= || inodes="-i"
29056
29057         for count in {1..100}; do
29058                 do_nodes "$CLIENTS" \
29059                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
29060                 sync; sleep 0.2
29061
29062                 # read the lines of interest
29063                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
29064                         error "df $inodes $dir | tail -n +2 failed"
29065                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
29066                         error "lfs df $inodes $dir | grep summary: failed"
29067
29068                 # skip first substrings of each output as they are different
29069                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
29070                 # compare the two outputs
29071                 passed=true
29072                 #  skip "available" on MDT until LU-13997 is fixed.
29073                 #for i in {1..5}; do
29074                 for i in 1 2 4 5; do
29075                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
29076                 done
29077                 $passed && break
29078         done
29079
29080         if ! $passed; then
29081                 df -P $inodes $dir
29082                 echo
29083                 lfs df $inodes $dir
29084                 error "df and lfs df $1 output mismatch: "      \
29085                       "df ${inodes}: ${df_out[*]}, "            \
29086                       "lfs df ${inodes}: ${lfs_df_out[*]}"
29087         fi
29088 }
29089
29090 test_418() {
29091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29092
29093         local dir=$DIR/$tdir
29094         local numfiles=$((RANDOM % 4096 + 2))
29095         local numblocks=$((RANDOM % 256 + 1))
29096
29097         wait_delete_completed
29098         test_mkdir $dir
29099
29100         # check block output
29101         check_lfs_df blocks $dir
29102         # check inode output
29103         check_lfs_df inodes $dir
29104
29105         # create a single file and retest
29106         echo "Creating a single file and testing"
29107         createmany -o $dir/$tfile- 1 &>/dev/null ||
29108                 error "creating 1 file in $dir failed"
29109         check_lfs_df blocks $dir
29110         check_lfs_df inodes $dir
29111
29112         # create a random number of files
29113         echo "Creating $((numfiles - 1)) files and testing"
29114         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
29115                 error "creating $((numfiles - 1)) files in $dir failed"
29116
29117         # write a random number of blocks to the first test file
29118         echo "Writing $numblocks 4K blocks and testing"
29119         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
29120                 count=$numblocks &>/dev/null ||
29121                 error "dd to $dir/${tfile}-0 failed"
29122
29123         # retest
29124         check_lfs_df blocks $dir
29125         check_lfs_df inodes $dir
29126
29127         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
29128                 error "unlinking $numfiles files in $dir failed"
29129 }
29130 run_test 418 "df and lfs df outputs match"
29131
29132 test_419()
29133 {
29134         local dir=$DIR/$tdir
29135
29136         mkdir -p $dir
29137         touch $dir/file
29138
29139         cancel_lru_locks mdc
29140
29141         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
29142         $LCTL set_param fail_loc=0x1410
29143         cat $dir/file
29144         $LCTL set_param fail_loc=0
29145         rm -rf $dir
29146 }
29147 run_test 419 "Verify open file by name doesn't crash kernel"
29148
29149 test_420()
29150 {
29151         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
29152                 skip "Need MDS version at least 2.12.53"
29153
29154         local SAVE_UMASK=$(umask)
29155         local dir=$DIR/$tdir
29156         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
29157
29158         mkdir -p $dir
29159         umask 0000
29160         mkdir -m03777 $dir/testdir
29161         ls -dn $dir/testdir
29162         # Need to remove trailing '.' when SELinux is enabled
29163         local dirperms=$(ls -dn $dir/testdir |
29164                          awk '{ sub(/\.$/, "", $1); print $1}')
29165         [ $dirperms == "drwxrwsrwt" ] ||
29166                 error "incorrect perms on $dir/testdir"
29167
29168         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
29169                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
29170         ls -n $dir/testdir/testfile
29171         local fileperms=$(ls -n $dir/testdir/testfile |
29172                           awk '{ sub(/\.$/, "", $1); print $1}')
29173         [ $fileperms == "-rwxr-xr-x" ] ||
29174                 error "incorrect perms on $dir/testdir/testfile"
29175
29176         umask $SAVE_UMASK
29177 }
29178 run_test 420 "clear SGID bit on non-directories for non-members"
29179
29180 test_421a() {
29181         local cnt
29182         local fid1
29183         local fid2
29184
29185         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29186                 skip "Need MDS version at least 2.12.54"
29187
29188         test_mkdir $DIR/$tdir
29189         createmany -o $DIR/$tdir/f 3
29190         cnt=$(ls -1 $DIR/$tdir | wc -l)
29191         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29192
29193         fid1=$(lfs path2fid $DIR/$tdir/f1)
29194         fid2=$(lfs path2fid $DIR/$tdir/f2)
29195         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
29196
29197         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
29198         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
29199
29200         cnt=$(ls -1 $DIR/$tdir | wc -l)
29201         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29202
29203         rm -f $DIR/$tdir/f3 || error "can't remove f3"
29204         createmany -o $DIR/$tdir/f 3
29205         cnt=$(ls -1 $DIR/$tdir | wc -l)
29206         [ $cnt != 3 ] && error "unexpected #files: $cnt"
29207
29208         fid1=$(lfs path2fid $DIR/$tdir/f1)
29209         fid2=$(lfs path2fid $DIR/$tdir/f2)
29210         echo "remove using fsname $FSNAME"
29211         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
29212
29213         cnt=$(ls -1 $DIR/$tdir | wc -l)
29214         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
29215 }
29216 run_test 421a "simple rm by fid"
29217
29218 test_421b() {
29219         local cnt
29220         local FID1
29221         local FID2
29222
29223         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29224                 skip "Need MDS version at least 2.12.54"
29225
29226         test_mkdir $DIR/$tdir
29227         createmany -o $DIR/$tdir/f 3
29228         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
29229         MULTIPID=$!
29230
29231         FID1=$(lfs path2fid $DIR/$tdir/f1)
29232         FID2=$(lfs path2fid $DIR/$tdir/f2)
29233         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
29234
29235         kill -USR1 $MULTIPID
29236         wait
29237
29238         cnt=$(ls $DIR/$tdir | wc -l)
29239         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
29240 }
29241 run_test 421b "rm by fid on open file"
29242
29243 test_421c() {
29244         local cnt
29245         local FIDS
29246
29247         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29248                 skip "Need MDS version at least 2.12.54"
29249
29250         test_mkdir $DIR/$tdir
29251         createmany -o $DIR/$tdir/f 3
29252         touch $DIR/$tdir/$tfile
29253         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
29254         cnt=$(ls -1 $DIR/$tdir | wc -l)
29255         [ $cnt != 184 ] && error "unexpected #files: $cnt"
29256
29257         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
29258         $LFS rmfid $DIR $FID1 || error "rmfid failed"
29259
29260         cnt=$(ls $DIR/$tdir | wc -l)
29261         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
29262 }
29263 run_test 421c "rm by fid against hardlinked files"
29264
29265 test_421d() {
29266         local cnt
29267         local FIDS
29268
29269         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29270                 skip "Need MDS version at least 2.12.54"
29271
29272         test_mkdir $DIR/$tdir
29273         createmany -o $DIR/$tdir/f 4097
29274         cnt=$(ls -1 $DIR/$tdir | wc -l)
29275         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
29276
29277         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
29278         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29279
29280         cnt=$(ls $DIR/$tdir | wc -l)
29281         rm -rf $DIR/$tdir
29282         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29283 }
29284 run_test 421d "rmfid en masse"
29285
29286 test_421e() {
29287         local cnt
29288         local FID
29289
29290         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29291         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29292                 skip "Need MDS version at least 2.12.54"
29293
29294         mkdir -p $DIR/$tdir
29295         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29296         createmany -o $DIR/$tdir/striped_dir/f 512
29297         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29298         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29299
29300         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29301                 sed "s/[/][^:]*://g")
29302         $LFS rmfid $DIR $FIDS || error "rmfid failed"
29303
29304         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29305         rm -rf $DIR/$tdir
29306         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29307 }
29308 run_test 421e "rmfid in DNE"
29309
29310 test_421f() {
29311         local cnt
29312         local FID
29313
29314         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29315                 skip "Need MDS version at least 2.12.54"
29316
29317         test_mkdir $DIR/$tdir
29318         touch $DIR/$tdir/f
29319         cnt=$(ls -1 $DIR/$tdir | wc -l)
29320         [ $cnt != 1 ] && error "unexpected #files: $cnt"
29321
29322         FID=$(lfs path2fid $DIR/$tdir/f)
29323         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
29324         # rmfid should fail
29325         cnt=$(ls -1 $DIR/$tdir | wc -l)
29326         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
29327
29328         chmod a+rw $DIR/$tdir
29329         ls -la $DIR/$tdir
29330         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
29331         # rmfid should fail
29332         cnt=$(ls -1 $DIR/$tdir | wc -l)
29333         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
29334
29335         rm -f $DIR/$tdir/f
29336         $RUNAS touch $DIR/$tdir/f
29337         FID=$(lfs path2fid $DIR/$tdir/f)
29338         echo "rmfid as root"
29339         $LFS rmfid $DIR $FID || error "rmfid as root failed"
29340         cnt=$(ls -1 $DIR/$tdir | wc -l)
29341         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
29342
29343         rm -f $DIR/$tdir/f
29344         $RUNAS touch $DIR/$tdir/f
29345         cnt=$(ls -1 $DIR/$tdir | wc -l)
29346         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
29347         FID=$(lfs path2fid $DIR/$tdir/f)
29348         # rmfid w/o user_fid2path mount option should fail
29349         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
29350         cnt=$(ls -1 $DIR/$tdir | wc -l)
29351         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
29352
29353         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
29354         stack_trap "rmdir $tmpdir"
29355         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
29356                 error "failed to mount client'"
29357         stack_trap "umount_client $tmpdir"
29358
29359         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
29360         # rmfid should succeed
29361         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
29362         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
29363
29364         # rmfid shouldn't allow to remove files due to dir's permission
29365         chmod a+rwx $tmpdir/$tdir
29366         touch $tmpdir/$tdir/f
29367         ls -la $tmpdir/$tdir
29368         FID=$(lfs path2fid $tmpdir/$tdir/f)
29369         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
29370         return 0
29371 }
29372 run_test 421f "rmfid checks permissions"
29373
29374 test_421g() {
29375         local cnt
29376         local FIDS
29377
29378         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
29379         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
29380                 skip "Need MDS version at least 2.12.54"
29381
29382         mkdir -p $DIR/$tdir
29383         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
29384         createmany -o $DIR/$tdir/striped_dir/f 512
29385         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29386         [ $cnt != 512 ] && error "unexpected #files: $cnt"
29387
29388         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
29389                 sed "s/[/][^:]*://g")
29390
29391         rm -f $DIR/$tdir/striped_dir/f1*
29392         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
29393         removed=$((512 - cnt))
29394
29395         # few files have been just removed, so we expect
29396         # rmfid to fail on their fids
29397         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
29398         [ $removed != $errors ] && error "$errors != $removed"
29399
29400         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
29401         rm -rf $DIR/$tdir
29402         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
29403 }
29404 run_test 421g "rmfid to return errors properly"
29405
29406 test_421h() {
29407         local mount_other
29408         local mount_ret
29409         local rmfid_ret
29410         local old_fid
29411         local fidA
29412         local fidB
29413         local fidC
29414         local fidD
29415
29416         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
29417                 skip "Need MDS version at least 2.15.53"
29418
29419         test_mkdir $DIR/$tdir
29420         test_mkdir $DIR/$tdir/subdir
29421         touch $DIR/$tdir/subdir/file0
29422         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
29423         echo File $DIR/$tdir/subdir/file0 FID $old_fid
29424         rm -f $DIR/$tdir/subdir/file0
29425         touch $DIR/$tdir/subdir/fileA
29426         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
29427         echo File $DIR/$tdir/subdir/fileA FID $fidA
29428         touch $DIR/$tdir/subdir/fileB
29429         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
29430         echo File $DIR/$tdir/subdir/fileB FID $fidB
29431         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
29432         touch $DIR/$tdir/subdir/fileC
29433         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
29434         echo File $DIR/$tdir/subdir/fileC FID $fidC
29435         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
29436         touch $DIR/$tdir/fileD
29437         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
29438         echo File $DIR/$tdir/fileD FID $fidD
29439
29440         # mount another client mount point with subdirectory mount
29441         export FILESET=/$tdir/subdir
29442         mount_other=${MOUNT}_other
29443         mount_client $mount_other ${MOUNT_OPTS}
29444         mount_ret=$?
29445         export FILESET=""
29446         (( mount_ret == 0 )) || error "mount $mount_other failed"
29447
29448         echo Removing FIDs:
29449         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29450         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
29451         rmfid_ret=$?
29452
29453         umount_client $mount_other || error "umount $mount_other failed"
29454
29455         (( rmfid_ret != 0 )) || error "rmfid should have failed"
29456
29457         # fileA should have been deleted
29458         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
29459
29460         # fileB should have been deleted
29461         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
29462
29463         # fileC should not have been deleted, fid also exists outside of fileset
29464         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
29465
29466         # fileD should not have been deleted, it exists outside of fileset
29467         stat $DIR/$tdir/fileD || error "fileD deleted"
29468 }
29469 run_test 421h "rmfid with fileset mount"
29470
29471 test_422() {
29472         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
29473         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
29474         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
29475         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
29476         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
29477
29478         local amc=$(at_max_get client)
29479         local amo=$(at_max_get mds1)
29480         local timeout=`lctl get_param -n timeout`
29481
29482         at_max_set 0 client
29483         at_max_set 0 mds1
29484
29485 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
29486         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
29487                         fail_val=$(((2*timeout + 10)*1000))
29488         touch $DIR/$tdir/d3/file &
29489         sleep 2
29490 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
29491         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
29492                         fail_val=$((2*timeout + 5))
29493         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
29494         local pid=$!
29495         sleep 1
29496         kill -9 $pid
29497         sleep $((2 * timeout))
29498         echo kill $pid
29499         kill -9 $pid
29500         lctl mark touch
29501         touch $DIR/$tdir/d2/file3
29502         touch $DIR/$tdir/d2/file4
29503         touch $DIR/$tdir/d2/file5
29504
29505         wait
29506         at_max_set $amc client
29507         at_max_set $amo mds1
29508
29509         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
29510         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
29511                 error "Watchdog is always throttled"
29512 }
29513 run_test 422 "kill a process with RPC in progress"
29514
29515 stat_test() {
29516     df -h $MOUNT &
29517     df -h $MOUNT &
29518     df -h $MOUNT &
29519     df -h $MOUNT &
29520     df -h $MOUNT &
29521     df -h $MOUNT &
29522 }
29523
29524 test_423() {
29525     local _stats
29526     # ensure statfs cache is expired
29527     sleep 2;
29528
29529     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
29530     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
29531
29532     return 0
29533 }
29534 run_test 423 "statfs should return a right data"
29535
29536 test_424() {
29537 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | CFS_FAIL_ONCE
29538         $LCTL set_param fail_loc=0x80000522
29539         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
29540         rm -f $DIR/$tfile
29541 }
29542 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
29543
29544 test_425() {
29545         test_mkdir -c -1 $DIR/$tdir
29546         $LFS setstripe -c -1 $DIR/$tdir
29547
29548         lru_resize_disable "" 100
29549         stack_trap "lru_resize_enable" EXIT
29550
29551         sleep 5
29552
29553         for i in $(seq $((MDSCOUNT * 125))); do
29554                 local t=$DIR/$tdir/$tfile_$i
29555
29556                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
29557                         error_noexit "Create file $t"
29558         done
29559         stack_trap "rm -rf $DIR/$tdir" EXIT
29560
29561         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
29562                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
29563                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
29564
29565                 [ $lock_count -le $lru_size ] ||
29566                         error "osc lock count $lock_count > lru size $lru_size"
29567         done
29568
29569         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
29570                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
29571                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
29572
29573                 [ $lock_count -le $lru_size ] ||
29574                         error "mdc lock count $lock_count > lru size $lru_size"
29575         done
29576 }
29577 run_test 425 "lock count should not exceed lru size"
29578
29579 test_426() {
29580         splice-test -r $DIR/$tfile
29581         splice-test -rd $DIR/$tfile
29582         splice-test $DIR/$tfile
29583         splice-test -d $DIR/$tfile
29584 }
29585 run_test 426 "splice test on Lustre"
29586
29587 test_427() {
29588         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
29589         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
29590                 skip "Need MDS version at least 2.12.4"
29591         local log
29592
29593         mkdir $DIR/$tdir
29594         mkdir $DIR/$tdir/1
29595         mkdir $DIR/$tdir/2
29596         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
29597         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
29598
29599         $LFS getdirstripe $DIR/$tdir/1/dir
29600
29601         #first setfattr for creating updatelog
29602         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
29603
29604 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
29605         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
29606         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
29607         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
29608
29609         sleep 2
29610         fail mds2
29611         wait_recovery_complete mds2 $((2*TIMEOUT))
29612
29613         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
29614         echo $log | grep "get update log failed" &&
29615                 error "update log corruption is detected" || true
29616 }
29617 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
29618
29619 test_428() {
29620         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29621         local max_cached_mb=$($LCTL get_param llite.*.max_cached_mb |
29622                               awk '/^max_cached_mb/ { print $2 }')
29623         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$max_cached_mb"
29624
29625         $LCTL set_param -n llite.*.max_cached_mb=64
29626
29627         mkdir $DIR/$tdir
29628         $LFS setstripe -c 1 $DIR/$tdir
29629         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
29630         stack_trap "rm -f $DIR/$tdir/$tfile.*"
29631         #test write
29632         for f in $(seq 4); do
29633                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
29634         done
29635         wait
29636
29637         cancel_lru_locks osc
29638         # Test read
29639         for f in $(seq 4); do
29640                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
29641         done
29642         wait
29643 }
29644 run_test 428 "large block size IO should not hang"
29645
29646 test_429() { # LU-7915 / LU-10948
29647         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
29648         local testfile=$DIR/$tfile
29649         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
29650         local new_flag=1
29651         local first_rpc
29652         local second_rpc
29653         local third_rpc
29654
29655         $LCTL get_param $ll_opencache_threshold_count ||
29656                 skip "client does not have opencache parameter"
29657
29658         set_opencache $new_flag
29659         stack_trap "restore_opencache"
29660         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
29661                 error "enable opencache failed"
29662         touch $testfile
29663         # drop MDC DLM locks
29664         cancel_lru_locks mdc
29665         # clear MDC RPC stats counters
29666         $LCTL set_param $mdc_rpcstats=clear
29667
29668         # According to the current implementation, we need to run 3 times
29669         # open & close file to verify if opencache is enabled correctly.
29670         # 1st, RPCs are sent for lookup/open and open handle is released on
29671         #      close finally.
29672         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
29673         #      so open handle won't be released thereafter.
29674         # 3rd, No RPC is sent out.
29675         $MULTIOP $testfile oc || error "multiop failed"
29676         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29677         echo "1st: $first_rpc RPCs in flight"
29678
29679         $MULTIOP $testfile oc || error "multiop failed"
29680         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29681         echo "2nd: $second_rpc RPCs in flight"
29682
29683         $MULTIOP $testfile oc || error "multiop failed"
29684         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
29685         echo "3rd: $third_rpc RPCs in flight"
29686
29687         #verify no MDC RPC is sent
29688         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
29689 }
29690 run_test 429 "verify if opencache flag on client side does work"
29691
29692 lseek_test_430() {
29693         local offset
29694         local file=$1
29695
29696         # data at [200K, 400K)
29697         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
29698                 error "256K->512K dd fails"
29699         # data at [2M, 3M)
29700         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
29701                 error "2M->3M dd fails"
29702         # data at [4M, 5M)
29703         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
29704                 error "4M->5M dd fails"
29705         echo "Data at 256K...512K, 2M...3M and 4M...5M"
29706         # start at first component hole #1
29707         printf "Seeking hole from 1000 ... "
29708         offset=$(lseek_test -l 1000 $file)
29709         echo $offset
29710         [[ $offset == 1000 ]] || error "offset $offset != 1000"
29711         printf "Seeking data from 1000 ... "
29712         offset=$(lseek_test -d 1000 $file)
29713         echo $offset
29714         [[ $offset == 262144 ]] || error "offset $offset != 262144"
29715
29716         # start at first component data block
29717         printf "Seeking hole from 300000 ... "
29718         offset=$(lseek_test -l 300000 $file)
29719         echo $offset
29720         [[ $offset == 524288 ]] || error "offset $offset != 524288"
29721         printf "Seeking data from 300000 ... "
29722         offset=$(lseek_test -d 300000 $file)
29723         echo $offset
29724         [[ $offset == 300000 ]] || error "offset $offset != 300000"
29725
29726         # start at the first component but beyond end of object size
29727         printf "Seeking hole from 1000000 ... "
29728         offset=$(lseek_test -l 1000000 $file)
29729         echo $offset
29730         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29731         printf "Seeking data from 1000000 ... "
29732         offset=$(lseek_test -d 1000000 $file)
29733         echo $offset
29734         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29735
29736         # start at second component stripe 2 (empty file)
29737         printf "Seeking hole from 1500000 ... "
29738         offset=$(lseek_test -l 1500000 $file)
29739         echo $offset
29740         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
29741         printf "Seeking data from 1500000 ... "
29742         offset=$(lseek_test -d 1500000 $file)
29743         echo $offset
29744         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
29745
29746         # start at second component stripe 1 (all data)
29747         printf "Seeking hole from 3000000 ... "
29748         offset=$(lseek_test -l 3000000 $file)
29749         echo $offset
29750         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
29751         printf "Seeking data from 3000000 ... "
29752         offset=$(lseek_test -d 3000000 $file)
29753         echo $offset
29754         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
29755
29756         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
29757                 error "2nd dd fails"
29758         echo "Add data block at 640K...1280K"
29759
29760         # start at before new data block, in hole
29761         printf "Seeking hole from 600000 ... "
29762         offset=$(lseek_test -l 600000 $file)
29763         echo $offset
29764         [[ $offset == 600000 ]] || error "offset $offset != 600000"
29765         printf "Seeking data from 600000 ... "
29766         offset=$(lseek_test -d 600000 $file)
29767         echo $offset
29768         [[ $offset == 655360 ]] || error "offset $offset != 655360"
29769
29770         # start at the first component new data block
29771         printf "Seeking hole from 1000000 ... "
29772         offset=$(lseek_test -l 1000000 $file)
29773         echo $offset
29774         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29775         printf "Seeking data from 1000000 ... "
29776         offset=$(lseek_test -d 1000000 $file)
29777         echo $offset
29778         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29779
29780         # start at second component stripe 2, new data
29781         printf "Seeking hole from 1200000 ... "
29782         offset=$(lseek_test -l 1200000 $file)
29783         echo $offset
29784         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
29785         printf "Seeking data from 1200000 ... "
29786         offset=$(lseek_test -d 1200000 $file)
29787         echo $offset
29788         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
29789
29790         # start beyond file end
29791         printf "Using offset > filesize ... "
29792         lseek_test -l 4000000 $file && error "lseek should fail"
29793         printf "Using offset > filesize ... "
29794         lseek_test -d 4000000 $file && error "lseek should fail"
29795
29796         printf "Done\n\n"
29797 }
29798
29799 test_430a() {
29800         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
29801                 skip "MDT does not support SEEK_HOLE"
29802
29803         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29804                 skip "OST does not support SEEK_HOLE"
29805
29806         local file=$DIR/$tdir/$tfile
29807
29808         mkdir -p $DIR/$tdir
29809
29810         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
29811         # OST stripe #1 will have continuous data at [1M, 3M)
29812         # OST stripe #2 is empty
29813         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
29814         lseek_test_430 $file
29815         rm $file
29816         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
29817         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
29818         lseek_test_430 $file
29819         rm $file
29820         $LFS setstripe -c2 -S 512K $file
29821         echo "Two stripes, stripe size 512K"
29822         lseek_test_430 $file
29823         rm $file
29824         # FLR with stale mirror
29825         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
29826                        -N -c2 -S 1M $file
29827         echo "Mirrored file:"
29828         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
29829         echo "Plain 2 stripes 1M"
29830         lseek_test_430 $file
29831         rm $file
29832 }
29833 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
29834
29835 test_430b() {
29836         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29837                 skip "OST does not support SEEK_HOLE"
29838
29839         local offset
29840         local file=$DIR/$tdir/$tfile
29841
29842         mkdir -p $DIR/$tdir
29843         # Empty layout lseek should fail
29844         $MCREATE $file
29845         # seek from 0
29846         printf "Seeking hole from 0 ... "
29847         lseek_test -l 0 $file && error "lseek should fail"
29848         printf "Seeking data from 0 ... "
29849         lseek_test -d 0 $file && error "lseek should fail"
29850         rm $file
29851
29852         # 1M-hole file
29853         $LFS setstripe -E 1M -c2 -E eof $file
29854         $TRUNCATE $file 1048576
29855         printf "Seeking hole from 1000000 ... "
29856         offset=$(lseek_test -l 1000000 $file)
29857         echo $offset
29858         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
29859         printf "Seeking data from 1000000 ... "
29860         lseek_test -d 1000000 $file && error "lseek should fail"
29861         rm $file
29862
29863         # full component followed by non-inited one
29864         $LFS setstripe -E 1M -c2 -E eof $file
29865         dd if=/dev/urandom of=$file bs=1M count=1
29866         printf "Seeking hole from 1000000 ... "
29867         offset=$(lseek_test -l 1000000 $file)
29868         echo $offset
29869         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29870         printf "Seeking hole from 1048576 ... "
29871         lseek_test -l 1048576 $file && error "lseek should fail"
29872         # init second component and truncate back
29873         echo "123" >> $file
29874         $TRUNCATE $file 1048576
29875         printf "Seeking hole from 1000000 ... "
29876         offset=$(lseek_test -l 1000000 $file)
29877         echo $offset
29878         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
29879         printf "Seeking hole from 1048576 ... "
29880         lseek_test -l 1048576 $file && error "lseek should fail"
29881         # boundary checks for big values
29882         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
29883         offset=$(lseek_test -d 0 $file.10g)
29884         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
29885         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
29886         offset=$(lseek_test -d 0 $file.100g)
29887         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
29888         return 0
29889 }
29890 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
29891
29892 test_430c() {
29893         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
29894                 skip "OST does not support SEEK_HOLE"
29895
29896         local file=$DIR/$tdir/$tfile
29897         local start
29898
29899         mkdir -p $DIR/$tdir
29900         stack_trap "rm -f $file $file.tmp"
29901         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
29902
29903         # cp version 8.33+ prefers lseek over fiemap
29904         local ver=$(cp --version | awk '{ print $4; exit; }')
29905
29906         echo "cp $ver installed"
29907         if (( $(version_code $ver) >= $(version_code 8.33) )); then
29908                 start=$SECONDS
29909                 time cp -v $file $file.tmp || error "cp $file failed"
29910                 (( SECONDS - start < 5 )) || {
29911                         strace cp $file $file.tmp |&
29912                                 grep -E "open|read|seek|FIEMAP" |
29913                                 grep -A 100 $file
29914                         error "cp: too long runtime $((SECONDS - start))"
29915                 }
29916         else
29917                 echo "cp test skipped due to $ver < 8.33"
29918         fi
29919
29920         # tar version 1.29+ supports SEEK_HOLE/DATA
29921         ver=$(tar --version | awk '{ print $4; exit; }')
29922         echo "tar $ver installed"
29923         if (( $(version_code $ver) >= $(version_code 1.29) )); then
29924                 start=$SECONDS
29925                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
29926                 (( SECONDS - start < 5 )) || {
29927                         strace tar cf $file.tmp --sparse $file |&
29928                                 grep -E "open|read|seek|FIEMAP" |
29929                                 grep -A 100 $file
29930                         error "tar: too long runtime $((SECONDS - start))"
29931                 }
29932         else
29933                 echo "tar test skipped due to $ver < 1.29"
29934         fi
29935 }
29936 run_test 430c "lseek: external tools check"
29937
29938 test_431() { # LU-14187
29939         local file=$DIR/$tdir/$tfile
29940
29941         mkdir -p $DIR/$tdir
29942         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
29943         dd if=/dev/urandom of=$file bs=4k count=1
29944         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
29945         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
29946         #define OBD_FAIL_OST_RESTART_IO 0x251
29947         do_facet ost1 "$LCTL set_param fail_loc=0x251"
29948         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
29949         cp $file $file.0
29950         cancel_lru_locks
29951         sync_all_data
29952         echo 3 > /proc/sys/vm/drop_caches
29953         diff  $file $file.0 || error "data diff"
29954 }
29955 run_test 431 "Restart transaction for IO"
29956
29957 cleanup_test_432() {
29958         do_facet mgs $LCTL nodemap_activate 0
29959         wait_nm_sync active
29960 }
29961
29962 test_432() {
29963         local tmpdir=$TMP/dir432
29964
29965         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
29966                 skip "Need MDS version at least 2.14.52"
29967
29968         stack_trap cleanup_test_432 EXIT
29969         mkdir $DIR/$tdir
29970         mkdir $tmpdir
29971
29972         do_facet mgs $LCTL nodemap_activate 1
29973         wait_nm_sync active
29974         do_facet mgs $LCTL nodemap_modify --name default \
29975                 --property admin --value 1
29976         do_facet mgs $LCTL nodemap_modify --name default \
29977                 --property trusted --value 1
29978         cancel_lru_locks mdc
29979         wait_nm_sync default admin_nodemap
29980         wait_nm_sync default trusted_nodemap
29981
29982         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
29983                grep -ci "Operation not permitted") -ne 0 ]; then
29984                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
29985         fi
29986 }
29987 run_test 432 "mv dir from outside Lustre"
29988
29989 test_433() {
29990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29991
29992         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
29993                 skip "inode cache not supported"
29994
29995         $LCTL set_param llite.*.inode_cache=0
29996         stack_trap "$LCTL set_param llite.*.inode_cache=1"
29997
29998         local count=256
29999         local before
30000         local after
30001
30002         cancel_lru_locks mdc
30003         test_mkdir $DIR/$tdir || error "mkdir $tdir"
30004         createmany -m $DIR/$tdir/f $count
30005         createmany -d $DIR/$tdir/d $count
30006         ls -l $DIR/$tdir > /dev/null
30007         stack_trap "rm -rf $DIR/$tdir"
30008
30009         before=$(num_objects)
30010         cancel_lru_locks mdc
30011         after=$(num_objects)
30012
30013         # sometimes even @before is less than 2 * count
30014         while (( before - after < count )); do
30015                 sleep 1
30016                 after=$(num_objects)
30017                 wait=$((wait + 1))
30018                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
30019                 if (( wait > 60 )); then
30020                         error "inode slab grew from $before to $after"
30021                 fi
30022         done
30023
30024         echo "lustre_inode_cache $before objs before lock cancel, $after after"
30025 }
30026 run_test 433 "ldlm lock cancel releases dentries and inodes"
30027
30028 test_434() {
30029         local file
30030         local getxattr_count
30031         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
30032         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
30033
30034         [[ $(getenforce) == "Disabled" ]] ||
30035                 skip "lsm selinux module have to be disabled for this test"
30036
30037         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
30038                 error "fail to create $DIR/$tdir/ on MDT0000"
30039
30040         touch $DIR/$tdir/$tfile-{001..100}
30041
30042         # disable the xattr cache
30043         save_lustre_params client "llite.*.xattr_cache" > $p
30044         lctl set_param llite.*.xattr_cache=0
30045         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
30046
30047         # clear clients mdc stats
30048         clear_stats $mdc_stat_param ||
30049                 error "fail to clear stats on mdc MDT0000"
30050
30051         for file in $DIR/$tdir/$tfile-{001..100}; do
30052                 getfattr -n security.selinux $file |&
30053                         grep -q "Operation not supported" ||
30054                         error "getxattr on security.selinux should return EOPNOTSUPP"
30055         done
30056
30057         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
30058         (( getxattr_count < 100 )) ||
30059                 error "client sent $getxattr_count getxattr RPCs to the MDS"
30060 }
30061 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
30062
30063 test_440() {
30064         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
30065                 source $LUSTRE/scripts/bash-completion/lustre
30066         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
30067                 source /usr/share/bash-completion/completions/lustre
30068         else
30069                 skip "bash completion scripts not found"
30070         fi
30071
30072         local lctl_completions
30073         local lfs_completions
30074
30075         lctl_completions=$(_lustre_cmds lctl)
30076         if [[ ! $lctl_completions =~ "get_param" ]]; then
30077                 error "lctl bash completion failed"
30078         fi
30079
30080         lfs_completions=$(_lustre_cmds lfs)
30081         if [[ ! $lfs_completions =~ "setstripe" ]]; then
30082                 error "lfs bash completion failed"
30083         fi
30084 }
30085 run_test 440 "bash completion for lfs, lctl"
30086
30087 test_442() {
30088         local pid1
30089         local pid2
30090         mkdir -p $DIR/$tdir
30091         multiop $DIR/$tdir/$tfile.1 O_w1 & pid1=$!
30092         multiop $DIR/$tdir/$tfile.1 O_w1 & pid2=$!
30093         sleep 1
30094         touch $DIR/$tdir/$tfile.2
30095         $LFS swap_layouts -n $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
30096         $LCTL set_param fail_loc=0x1430
30097         kill -USR1 $pid1
30098         sleep 1
30099         kill -USR1 $pid2
30100         wait
30101 }
30102 run_test 442 "truncate vs read/write should not panic"
30103
30104 prep_801() {
30105         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
30106         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
30107                 skip "Need server version at least 2.9.55"
30108
30109         start_full_debug_logging
30110 }
30111
30112 post_801() {
30113         stop_full_debug_logging
30114 }
30115
30116 barrier_stat() {
30117         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30118                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30119                            awk '/The barrier for/ { print $7 }')
30120                 echo $st
30121         else
30122                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
30123                 echo \'$st\'
30124         fi
30125 }
30126
30127 barrier_expired() {
30128         local expired
30129
30130         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
30131                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
30132                           awk '/will be expired/ { print $7 }')
30133         else
30134                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
30135         fi
30136
30137         echo $expired
30138 }
30139
30140 test_801a() {
30141         prep_801
30142
30143         echo "Start barrier_freeze at: $(date)"
30144         #define OBD_FAIL_BARRIER_DELAY          0x2202
30145         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30146         # Do not reduce barrier time - See LU-11873
30147         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
30148
30149         sleep 2
30150         local b_status=$(barrier_stat)
30151         echo "Got barrier status at: $(date)"
30152         [ "$b_status" = "'freezing_p1'" ] ||
30153                 error "(1) unexpected barrier status $b_status"
30154
30155         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30156         wait
30157         b_status=$(barrier_stat)
30158         [ "$b_status" = "'frozen'" ] ||
30159                 error "(2) unexpected barrier status $b_status"
30160
30161         local expired=$(barrier_expired)
30162         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
30163         sleep $((expired + 3))
30164
30165         b_status=$(barrier_stat)
30166         [ "$b_status" = "'expired'" ] ||
30167                 error "(3) unexpected barrier status $b_status"
30168
30169         # Do not reduce barrier time - See LU-11873
30170         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
30171                 error "(4) fail to freeze barrier"
30172
30173         b_status=$(barrier_stat)
30174         [ "$b_status" = "'frozen'" ] ||
30175                 error "(5) unexpected barrier status $b_status"
30176
30177         echo "Start barrier_thaw at: $(date)"
30178         #define OBD_FAIL_BARRIER_DELAY          0x2202
30179         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
30180         do_facet mgs $LCTL barrier_thaw $FSNAME &
30181
30182         sleep 2
30183         b_status=$(barrier_stat)
30184         echo "Got barrier status at: $(date)"
30185         [ "$b_status" = "'thawing'" ] ||
30186                 error "(6) unexpected barrier status $b_status"
30187
30188         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
30189         wait
30190         b_status=$(barrier_stat)
30191         [ "$b_status" = "'thawed'" ] ||
30192                 error "(7) unexpected barrier status $b_status"
30193
30194         #define OBD_FAIL_BARRIER_FAILURE        0x2203
30195         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
30196         do_facet mgs $LCTL barrier_freeze $FSNAME
30197
30198         b_status=$(barrier_stat)
30199         [ "$b_status" = "'failed'" ] ||
30200                 error "(8) unexpected barrier status $b_status"
30201
30202         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
30203         do_facet mgs $LCTL barrier_thaw $FSNAME
30204
30205         post_801
30206 }
30207 run_test 801a "write barrier user interfaces and stat machine"
30208
30209 test_801b() {
30210         prep_801
30211
30212         mkdir $DIR/$tdir || error "(1) fail to mkdir"
30213         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
30214         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
30215         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
30216         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
30217
30218         cancel_lru_locks mdc
30219
30220         # 180 seconds should be long enough
30221         do_facet mgs $LCTL barrier_freeze $FSNAME 180
30222
30223         local b_status=$(barrier_stat)
30224         [ "$b_status" = "'frozen'" ] ||
30225                 error "(6) unexpected barrier status $b_status"
30226
30227         mkdir $DIR/$tdir/d0/d10 &
30228         mkdir_pid=$!
30229
30230         touch $DIR/$tdir/d1/f13 &
30231         touch_pid=$!
30232
30233         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
30234         ln_pid=$!
30235
30236         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
30237         mv_pid=$!
30238
30239         rm -f $DIR/$tdir/d4/f12 &
30240         rm_pid=$!
30241
30242         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
30243
30244         # To guarantee taht the 'stat' is not blocked
30245         b_status=$(barrier_stat)
30246         [ "$b_status" = "'frozen'" ] ||
30247                 error "(8) unexpected barrier status $b_status"
30248
30249         # let above commands to run at background
30250         sleep 5
30251
30252         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
30253         ps -p $touch_pid || error "(10) touch should be blocked"
30254         ps -p $ln_pid || error "(11) link should be blocked"
30255         ps -p $mv_pid || error "(12) rename should be blocked"
30256         ps -p $rm_pid || error "(13) unlink should be blocked"
30257
30258         b_status=$(barrier_stat)
30259         [ "$b_status" = "'frozen'" ] ||
30260                 error "(14) unexpected barrier status $b_status"
30261
30262         do_facet mgs $LCTL barrier_thaw $FSNAME
30263         b_status=$(barrier_stat)
30264         [ "$b_status" = "'thawed'" ] ||
30265                 error "(15) unexpected barrier status $b_status"
30266
30267         wait $mkdir_pid || error "(16) mkdir should succeed"
30268         wait $touch_pid || error "(17) touch should succeed"
30269         wait $ln_pid || error "(18) link should succeed"
30270         wait $mv_pid || error "(19) rename should succeed"
30271         wait $rm_pid || error "(20) unlink should succeed"
30272
30273         post_801
30274 }
30275 run_test 801b "modification will be blocked by write barrier"
30276
30277 test_801c() {
30278         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30279
30280         prep_801
30281
30282         stop mds2 || error "(1) Fail to stop mds2"
30283
30284         do_facet mgs $LCTL barrier_freeze $FSNAME 30
30285
30286         local b_status=$(barrier_stat)
30287         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
30288                 do_facet mgs $LCTL barrier_thaw $FSNAME
30289                 error "(2) unexpected barrier status $b_status"
30290         }
30291
30292         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30293                 error "(3) Fail to rescan barrier bitmap"
30294
30295         # Do not reduce barrier time - See LU-11873
30296         do_facet mgs $LCTL barrier_freeze $FSNAME 20
30297
30298         b_status=$(barrier_stat)
30299         [ "$b_status" = "'frozen'" ] ||
30300                 error "(4) unexpected barrier status $b_status"
30301
30302         do_facet mgs $LCTL barrier_thaw $FSNAME
30303         b_status=$(barrier_stat)
30304         [ "$b_status" = "'thawed'" ] ||
30305                 error "(5) unexpected barrier status $b_status"
30306
30307         local devname=$(mdsdevname 2)
30308
30309         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
30310
30311         do_facet mgs $LCTL barrier_rescan $FSNAME ||
30312                 error "(7) Fail to rescan barrier bitmap"
30313
30314         post_801
30315 }
30316 run_test 801c "rescan barrier bitmap"
30317
30318 test_802b() {
30319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30320         remote_mds_nodsh && skip "remote MDS with nodsh"
30321
30322         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
30323                 skip "readonly option not available"
30324
30325         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
30326
30327         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
30328                 error "(2) Fail to copy"
30329
30330         # write back all cached data before setting MDT to readonly
30331         cancel_lru_locks
30332         sync_all_data
30333
30334         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
30335         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
30336
30337         echo "Modify should be refused"
30338         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
30339
30340         echo "Read should be allowed"
30341         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
30342                 error "(7) Read should succeed under ro mode"
30343
30344         # disable readonly
30345         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
30346 }
30347 run_test 802b "be able to set MDTs to readonly"
30348
30349 test_803a() {
30350         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30351         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30352                 skip "MDS needs to be newer than 2.10.54"
30353
30354         mkdir_on_mdt0 $DIR/$tdir
30355         # Create some objects on all MDTs to trigger related logs objects
30356         for idx in $(seq $MDSCOUNT); do
30357                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
30358                         $DIR/$tdir/dir${idx} ||
30359                         error "Fail to create $DIR/$tdir/dir${idx}"
30360         done
30361
30362         wait_delete_completed # ensure old test cleanups are finished
30363         sleep 3
30364         echo "before create:"
30365         $LFS df -i $MOUNT
30366         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30367
30368         for i in {1..10}; do
30369                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
30370                         error "Fail to create $DIR/$tdir/foo$i"
30371         done
30372
30373         # sync ZFS-on-MDS to refresh statfs data
30374         wait_zfs_commit mds1
30375         sleep 3
30376         echo "after create:"
30377         $LFS df -i $MOUNT
30378         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30379
30380         # allow for an llog to be cleaned up during the test
30381         [ $after_used -ge $((before_used + 10 - 1)) ] ||
30382                 error "before ($before_used) + 10 > after ($after_used)"
30383
30384         for i in {1..10}; do
30385                 rm -rf $DIR/$tdir/foo$i ||
30386                         error "Fail to remove $DIR/$tdir/foo$i"
30387         done
30388
30389         # sync ZFS-on-MDS to refresh statfs data
30390         wait_zfs_commit mds1
30391         wait_delete_completed
30392         sleep 3 # avoid MDT return cached statfs
30393         echo "after unlink:"
30394         $LFS df -i $MOUNT
30395         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
30396
30397         # allow for an llog to be created during the test
30398         [ $after_used -le $((before_used + 1)) ] ||
30399                 error "after ($after_used) > before ($before_used) + 1"
30400 }
30401 run_test 803a "verify agent object for remote object"
30402
30403 test_803b() {
30404         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30405         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
30406                 skip "MDS needs to be newer than 2.13.56"
30407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30408
30409         for i in $(seq 0 $((MDSCOUNT - 1))); do
30410                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
30411         done
30412
30413         local before=0
30414         local after=0
30415
30416         local tmp
30417
30418         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30419         for i in $(seq 0 $((MDSCOUNT - 1))); do
30420                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30421                         awk '/getattr/ { print $2 }')
30422                 before=$((before + tmp))
30423         done
30424         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
30425         for i in $(seq 0 $((MDSCOUNT - 1))); do
30426                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
30427                         awk '/getattr/ { print $2 }')
30428                 after=$((after + tmp))
30429         done
30430
30431         [ $before -eq $after ] || error "getattr count $before != $after"
30432 }
30433 run_test 803b "remote object can getattr from cache"
30434
30435 test_804() {
30436         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
30437         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
30438                 skip "MDS needs to be newer than 2.10.54"
30439         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
30440
30441         mkdir -p $DIR/$tdir
30442         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
30443                 error "Fail to create $DIR/$tdir/dir0"
30444
30445         local fid=$($LFS path2fid $DIR/$tdir/dir0)
30446         local dev=$(mdsdevname 2)
30447
30448         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30449                 grep ${fid} || error "NOT found agent entry for dir0"
30450
30451         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
30452                 error "Fail to create $DIR/$tdir/dir1"
30453
30454         touch $DIR/$tdir/dir1/foo0 ||
30455                 error "Fail to create $DIR/$tdir/dir1/foo0"
30456         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
30457         local rc=0
30458
30459         for idx in $(seq $MDSCOUNT); do
30460                 dev=$(mdsdevname $idx)
30461                 do_facet mds${idx} \
30462                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30463                         grep ${fid} && rc=$idx
30464         done
30465
30466         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
30467                 error "Fail to rename foo0 to foo1"
30468         if [ $rc -eq 0 ]; then
30469                 for idx in $(seq $MDSCOUNT); do
30470                         dev=$(mdsdevname $idx)
30471                         do_facet mds${idx} \
30472                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30473                         grep ${fid} && rc=$idx
30474                 done
30475         fi
30476
30477         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
30478                 error "Fail to rename foo1 to foo2"
30479         if [ $rc -eq 0 ]; then
30480                 for idx in $(seq $MDSCOUNT); do
30481                         dev=$(mdsdevname $idx)
30482                         do_facet mds${idx} \
30483                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
30484                         grep ${fid} && rc=$idx
30485                 done
30486         fi
30487
30488         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
30489
30490         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
30491                 error "Fail to link to $DIR/$tdir/dir1/foo2"
30492         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
30493                 error "Fail to rename foo2 to foo0"
30494         unlink $DIR/$tdir/dir1/foo0 ||
30495                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
30496         rm -rf $DIR/$tdir/dir0 ||
30497                 error "Fail to rm $DIR/$tdir/dir0"
30498
30499         for idx in $(seq $MDSCOUNT); do
30500                 rc=0
30501
30502                 stop mds${idx}
30503                 dev=$(mdsdevname $idx)
30504                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
30505                         rc=$?
30506                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
30507                         error "mount mds$idx failed"
30508                 df $MOUNT > /dev/null 2>&1
30509
30510                 # e2fsck should not return error
30511                 [ $rc -eq 0 ] ||
30512                         error "e2fsck detected error on MDT${idx}: rc=$rc"
30513         done
30514 }
30515 run_test 804 "verify agent entry for remote entry"
30516
30517 cleanup_805() {
30518         do_facet $SINGLEMDS zfs set quota=$old $fsset
30519         unlinkmany $DIR/$tdir/f- 1000000
30520         trap 0
30521 }
30522
30523 test_805() {
30524         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
30525         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
30526         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
30527                 skip "netfree not implemented before 0.7"
30528         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
30529                 skip "Need MDS version at least 2.10.57"
30530
30531         local fsset
30532         local freekb
30533         local usedkb
30534         local old
30535         local quota
30536         local pref="osd-zfs.$FSNAME-MDT0000."
30537
30538         # limit available space on MDS dataset to meet nospace issue
30539         # quickly. then ZFS 0.7.2 can use reserved space if asked
30540         # properly (using netfree flag in osd_declare_destroy()
30541         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
30542         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
30543                 gawk '{print $3}')
30544         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
30545         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
30546         let "usedkb=usedkb-freekb"
30547         let "freekb=freekb/2"
30548         if let "freekb > 5000"; then
30549                 let "freekb=5000"
30550         fi
30551         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
30552         trap cleanup_805 EXIT
30553         mkdir_on_mdt0 $DIR/$tdir
30554         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
30555                 error "Can't set PFL layout"
30556         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
30557         rm -rf $DIR/$tdir || error "not able to remove"
30558         do_facet $SINGLEMDS zfs set quota=$old $fsset
30559         trap 0
30560 }
30561 run_test 805 "ZFS can remove from full fs"
30562
30563 # Size-on-MDS test
30564 check_lsom_data()
30565 {
30566         local file=$1
30567         local expect=$(stat -c %s $file)
30568
30569         check_lsom_size $1 $expect
30570
30571         local blocks=$($LFS getsom -b $file)
30572         expect=$(stat -c %b $file)
30573         [[ $blocks == $expect ]] ||
30574                 error "$file expected blocks: $expect, got: $blocks"
30575 }
30576
30577 check_lsom_size()
30578 {
30579         local size
30580         local expect=$2
30581
30582         cancel_lru_locks mdc
30583
30584         size=$($LFS getsom -s $1)
30585         [[ $size == $expect ]] ||
30586                 error "$file expected size: $expect, got: $size"
30587 }
30588
30589 test_806() {
30590         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30591                 skip "Need MDS version at least 2.11.52"
30592
30593         local bs=1048576
30594
30595         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
30596
30597         disable_opencache
30598         stack_trap "restore_opencache"
30599
30600         # single-threaded write
30601         echo "Test SOM for single-threaded write"
30602         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
30603                 error "write $tfile failed"
30604         check_lsom_size $DIR/$tfile $bs
30605
30606         local num=32
30607         local size=$(($num * $bs))
30608         local offset=0
30609         local i
30610
30611         echo "Test SOM for single client multi-threaded($num) write"
30612         $TRUNCATE $DIR/$tfile 0
30613         for ((i = 0; i < $num; i++)); do
30614                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30615                 local pids[$i]=$!
30616                 offset=$((offset + $bs))
30617         done
30618         for (( i=0; i < $num; i++ )); do
30619                 wait ${pids[$i]}
30620         done
30621         check_lsom_size $DIR/$tfile $size
30622
30623         $TRUNCATE $DIR/$tfile 0
30624         for ((i = 0; i < $num; i++)); do
30625                 offset=$((offset - $bs))
30626                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30627                 local pids[$i]=$!
30628         done
30629         for (( i=0; i < $num; i++ )); do
30630                 wait ${pids[$i]}
30631         done
30632         check_lsom_size $DIR/$tfile $size
30633
30634         # multi-client writes
30635         num=$(get_node_count ${CLIENTS//,/ })
30636         size=$(($num * $bs))
30637         offset=0
30638         i=0
30639
30640         echo "Test SOM for multi-client ($num) writes"
30641         $TRUNCATE $DIR/$tfile 0
30642         for client in ${CLIENTS//,/ }; do
30643                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30644                 local pids[$i]=$!
30645                 i=$((i + 1))
30646                 offset=$((offset + $bs))
30647         done
30648         for (( i=0; i < $num; i++ )); do
30649                 wait ${pids[$i]}
30650         done
30651         check_lsom_size $DIR/$tfile $offset
30652
30653         i=0
30654         $TRUNCATE $DIR/$tfile 0
30655         for client in ${CLIENTS//,/ }; do
30656                 offset=$((offset - $bs))
30657                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30658                 local pids[$i]=$!
30659                 i=$((i + 1))
30660         done
30661         for (( i=0; i < $num; i++ )); do
30662                 wait ${pids[$i]}
30663         done
30664         check_lsom_size $DIR/$tfile $size
30665
30666         # verify SOM blocks count
30667         echo "Verify SOM block count"
30668         $TRUNCATE $DIR/$tfile 0
30669         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
30670                 error "failed to write file $tfile with fdatasync and fstat"
30671         check_lsom_data $DIR/$tfile
30672
30673         $TRUNCATE $DIR/$tfile 0
30674         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
30675                 error "failed to write file $tfile with fdatasync"
30676         check_lsom_data $DIR/$tfile
30677
30678         $TRUNCATE $DIR/$tfile 0
30679         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
30680                 error "failed to write file $tfile with sync IO"
30681         check_lsom_data $DIR/$tfile
30682
30683         # verify truncate
30684         echo "Test SOM for truncate"
30685         # use ftruncate to sync blocks on close request
30686         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
30687         check_lsom_size $DIR/$tfile 16384
30688         check_lsom_data $DIR/$tfile
30689
30690         $TRUNCATE $DIR/$tfile 1234
30691         check_lsom_size $DIR/$tfile 1234
30692         # sync blocks on the MDT
30693         $MULTIOP $DIR/$tfile oc
30694         check_lsom_data $DIR/$tfile
30695 }
30696 run_test 806 "Verify Lazy Size on MDS"
30697
30698 test_807() {
30699         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
30700         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
30701                 skip "Need MDS version at least 2.11.52"
30702
30703         # Registration step
30704         changelog_register || error "changelog_register failed"
30705         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
30706         changelog_users $SINGLEMDS | grep -q $cl_user ||
30707                 error "User $cl_user not found in changelog_users"
30708
30709         rm -rf $DIR/$tdir || error "rm $tdir failed"
30710         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
30711         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
30712         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
30713         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
30714                 error "truncate $tdir/trunc failed"
30715
30716         local bs=1048576
30717         echo "Test SOM for single-threaded write with fsync"
30718         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
30719                 error "write $tfile failed"
30720         sync;sync;sync
30721
30722         # multi-client wirtes
30723         local num=$(get_node_count ${CLIENTS//,/ })
30724         local offset=0
30725         local i=0
30726
30727         echo "Test SOM for multi-client ($num) writes"
30728         touch $DIR/$tfile || error "touch $tfile failed"
30729         $TRUNCATE $DIR/$tfile 0
30730         for client in ${CLIENTS//,/ }; do
30731                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
30732                 local pids[$i]=$!
30733                 i=$((i + 1))
30734                 offset=$((offset + $bs))
30735         done
30736         for (( i=0; i < $num; i++ )); do
30737                 wait ${pids[$i]}
30738         done
30739
30740         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
30741         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
30742         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
30743         check_lsom_data $DIR/$tdir/trunc
30744         check_lsom_data $DIR/$tdir/single_dd
30745         check_lsom_data $DIR/$tfile
30746
30747         rm -rf $DIR/$tdir
30748         # Deregistration step
30749         changelog_deregister || error "changelog_deregister failed"
30750 }
30751 run_test 807 "verify LSOM syncing tool"
30752
30753 check_som_nologged()
30754 {
30755         local lines=$($LFS changelog $FSNAME-MDT0000 |
30756                 grep 'x=trusted.som' | wc -l)
30757         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
30758 }
30759
30760 test_808() {
30761         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
30762                 skip "Need MDS version at least 2.11.55"
30763
30764         # Registration step
30765         changelog_register || error "changelog_register failed"
30766
30767         touch $DIR/$tfile || error "touch $tfile failed"
30768         check_som_nologged
30769
30770         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
30771                 error "write $tfile failed"
30772         check_som_nologged
30773
30774         $TRUNCATE $DIR/$tfile 1234
30775         check_som_nologged
30776
30777         $TRUNCATE $DIR/$tfile 1048576
30778         check_som_nologged
30779
30780         # Deregistration step
30781         changelog_deregister || error "changelog_deregister failed"
30782 }
30783 run_test 808 "Check trusted.som xattr not logged in Changelogs"
30784
30785 check_som_nodata()
30786 {
30787         $LFS getsom $1
30788         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
30789 }
30790
30791 test_809() {
30792         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
30793                 skip "Need MDS version at least 2.11.56"
30794
30795         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
30796                 error "failed to create DoM-only file $DIR/$tfile"
30797         touch $DIR/$tfile || error "touch $tfile failed"
30798         check_som_nodata $DIR/$tfile
30799
30800         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
30801                 error "write $tfile failed"
30802         check_som_nodata $DIR/$tfile
30803
30804         $TRUNCATE $DIR/$tfile 1234
30805         check_som_nodata $DIR/$tfile
30806
30807         $TRUNCATE $DIR/$tfile 4097
30808         check_som_nodata $DIR/$file
30809 }
30810 run_test 809 "Verify no SOM xattr store for DoM-only files"
30811
30812 test_810() {
30813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
30814         $GSS && skip_env "could not run with gss"
30815         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
30816                 skip "OST < 2.12.58 doesn't align checksum"
30817
30818         set_checksums 1
30819         stack_trap "set_checksums $ORIG_CSUM" EXIT
30820         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
30821
30822         local csum
30823         local before
30824         local after
30825         for csum in $CKSUM_TYPES; do
30826                 #define OBD_FAIL_OSC_NO_GRANT   0x411
30827                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
30828                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
30829                         eval set -- $i
30830                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
30831                         before=$(md5sum $DIR/$tfile)
30832                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
30833                         after=$(md5sum $DIR/$tfile)
30834                         [ "$before" == "$after" ] ||
30835                                 error "$csum: $before != $after bs=$1 seek=$2"
30836                 done
30837         done
30838 }
30839 run_test 810 "partial page writes on ZFS (LU-11663)"
30840
30841 test_812a() {
30842         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30843                 skip "OST < 2.12.51 doesn't support this fail_loc"
30844
30845         $LFS setstripe -c 1 -i 0 $DIR/$tfile
30846         # ensure ost1 is connected
30847         stat $DIR/$tfile >/dev/null || error "can't stat"
30848         wait_osc_import_state client ost1 FULL
30849         # no locks, no reqs to let the connection idle
30850         cancel_lru_locks osc
30851
30852         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30853 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30854         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30855         wait_osc_import_state client ost1 CONNECTING
30856         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30857
30858         stat $DIR/$tfile >/dev/null || error "can't stat file"
30859 }
30860 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
30861
30862 test_812b() { # LU-12378
30863         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
30864                 skip "OST < 2.12.51 doesn't support this fail_loc"
30865
30866         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
30867         # ensure ost1 is connected
30868         stat $DIR/$tfile >/dev/null || error "can't stat"
30869         wait_osc_import_state client ost1 FULL
30870         # no locks, no reqs to let the connection idle
30871         cancel_lru_locks osc
30872
30873         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
30874 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
30875         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
30876         wait_osc_import_state client ost1 CONNECTING
30877         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
30878
30879         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
30880         wait_osc_import_state client ost1 IDLE
30881 }
30882 run_test 812b "do not drop no resend request for idle connect"
30883
30884 test_812c() {
30885         local old
30886
30887         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
30888
30889         $LFS setstripe -c 1 -o 0 $DIR/$tfile
30890         $LFS getstripe $DIR/$tfile
30891         $LCTL set_param osc.*.idle_timeout=10
30892         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
30893         # ensure ost1 is connected
30894         stat $DIR/$tfile >/dev/null || error "can't stat"
30895         wait_osc_import_state client ost1 FULL
30896         # no locks, no reqs to let the connection idle
30897         cancel_lru_locks osc
30898
30899 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
30900         $LCTL set_param fail_loc=0x80000533
30901         sleep 15
30902         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
30903 }
30904 run_test 812c "idle import vs lock enqueue race"
30905
30906 test_813() {
30907         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
30908         [ -z "$file_heat_sav" ] && skip "no file heat support"
30909
30910         local readsample
30911         local writesample
30912         local readbyte
30913         local writebyte
30914         local readsample1
30915         local writesample1
30916         local readbyte1
30917         local writebyte1
30918
30919         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
30920         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
30921
30922         $LCTL set_param -n llite.*.file_heat=1
30923         echo "Turn on file heat"
30924         echo "Period second: $period_second, Decay percentage: $decay_pct"
30925
30926         echo "QQQQ" > $DIR/$tfile
30927         echo "QQQQ" > $DIR/$tfile
30928         echo "QQQQ" > $DIR/$tfile
30929         cat $DIR/$tfile > /dev/null
30930         cat $DIR/$tfile > /dev/null
30931         cat $DIR/$tfile > /dev/null
30932         cat $DIR/$tfile > /dev/null
30933
30934         local out=$($LFS heat_get $DIR/$tfile)
30935
30936         $LFS heat_get $DIR/$tfile
30937         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30938         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30939         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30940         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30941
30942         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
30943         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
30944         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
30945         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
30946
30947         sleep $((period_second + 3))
30948         echo "Sleep $((period_second + 3)) seconds..."
30949         # The recursion formula to calculate the heat of the file f is as
30950         # follow:
30951         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
30952         # Where Hi is the heat value in the period between time points i*I and
30953         # (i+1)*I; Ci is the access count in the period; the symbol P refers
30954         # to the weight of Ci.
30955         out=$($LFS heat_get $DIR/$tfile)
30956         $LFS heat_get $DIR/$tfile
30957         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30958         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30959         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30960         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30961
30962         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
30963                 error "read sample ($readsample) is wrong"
30964         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
30965                 error "write sample ($writesample) is wrong"
30966         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
30967                 error "read bytes ($readbyte) is wrong"
30968         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
30969                 error "write bytes ($writebyte) is wrong"
30970
30971         echo "QQQQ" > $DIR/$tfile
30972         echo "QQQQ" > $DIR/$tfile
30973         echo "QQQQ" > $DIR/$tfile
30974         cat $DIR/$tfile > /dev/null
30975         cat $DIR/$tfile > /dev/null
30976         cat $DIR/$tfile > /dev/null
30977         cat $DIR/$tfile > /dev/null
30978
30979         sleep $((period_second + 3))
30980         echo "Sleep $((period_second + 3)) seconds..."
30981
30982         out=$($LFS heat_get $DIR/$tfile)
30983         $LFS heat_get $DIR/$tfile
30984         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
30985         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
30986         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
30987         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
30988
30989         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
30990                 4 * $decay_pct) / 100") -eq 1 ] ||
30991                 error "read sample ($readsample1) is wrong"
30992         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
30993                 3 * $decay_pct) / 100") -eq 1 ] ||
30994                 error "write sample ($writesample1) is wrong"
30995         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
30996                 20 * $decay_pct) / 100") -eq 1 ] ||
30997                 error "read bytes ($readbyte1) is wrong"
30998         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
30999                 15 * $decay_pct) / 100") -eq 1 ] ||
31000                 error "write bytes ($writebyte1) is wrong"
31001
31002         echo "Turn off file heat for the file $DIR/$tfile"
31003         $LFS heat_set -o $DIR/$tfile
31004
31005         echo "QQQQ" > $DIR/$tfile
31006         echo "QQQQ" > $DIR/$tfile
31007         echo "QQQQ" > $DIR/$tfile
31008         cat $DIR/$tfile > /dev/null
31009         cat $DIR/$tfile > /dev/null
31010         cat $DIR/$tfile > /dev/null
31011         cat $DIR/$tfile > /dev/null
31012
31013         out=$($LFS heat_get $DIR/$tfile)
31014         $LFS heat_get $DIR/$tfile
31015         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31016         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31017         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31018         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31019
31020         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31021         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31022         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31023         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31024
31025         echo "Trun on file heat for the file $DIR/$tfile"
31026         $LFS heat_set -O $DIR/$tfile
31027
31028         echo "QQQQ" > $DIR/$tfile
31029         echo "QQQQ" > $DIR/$tfile
31030         echo "QQQQ" > $DIR/$tfile
31031         cat $DIR/$tfile > /dev/null
31032         cat $DIR/$tfile > /dev/null
31033         cat $DIR/$tfile > /dev/null
31034         cat $DIR/$tfile > /dev/null
31035
31036         out=$($LFS heat_get $DIR/$tfile)
31037         $LFS heat_get $DIR/$tfile
31038         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31039         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31040         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31041         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31042
31043         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
31044         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
31045         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
31046         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
31047
31048         $LFS heat_set -c $DIR/$tfile
31049         $LCTL set_param -n llite.*.file_heat=0
31050         echo "Turn off file heat support for the Lustre filesystem"
31051
31052         echo "QQQQ" > $DIR/$tfile
31053         echo "QQQQ" > $DIR/$tfile
31054         echo "QQQQ" > $DIR/$tfile
31055         cat $DIR/$tfile > /dev/null
31056         cat $DIR/$tfile > /dev/null
31057         cat $DIR/$tfile > /dev/null
31058         cat $DIR/$tfile > /dev/null
31059
31060         out=$($LFS heat_get $DIR/$tfile)
31061         $LFS heat_get $DIR/$tfile
31062         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
31063         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
31064         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
31065         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
31066
31067         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
31068         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
31069         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
31070         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
31071
31072         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
31073         rm -f $DIR/$tfile
31074 }
31075 run_test 813 "File heat verfication"
31076
31077 test_814()
31078 {
31079         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
31080         echo -n y >> $DIR/$tfile
31081         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
31082         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
31083 }
31084 run_test 814 "sparse cp works as expected (LU-12361)"
31085
31086 test_815()
31087 {
31088         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
31089         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
31090 }
31091 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
31092
31093 test_816() {
31094         local ost1_imp=$(get_osc_import_name client ost1)
31095         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
31096                          cut -d'.' -f2)
31097
31098         $LFS setstripe -c 1 -i 0 $DIR/$tfile
31099         # ensure ost1 is connected
31100
31101         stat $DIR/$tfile >/dev/null || error "can't stat"
31102         wait_osc_import_state client ost1 FULL
31103         # no locks, no reqs to let the connection idle
31104         cancel_lru_locks osc
31105         lru_resize_disable osc
31106         local before
31107         local now
31108         before=$($LCTL get_param -n \
31109                  ldlm.namespaces.$imp_name.lru_size)
31110
31111         wait_osc_import_state client ost1 IDLE
31112         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
31113         now=$($LCTL get_param -n \
31114               ldlm.namespaces.$imp_name.lru_size)
31115         [ $before == $now ] || error "lru_size changed $before != $now"
31116 }
31117 run_test 816 "do not reset lru_resize on idle reconnect"
31118
31119 cleanup_817() {
31120         umount $tmpdir
31121         exportfs -u localhost:$DIR/nfsexp
31122         rm -rf $DIR/nfsexp
31123 }
31124
31125 test_817() {
31126         systemctl restart nfs-server.service || skip "failed to restart nfsd"
31127
31128         mkdir -p $DIR/nfsexp
31129         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
31130                 error "failed to export nfs"
31131
31132         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
31133         stack_trap cleanup_817 EXIT
31134
31135         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
31136                 error "failed to mount nfs to $tmpdir"
31137
31138         cp /bin/true $tmpdir
31139         $DIR/nfsexp/true || error "failed to execute 'true' command"
31140 }
31141 run_test 817 "nfsd won't cache write lock for exec file"
31142
31143 test_818() {
31144         test_mkdir -i0 -c1 $DIR/$tdir
31145         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
31146         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
31147         stop $SINGLEMDS
31148
31149         # restore osp-syn threads
31150         stack_trap "fail $SINGLEMDS"
31151
31152         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
31153         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
31154         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
31155                 error "start $SINGLEMDS failed"
31156         rm -rf $DIR/$tdir
31157
31158         local testid=$(echo $TESTNAME | tr '_' ' ')
31159
31160         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
31161                 grep "run LFSCK" || error "run LFSCK is not suggested"
31162 }
31163 run_test 818 "unlink with failed llog"
31164
31165 test_819a() {
31166         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31167         cancel_lru_locks osc
31168         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31169         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31170         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
31171         rm -f $TDIR/$tfile
31172 }
31173 run_test 819a "too big niobuf in read"
31174
31175 test_819b() {
31176         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
31177         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
31178         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31179         cancel_lru_locks osc
31180         sleep 1
31181         rm -f $TDIR/$tfile
31182 }
31183 run_test 819b "too big niobuf in write"
31184
31185
31186 function test_820_start_ost() {
31187         sleep 5
31188
31189         for num in $(seq $OSTCOUNT); do
31190                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
31191         done
31192 }
31193
31194 test_820() {
31195         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
31196
31197         mkdir $DIR/$tdir
31198         umount_client $MOUNT || error "umount failed"
31199         for num in $(seq $OSTCOUNT); do
31200                 stop ost$num
31201         done
31202
31203         # mount client with no active OSTs
31204         # so that the client can't initialize max LOV EA size
31205         # from OSC notifications
31206         mount_client $MOUNT || error "mount failed"
31207         # delay OST starting to keep this 0 max EA size for a while
31208         test_820_start_ost &
31209
31210         # create a directory on MDS2
31211         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
31212                 error "Failed to create directory"
31213         # open intent should update default EA size
31214         # see mdc_update_max_ea_from_body()
31215         # notice this is the very first RPC to MDS2
31216         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
31217         ret=$?
31218         echo $out
31219         # With SSK, this situation can lead to -EPERM being returned.
31220         # In that case, simply retry.
31221         if [ $ret -ne 0 ] && $SHARED_KEY; then
31222                 if echo "$out" | grep -q "not permitted"; then
31223                         cp /etc/services $DIR/$tdir/mds2
31224                         ret=$?
31225                 fi
31226         fi
31227         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
31228 }
31229 run_test 820 "update max EA from open intent"
31230
31231 test_823() {
31232         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31233         local OST_MAX_PRECREATE=20000
31234
31235         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
31236                 skip "Need MDS version at least 2.14.56"
31237
31238         save_lustre_params mds1 \
31239                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
31240         do_facet $SINGLEMDS "$LCTL set_param -n \
31241                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
31242         do_facet $SINGLEMDS "$LCTL set_param -n \
31243                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
31244
31245         stack_trap "restore_lustre_params < $p; rm $p"
31246
31247         do_facet $SINGLEMDS "$LCTL set_param -n \
31248                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
31249
31250         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31251                       osp.$FSNAME-OST0000*MDT0000.create_count")
31252         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
31253                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
31254         local expect_count=$(((($max/2)/256) * 256))
31255
31256         log "setting create_count to 100200:"
31257         log " -result- count: $count with max: $max, expecting: $expect_count"
31258
31259         [[ $count -eq expect_count ]] ||
31260                 error "Create count not set to max precreate."
31261 }
31262 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
31263
31264 test_831() {
31265         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
31266                 skip "Need MDS version 2.14.56"
31267
31268         local sync_changes=$(do_facet $SINGLEMDS \
31269                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31270
31271         [ "$sync_changes" -gt 100 ] &&
31272                 skip "Sync changes $sync_changes > 100 already"
31273
31274         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
31275
31276         $LFS mkdir -i 0 $DIR/$tdir
31277         $LFS setstripe -c 1 -i 0 $DIR/$tdir
31278
31279         save_lustre_params mds1 \
31280                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
31281         save_lustre_params mds1 \
31282                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
31283
31284         do_facet mds1 "$LCTL set_param -n \
31285                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
31286                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
31287         stack_trap "restore_lustre_params < $p" EXIT
31288
31289         createmany -o $DIR/$tdir/f- 1000
31290         unlinkmany $DIR/$tdir/f- 1000 &
31291         local UNLINK_PID=$!
31292
31293         while sleep 1; do
31294                 sync_changes=$(do_facet mds1 \
31295                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
31296                 # the check in the code is racy, fail the test
31297                 # if the value above the limit by 10.
31298                 [ $sync_changes -gt 110 ] && {
31299                         kill -2 $UNLINK_PID
31300                         wait
31301                         error "osp changes throttling failed, $sync_changes>110"
31302                 }
31303                 kill -0 $UNLINK_PID 2> /dev/null || break
31304         done
31305         wait
31306 }
31307 run_test 831 "throttling unlink/setattr queuing on OSP"
31308
31309 test_832() {
31310         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
31311         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
31312                 skip "Need MDS version 2.15.52+"
31313         is_rmentry_supported || skip "rm_entry not supported"
31314
31315         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
31316         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
31317         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
31318                 error "mkdir remote_dir failed"
31319         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
31320                 error "mkdir striped_dir failed"
31321         touch $DIR/$tdir/file || error "touch file failed"
31322         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
31323         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
31324 }
31325 run_test 832 "lfs rm_entry"
31326
31327 test_833() {
31328         local file=$DIR/$tfile
31329
31330         stack_trap "rm -f $file" EXIT
31331         dd if=/dev/zero of=$file bs=1M count=50 || error "Write $file failed"
31332
31333         local wpid
31334         local rpid
31335         local rpid2
31336
31337         # Buffered I/O write
31338         (
31339                 while [ ! -e $DIR/sanity.833.lck ]; do
31340                         dd if=/dev/zero of=$file bs=1M count=50 conv=notrunc ||
31341                                 error "failed to write $file"
31342                         sleep 0.$((RANDOM % 4 + 1))
31343                 done
31344         )&
31345         wpid=$!
31346
31347         # Buffered I/O read
31348         (
31349                 while [ ! -e $DIR/sanity.833.lck ]; do
31350                         dd if=$file of=/dev/null bs=1M count=50 ||
31351                                 error "failed to read $file"
31352                         sleep 0.$((RANDOM % 4 + 1))
31353                 done
31354         )&
31355         rpid=$!
31356
31357         # Direct I/O read
31358         (
31359                 while [ ! -e $DIR/sanity.833.lck ]; do
31360                         dd if=$file of=/dev/null bs=1M count=50 iflag=direct ||
31361                                 error "failed to read $file in direct I/O mode"
31362                         sleep 0.$((RANDOM % 4 + 1))
31363                 done
31364         )&
31365         rpid2=$!
31366
31367         sleep 30
31368         touch $DIR/sanity.833.lck
31369         wait $wpid || error "$?: buffered write failed"
31370         wait $rpid || error "$?: buffered read failed"
31371         wait $rpid2 || error "$?: direct read failed"
31372 }
31373 run_test 833 "Mixed buffered/direct read and write should not return -EIO"
31374
31375 test_850() {
31376         local dir=$DIR/$tdir
31377         local file=$dir/$tfile
31378         local statsfile=$dir/all_job_stats.txt
31379
31380         test_mkdir -p $dir || error "failed to create dir $dir"
31381         echo "abcdefg" > $file || error "failed to create file $file"
31382
31383         # read job_stats in the living system
31384         lljobstat -n 1 ||
31385                 error "failed to run lljobstat on living system"
31386
31387         $LCTL get_param *.*.job_stats > $statsfile
31388         lljobstat --statsfile=$statsfile ||
31389                 error "failed to run lljobstat on file $statsfile"
31390 }
31391 run_test 850 "lljobstat can parse living and aggregated job_stats"
31392
31393 #
31394 # tests that do cleanup/setup should be run at the end
31395 #
31396
31397 test_900() {
31398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31399         local ls
31400
31401         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
31402         $LCTL set_param fail_loc=0x903
31403
31404         cancel_lru_locks MGC
31405
31406         FAIL_ON_ERROR=true cleanup
31407         FAIL_ON_ERROR=true setup
31408 }
31409 run_test 900 "umount should not race with any mgc requeue thread"
31410
31411 # LUS-6253/LU-11185
31412 test_901() {
31413         local old
31414         local count
31415         local oldc
31416         local newc
31417         local olds
31418         local news
31419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
31420
31421         # some get_param have a bug to handle dot in param name
31422         cancel_lru_locks MGC
31423         old=$(mount -t lustre | wc -l)
31424         # 1 config+sptlrpc
31425         # 2 params
31426         # 3 nodemap
31427         # 4 IR
31428         old=$((old * 4))
31429         oldc=0
31430         count=0
31431         while [ $old -ne $oldc ]; do
31432                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31433                 sleep 1
31434                 ((count++))
31435                 if [ $count -ge $TIMEOUT ]; then
31436                         error "too large timeout"
31437                 fi
31438         done
31439         umount_client $MOUNT || error "umount failed"
31440         mount_client $MOUNT || error "mount failed"
31441         cancel_lru_locks MGC
31442         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
31443
31444         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
31445
31446         return 0
31447 }
31448 run_test 901 "don't leak a mgc lock on client umount"
31449
31450 # LU-13377
31451 test_902() {
31452         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
31453                 skip "client does not have LU-13377 fix"
31454         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
31455         $LCTL set_param fail_loc=0x1415
31456         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
31457         cancel_lru_locks osc
31458         rm -f $DIR/$tfile
31459 }
31460 run_test 902 "test short write doesn't hang lustre"
31461
31462 # LU-14711
31463 test_903() {
31464         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
31465         echo "blah" > $DIR/${tfile}-2
31466         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
31467         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
31468         $LCTL set_param fail_loc=0x417 fail_val=20
31469
31470         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
31471         sleep 1 # To start the destroy
31472         wait_destroy_complete 150 || error "Destroy taking too long"
31473         cat $DIR/$tfile > /dev/null || error "Evicted"
31474 }
31475 run_test 903 "Test long page discard does not cause evictions"
31476
31477 test_904() {
31478         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
31479         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
31480                 grep -q project || skip "skip project quota not supported"
31481
31482         local testfile="$DIR/$tdir/$tfile"
31483         local xattr="trusted.projid"
31484         local projid
31485         local mdts=$(comma_list $(mdts_nodes))
31486         local saved=$(do_facet mds1 $LCTL get_param -n \
31487                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
31488
31489         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
31490         stack_trap "do_nodes $mdts $LCTL set_param \
31491                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
31492
31493         mkdir -p $DIR/$tdir
31494         touch $testfile
31495         #hide projid xattr on server
31496         $LFS project -p 1 $testfile ||
31497                 error "set $testfile project id failed"
31498         getfattr -m - $testfile | grep $xattr &&
31499                 error "do not show trusted.projid when disabled on server"
31500         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
31501         #should be hidden when projid is 0
31502         $LFS project -p 0 $testfile ||
31503                 error "set $testfile project id failed"
31504         getfattr -m - $testfile | grep $xattr &&
31505                 error "do not show trusted.projid with project ID 0"
31506
31507         #still can getxattr explicitly
31508         projid=$(getfattr -n $xattr $testfile |
31509                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31510         [ $projid == "0" ] ||
31511                 error "projid expected 0 not $projid"
31512
31513         #set the projid via setxattr
31514         setfattr -n $xattr -v "1000" $testfile ||
31515                 error "setattr failed with $?"
31516         projid=($($LFS project $testfile))
31517         [ ${projid[0]} == "1000" ] ||
31518                 error "projid expected 1000 not $projid"
31519
31520         #check the new projid via getxattr
31521         $LFS project -p 1001 $testfile ||
31522                 error "set $testfile project id failed"
31523         getfattr -m - $testfile | grep $xattr ||
31524                 error "should show trusted.projid when project ID != 0"
31525         projid=$(getfattr -n $xattr $testfile |
31526                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31527         [ $projid == "1001" ] ||
31528                 error "projid expected 1001 not $projid"
31529
31530         #try to set invalid projid
31531         setfattr -n $xattr -v "4294967295" $testfile &&
31532                 error "set invalid projid should fail"
31533
31534         #remove the xattr means setting projid to 0
31535         setfattr -x $xattr $testfile ||
31536                 error "setfattr failed with $?"
31537         projid=($($LFS project $testfile))
31538         [ ${projid[0]} == "0" ] ||
31539                 error "projid expected 0 not $projid"
31540
31541         #should be hidden when parent has inherit flag and same projid
31542         $LFS project -srp 1002 $DIR/$tdir ||
31543                 error "set $tdir project id failed"
31544         getfattr -m - $testfile | grep $xattr &&
31545                 error "do not show trusted.projid with inherit flag"
31546
31547         #still can getxattr explicitly
31548         projid=$(getfattr -n $xattr $testfile |
31549                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
31550         [ $projid == "1002" ] ||
31551                 error "projid expected 1002 not $projid"
31552 }
31553 run_test 904 "virtual project ID xattr"
31554
31555 # LU-8582
31556 test_905() {
31557         (( $OST1_VERSION >= $(version_code 2.15.50.220) )) ||
31558                 skip "need OST version >= 2.15.50.220 for fail_loc"
31559
31560         remote_ost_nodsh && skip "remote OST with nodsh"
31561         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
31562
31563         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
31564
31565         #define OBD_FAIL_OST_OPCODE 0x253
31566         # OST_LADVISE = 21
31567         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
31568         $LFS ladvise -a willread $DIR/$tfile &&
31569                 error "unexpected success of ladvise with fault injection"
31570         $LFS ladvise -a willread $DIR/$tfile |&
31571                 grep -q "Operation not supported"
31572         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
31573 }
31574 run_test 905 "bad or new opcode should not stuck client"
31575
31576 test_906() {
31577         grep -q io_uring_setup /proc/kallsyms ||
31578                 skip "Client OS does not support io_uring I/O engine"
31579         io_uring_probe || skip "kernel does not support io_uring fully"
31580         which fio || skip_env "no fio installed"
31581         fio --enghelp | grep -q io_uring ||
31582                 skip_env "fio does not support io_uring I/O engine"
31583
31584         local file=$DIR/$tfile
31585         local ioengine="io_uring"
31586         local numjobs=2
31587         local size=50M
31588
31589         fio --name=seqwrite --ioengine=$ioengine        \
31590                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31591                 --iodepth=64 --size=$size --filename=$file --rw=write ||
31592                 error "fio seqwrite $file failed"
31593
31594         fio --name=seqread --ioengine=$ioengine \
31595                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
31596                 --iodepth=64 --size=$size --filename=$file --rw=read ||
31597                 error "fio seqread $file failed"
31598
31599         rm -f $file || error "rm -f $file failed"
31600 }
31601 run_test 906 "Simple test for io_uring I/O engine via fio"
31602
31603 test_907() {
31604         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
31605
31606         # set stripe size to max rpc size
31607         $LFS setstripe -i 0 -c 2 -S $((max_pages * PAGE_SIZE)) $DIR/$tfile
31608         $LFS getstripe $DIR/$tfile
31609 #define OBD_FAIL_OST_EROFS               0x216
31610         do_facet ost1 "$LCTL set_param fail_val=3 fail_loc=0x80000216"
31611
31612         local bs=$((max_pages * PAGE_SIZE / 16))
31613
31614         # write full one stripe and one block
31615         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=17 || error "dd failed"
31616
31617         rm $DIR/$tfile || error "rm failed"
31618 }
31619 run_test 907 "write rpc error during unlink"
31620
31621
31622 complete_test $SECONDS
31623 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
31624 check_and_cleanup_lustre
31625 if [ "$I_MOUNTED" != "yes" ]; then
31626         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
31627 fi
31628 exit_status