Whamcloud - gitweb
LU-13706 tests: remove test 119d
[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 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31
32 TRACE=${TRACE:-""}
33 LUSTRE=${LUSTRE:-$(dirname $0)/..}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 . $LUSTRE/tests/test-framework.sh
36 init_test_env "$@"
37
38 init_logging
39
40 ALWAYS_EXCEPT="$SANITY_EXCEPT "
41 always_except LU-9693  42a 42c
42 always_except LU-6493  42b
43 always_except LU-16515 118c 118d
44 always_except LU-14541 277
45 always_except LU-8411  407
46
47 if $SHARED_KEY; then
48         always_except LU-14181 64e 64f
49 fi
50
51 # skip the grant tests for ARM until they are fixed
52 if [[ $(uname -m) = aarch64 ]]; then
53         always_except LU-11671 45
54 fi
55
56 # skip nfs tests on kernels >= 4.12.0 until they are fixed
57 if [ $LINUX_VERSION_CODE -ge $(version_code 4.12.0) ]; then
58         always_except LU-12661 817
59 fi
60 # skip cgroup tests on RHEL8.1 kernels until they are fixed
61 if (( $LINUX_VERSION_CODE >= $(version_code 4.18.0) &&
62       $LINUX_VERSION_CODE <  $(version_code 5.4.0) )); then
63         always_except LU-13063 411
64 fi
65
66 # skip basic ops on file with foreign LOV tests on 5.16.0+ kernels
67 # until the filemap_read() issue is fixed
68 if (( $LINUX_VERSION_CODE >= $(version_code 5.16.0) )); then
69         always_except LU-16101 27J
70 fi
71
72 #                                  5              12     8   12  15   (min)"
73 [[ "$SLOW" = "no" ]] && EXCEPT_SLOW="27m 60i 64b 68 71 135 136 230d 300o"
74
75 if [[ "$mds1_FSTYPE" == "zfs" ]]; then
76         #                                               13    (min)"
77         [[ "$SLOW" == "no" ]] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
78 fi
79
80 if [[ "$ost1_FSTYPE" = "zfs" ]]; then
81         always_except LU-1941 130b 130c 130d 130e 130f 130g
82         always_except LU-9054 312
83 fi
84
85 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
86
87 # Get the SLES distro version
88 #
89 # Returns a version string that should only be used in comparing
90 # strings returned by version_code()
91 sles_version_code()
92 {
93         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
94
95         # All SuSE Linux versions have one decimal. version_code expects two
96         local sles_version=$version.0
97         version_code $sles_version
98 }
99
100 # Check if we are running on Ubuntu or SLES so we can make decisions on
101 # what tests to run
102 if [ -r /etc/SuSE-release ] || [ -r /etc/SUSE-brand ]; then
103         sles_version=$(sles_version_code)
104         [ $sles_version -lt $(version_code 11.4.0) ] &&
105                 always_except LU-4341 170
106
107         [ $sles_version -lt $(version_code 12.0.0) ] &&
108                 always_except LU-3703 234
109
110         [ $sles_version -ge $(version_code 15.4.0) ] &&
111                 always_except LU-16101 27J
112 elif [ -r /etc/os-release ]; then
113         if grep -qi ubuntu /etc/os-release; then
114                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
115                                                 -e 's/^VERSION=//p' \
116                                                 /etc/os-release |
117                                                 awk '{ print $1 }'))
118
119                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
120                         always_except LU-10366 410
121                 fi
122         fi
123 fi
124
125 build_test_filter
126 FAIL_ON_ERROR=false
127
128 cleanup() {
129         echo -n "cln.."
130         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
131         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
132 }
133 setup() {
134         echo -n "mnt.."
135         load_modules
136         setupall || exit 10
137         echo "done"
138 }
139
140 check_swap_layouts_support()
141 {
142         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
143                 skip "Does not support layout lock."
144 }
145
146 check_swap_layout_no_dom()
147 {
148         local FOLDER=$1
149         local SUPP=$(lfs getstripe $FOLDER | grep "pattern:       mdt" | wc -l)
150         [ $SUPP -eq 0 ] || skip "layout swap does not support DOM files so far"
151 }
152
153 check_and_setup_lustre
154 DIR=${DIR:-$MOUNT}
155 assert_DIR
156
157 MAXFREE=${MAXFREE:-$((300000 * $OSTCOUNT))}
158
159 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
160 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
161 rm -rf $DIR/[Rdfs][0-9]*
162
163 # $RUNAS_ID may get set incorrectly somewhere else
164 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
165         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
166
167 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
168
169 if [ "${ONLY}" = "MOUNT" ] ; then
170         echo "Lustre is up, please go on"
171         exit
172 fi
173
174 echo "preparing for tests involving mounts"
175 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
176 touch $EXT2_DEV
177 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
178 echo # add a newline after mke2fs.
179
180 umask 077
181
182 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
183
184 # ensure all internal functions know we want full debug
185 export PTLDEBUG=all
186 lctl set_param debug=$PTLDEBUG 2> /dev/null || true
187
188 test_0a() {
189         touch $DIR/$tfile
190         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
191         rm $DIR/$tfile
192         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
193 }
194 run_test 0a "touch; rm ====================="
195
196 test_0b() {
197         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
198         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
199 }
200 run_test 0b "chmod 0755 $DIR ============================="
201
202 test_0c() {
203         $LCTL get_param mdc.*.import | grep "state: FULL" ||
204                 error "import not FULL"
205         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
206                 error "bad target"
207 }
208 run_test 0c "check import proc"
209
210 test_0d() { # LU-3397
211         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
212                 skip "proc exports not supported before 2.10.57"
213
214         local mgs_exp="mgs.MGS.exports"
215         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
216         local exp_client_nid
217         local exp_client_version
218         local exp_val
219         local imp_val
220         local temp_imp=$DIR/$tfile.import
221         local temp_exp=$DIR/$tfile.export
222
223         # save mgc import file to $temp_imp
224         $LCTL get_param mgc.*.import | tee $temp_imp
225         # Check if client uuid is found in MGS export
226         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
227                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
228                         $client_uuid ] &&
229                         break;
230         done
231         # save mgs export file to $temp_exp
232         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
233
234         # Compare the value of field "connect_flags"
235         imp_val=$(grep "connect_flags" $temp_imp)
236         exp_val=$(grep "connect_flags" $temp_exp)
237         [ "$exp_val" == "$imp_val" ] ||
238                 error "export flags '$exp_val' != import flags '$imp_val'"
239
240         # Compare client versions.  Only compare top-3 fields for compatibility
241         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
242         exp_val=$(version_code $(cut -d. -f1,2,3 <<<$exp_client_version))
243         imp_val=$(version_code $(lustre_build_version client | cut -d. -f1,2,3))
244         [ "$exp_val" == "$imp_val" ] ||
245                 error "exp version '$exp_client_version'($exp_val) != " \
246                         "'$(lustre_build_version client)'($imp_val)"
247 }
248 run_test 0d "check export proc ============================="
249
250 test_0e() { # LU-13417
251         (( $MDSCOUNT > 1 )) ||
252                 skip "We need at least 2 MDTs for this test"
253
254         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
255                 skip "Need server version at least 2.14.51"
256
257         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
258         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
259
260         [ $default_lmv_count -eq 1 ] ||
261                 error "$MOUNT default stripe count $default_lmv_count"
262
263         [ $default_lmv_index -eq -1 ] ||
264                 error "$MOUNT default stripe index $default_lmv_index"
265
266         mkdir $MOUNT/$tdir.1 || error "mkdir $MOUNT/$tdir.1 failed"
267         mkdir $MOUNT/$tdir.2 || error "mkdir $MOUNT/$tdir.2 failed"
268
269         local mdt_index1=$($LFS getdirstripe -i $MOUNT/$tdir.1)
270         local mdt_index2=$($LFS getdirstripe -i $MOUNT/$tdir.2)
271
272         [ $mdt_index1 -eq $mdt_index2 ] &&
273                 error "directories are on the same MDT $mdt_index1=$mdt_index2"
274
275         rmdir $MOUNT/$tdir.1 $MOUNT/$tdir.2
276 }
277 run_test 0e "Enable DNE MDT balancing for mkdir in the ROOT"
278
279 test_1() {
280         test_mkdir $DIR/$tdir
281         test_mkdir $DIR/$tdir/d2
282         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
283         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
284         rmdir $DIR/$tdir/d2
285         rmdir $DIR/$tdir
286         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
287 }
288 run_test 1 "mkdir; remkdir; rmdir"
289
290 test_2() {
291         test_mkdir $DIR/$tdir
292         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
293         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
294         rm -r $DIR/$tdir
295         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
296 }
297 run_test 2 "mkdir; touch; rmdir; check file"
298
299 test_3() {
300         test_mkdir $DIR/$tdir
301         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
302         touch $DIR/$tdir/$tfile
303         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
304         rm -r $DIR/$tdir
305         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
306 }
307 run_test 3 "mkdir; touch; rmdir; check dir"
308
309 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
310 test_4() {
311         test_mkdir -i 1 $DIR/$tdir
312
313         touch $DIR/$tdir/$tfile ||
314                 error "Create file under remote directory failed"
315
316         rmdir $DIR/$tdir &&
317                 error "Expect error removing in-use dir $DIR/$tdir"
318
319         test -d $DIR/$tdir || error "Remote directory disappeared"
320
321         rm -rf $DIR/$tdir || error "remove remote dir error"
322 }
323 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
324
325 test_5() {
326         test_mkdir $DIR/$tdir
327         test_mkdir $DIR/$tdir/d2
328         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
329         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
330         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
331 }
332 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
333
334 test_6a() {
335         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
336         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
337         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
338                 error "$tfile does not have perm 0666 or UID $UID"
339         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
340         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
341                 error "$tfile should be 0666 and owned by UID $UID"
342 }
343 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
344
345 test_6c() {
346         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
347
348         touch $DIR/$tfile
349         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
350         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
351                 error "$tfile should be owned by UID $RUNAS_ID"
352         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
353         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
354                 error "$tfile should be owned by UID $RUNAS_ID"
355 }
356 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
357
358 test_6e() {
359         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
360
361         touch $DIR/$tfile
362         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
363         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
364                 error "$tfile should be owned by GID $UID"
365         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
366         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
367                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
368 }
369 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
370
371 test_6g() {
372         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
373
374         test_mkdir $DIR/$tdir
375         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
376         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
377         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
378         test_mkdir $DIR/$tdir/d/subdir
379         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
380                 error "$tdir/d/subdir should be GID $RUNAS_GID"
381         if [[ $MDSCOUNT -gt 1 ]]; then
382                 # check remote dir sgid inherite
383                 $LFS mkdir -i 0 $DIR/$tdir.local ||
384                         error "mkdir $tdir.local failed"
385                 chmod g+s $DIR/$tdir.local ||
386                         error "chmod $tdir.local failed"
387                 chgrp $RUNAS_GID $DIR/$tdir.local ||
388                         error "chgrp $tdir.local failed"
389                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
390                         error "mkdir $tdir.remote failed"
391                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
392                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
393                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
394                         error "$tdir.remote should be mode 02755"
395         fi
396 }
397 run_test 6g "verify new dir in sgid dir inherits group"
398
399 test_6h() { # bug 7331
400         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
401
402         touch $DIR/$tfile || error "touch failed"
403         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
404         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
405                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
406         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
407                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
408 }
409 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
410
411 test_7a() {
412         test_mkdir $DIR/$tdir
413         $MCREATE $DIR/$tdir/$tfile
414         chmod 0666 $DIR/$tdir/$tfile
415         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
416                 error "$tdir/$tfile should be mode 0666"
417 }
418 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
419
420 test_7b() {
421         if [ ! -d $DIR/$tdir ]; then
422                 test_mkdir $DIR/$tdir
423         fi
424         $MCREATE $DIR/$tdir/$tfile
425         echo -n foo > $DIR/$tdir/$tfile
426         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
427         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
428 }
429 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
430
431 test_8() {
432         test_mkdir $DIR/$tdir
433         touch $DIR/$tdir/$tfile
434         chmod 0666 $DIR/$tdir/$tfile
435         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
436                 error "$tfile mode not 0666"
437 }
438 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
439
440 test_9() {
441         test_mkdir $DIR/$tdir
442         test_mkdir $DIR/$tdir/d2
443         test_mkdir $DIR/$tdir/d2/d3
444         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
445 }
446 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
447
448 test_10() {
449         test_mkdir $DIR/$tdir
450         test_mkdir $DIR/$tdir/d2
451         touch $DIR/$tdir/d2/$tfile
452         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
453                 error "$tdir/d2/$tfile not a file"
454 }
455 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
456
457 test_11() {
458         test_mkdir $DIR/$tdir
459         test_mkdir $DIR/$tdir/d2
460         chmod 0666 $DIR/$tdir/d2
461         chmod 0705 $DIR/$tdir/d2
462         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
463                 error "$tdir/d2 mode not 0705"
464 }
465 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
466
467 test_12() {
468         test_mkdir $DIR/$tdir
469         touch $DIR/$tdir/$tfile
470         chmod 0666 $DIR/$tdir/$tfile
471         chmod 0654 $DIR/$tdir/$tfile
472         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
473                 error "$tdir/d2 mode not 0654"
474 }
475 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
476
477 test_13() {
478         test_mkdir $DIR/$tdir
479         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
480         >  $DIR/$tdir/$tfile
481         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
482                 error "$tdir/$tfile size not 0 after truncate"
483 }
484 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
485
486 test_14() {
487         test_mkdir $DIR/$tdir
488         touch $DIR/$tdir/$tfile
489         rm $DIR/$tdir/$tfile
490         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
491 }
492 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
493
494 test_15() {
495         test_mkdir $DIR/$tdir
496         touch $DIR/$tdir/$tfile
497         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
498         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
499                 error "$tdir/${tfile_2} not a file after rename"
500         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
501 }
502 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
503
504 test_16() {
505         test_mkdir $DIR/$tdir
506         touch $DIR/$tdir/$tfile
507         rm -rf $DIR/$tdir/$tfile
508         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
509 }
510 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
511
512 test_17a() {
513         test_mkdir $DIR/$tdir
514         touch $DIR/$tdir/$tfile
515         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
516         ls -l $DIR/$tdir
517         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
518                 error "$tdir/l-exist not a symlink"
519         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
520                 error "$tdir/l-exist not referencing a file"
521         rm -f $DIR/$tdir/l-exist
522         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
523 }
524 run_test 17a "symlinks: create, remove (real)"
525
526 test_17b() {
527         test_mkdir $DIR/$tdir
528         ln -s no-such-file $DIR/$tdir/l-dangle
529         ls -l $DIR/$tdir
530         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
531                 error "$tdir/l-dangle not referencing no-such-file"
532         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
533                 error "$tdir/l-dangle not referencing non-existent file"
534         rm -f $DIR/$tdir/l-dangle
535         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
536 }
537 run_test 17b "symlinks: create, remove (dangling)"
538
539 test_17c() { # bug 3440 - don't save failed open RPC for replay
540         test_mkdir $DIR/$tdir
541         ln -s foo $DIR/$tdir/$tfile
542         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
543 }
544 run_test 17c "symlinks: open dangling (should return error)"
545
546 test_17d() {
547         test_mkdir $DIR/$tdir
548         ln -s foo $DIR/$tdir/$tfile
549         touch $DIR/$tdir/$tfile || error "creating to new symlink"
550 }
551 run_test 17d "symlinks: create dangling"
552
553 test_17e() {
554         test_mkdir $DIR/$tdir
555         local foo=$DIR/$tdir/$tfile
556         ln -s $foo $foo || error "create symlink failed"
557         ls -l $foo || error "ls -l failed"
558         ls $foo && error "ls not failed" || true
559 }
560 run_test 17e "symlinks: create recursive symlink (should return error)"
561
562 test_17f() {
563         test_mkdir $DIR/$tdir
564         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
565         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
566         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
567         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
568         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
569         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
570         ls -l  $DIR/$tdir
571 }
572 run_test 17f "symlinks: long and very long symlink name"
573
574 # str_repeat(S, N) generate a string that is string S repeated N times
575 str_repeat() {
576         local s=$1
577         local n=$2
578         local ret=''
579         while [ $((n -= 1)) -ge 0 ]; do
580                 ret=$ret$s
581         done
582         echo $ret
583 }
584
585 # Long symlinks and LU-2241
586 test_17g() {
587         test_mkdir $DIR/$tdir
588         local TESTS="59 60 61 4094 4095"
589
590         # Fix for inode size boundary in 2.1.4
591         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
592                 TESTS="4094 4095"
593
594         # Patch not applied to 2.2 or 2.3 branches
595         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
596         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
597                 TESTS="4094 4095"
598
599         for i in $TESTS; do
600                 local SYMNAME=$(str_repeat 'x' $i)
601                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
602                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
603         done
604 }
605 run_test 17g "symlinks: really long symlink name and inode boundaries"
606
607 test_17h() { #bug 17378
608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
609         remote_mds_nodsh && skip "remote MDS with nodsh"
610
611         local mdt_idx
612
613         test_mkdir $DIR/$tdir
614         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
615         $LFS setstripe -c -1 $DIR/$tdir
616         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
617         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
618         touch $DIR/$tdir/$tfile || true
619 }
620 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
621
622 test_17i() { #bug 20018
623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625
626         local foo=$DIR/$tdir/$tfile
627         local mdt_idx
628
629         test_mkdir -c1 $DIR/$tdir
630         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
631         ln -s $foo $foo || error "create symlink failed"
632 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
633         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
634         ls -l $foo && error "error not detected"
635         return 0
636 }
637 run_test 17i "don't panic on short symlink (should return error)"
638
639 test_17k() { #bug 22301
640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
641         [[ -z "$(which rsync 2>/dev/null)" ]] &&
642                 skip "no rsync command"
643         rsync --help | grep -q xattr ||
644                 skip_env "$(rsync --version | head -n1) does not support xattrs"
645         test_mkdir $DIR/$tdir
646         test_mkdir $DIR/$tdir.new
647         touch $DIR/$tdir/$tfile
648         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
649         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
650                 error "rsync failed with xattrs enabled"
651 }
652 run_test 17k "symlinks: rsync with xattrs enabled"
653
654 test_17l() { # LU-279
655         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
656                 skip "no getfattr command"
657
658         test_mkdir $DIR/$tdir
659         touch $DIR/$tdir/$tfile
660         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
661         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
662                 # -h to not follow symlinks. -m '' to list all the xattrs.
663                 # grep to remove first line: '# file: $path'.
664                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
665                 do
666                         lgetxattr_size_check $path $xattr ||
667                                 error "lgetxattr_size_check $path $xattr failed"
668                 done
669         done
670 }
671 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
672
673 # LU-1540
674 test_17m() {
675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
676         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
677         remote_mds_nodsh && skip "remote MDS with nodsh"
678         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
679         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
680                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
681
682         local short_sym="0123456789"
683         local wdir=$DIR/$tdir
684         local i
685
686         test_mkdir $wdir
687         long_sym=$short_sym
688         # create a long symlink file
689         for ((i = 0; i < 4; ++i)); do
690                 long_sym=${long_sym}${long_sym}
691         done
692
693         echo "create 512 short and long symlink files under $wdir"
694         for ((i = 0; i < 256; ++i)); do
695                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
696                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
697         done
698
699         echo "erase them"
700         rm -f $wdir/*
701         sync
702         wait_delete_completed
703
704         echo "recreate the 512 symlink files with a shorter string"
705         for ((i = 0; i < 512; ++i)); do
706                 # rewrite the symlink file with a shorter string
707                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
708                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
709         done
710
711         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
712
713         echo "stop and checking mds${mds_index}:"
714         # e2fsck should not return error
715         stop mds${mds_index}
716         local devname=$(mdsdevname $mds_index)
717         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
718         rc=$?
719
720         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
721                 error "start mds${mds_index} failed"
722         df $MOUNT > /dev/null 2>&1
723         [ $rc -eq 0 ] ||
724                 error "e2fsck detected error for short/long symlink: rc=$rc"
725         rm -f $wdir/*
726 }
727 run_test 17m "run e2fsck against MDT which contains short/long symlink"
728
729 check_fs_consistency_17n() {
730         local mdt_index
731         local rc=0
732
733         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
734         # so it only check MDT1/MDT2 instead of all of MDTs.
735         for mdt_index in 1 2; do
736                 # e2fsck should not return error
737                 stop mds${mdt_index}
738                 local devname=$(mdsdevname $mdt_index)
739                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
740                         rc=$((rc + $?))
741
742                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
743                         error "mount mds$mdt_index failed"
744                 df $MOUNT > /dev/null 2>&1
745         done
746         return $rc
747 }
748
749 test_17n() {
750         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
752         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
753         remote_mds_nodsh && skip "remote MDS with nodsh"
754         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
755         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
756                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
757
758         local i
759
760         test_mkdir $DIR/$tdir
761         for ((i=0; i<10; i++)); do
762                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
763                         error "create remote dir error $i"
764                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
765                         error "create files under remote dir failed $i"
766         done
767
768         check_fs_consistency_17n ||
769                 error "e2fsck report error after create files under remote dir"
770
771         for ((i = 0; i < 10; i++)); do
772                 rm -rf $DIR/$tdir/remote_dir_${i} ||
773                         error "destroy remote dir error $i"
774         done
775
776         check_fs_consistency_17n ||
777                 error "e2fsck report error after unlink files under remote dir"
778
779         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
780                 skip "lustre < 2.4.50 does not support migrate mv"
781
782         for ((i = 0; i < 10; i++)); do
783                 mkdir -p $DIR/$tdir/remote_dir_${i}
784                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
785                         error "create files under remote dir failed $i"
786                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
787                         error "migrate remote dir error $i"
788         done
789         check_fs_consistency_17n || error "e2fsck report error after migration"
790
791         for ((i = 0; i < 10; i++)); do
792                 rm -rf $DIR/$tdir/remote_dir_${i} ||
793                         error "destroy remote dir error $i"
794         done
795
796         check_fs_consistency_17n || error "e2fsck report error after unlink"
797 }
798 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
799
800 test_17o() {
801         remote_mds_nodsh && skip "remote MDS with nodsh"
802         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
803                 skip "Need MDS version at least 2.3.64"
804
805         local wdir=$DIR/${tdir}o
806         local mdt_index
807         local rc=0
808
809         test_mkdir $wdir
810         touch $wdir/$tfile
811         mdt_index=$($LFS getstripe -m $wdir/$tfile)
812         mdt_index=$((mdt_index + 1))
813
814         cancel_lru_locks mdc
815         #fail mds will wait the failover finish then set
816         #following fail_loc to avoid interfer the recovery process.
817         fail mds${mdt_index}
818
819         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
820         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
821         ls -l $wdir/$tfile && rc=1
822         do_facet mds${mdt_index} lctl set_param fail_loc=0
823         [[ $rc -eq 0 ]] || error "stat file should fail"
824 }
825 run_test 17o "stat file with incompat LMA feature"
826
827 test_18() {
828         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
829         ls $DIR || error "Failed to ls $DIR: $?"
830 }
831 run_test 18 "touch .../f ; ls ... =============================="
832
833 test_19a() {
834         touch $DIR/$tfile
835         ls -l $DIR
836         rm $DIR/$tfile
837         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
838 }
839 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
840
841 test_19b() {
842         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
843 }
844 run_test 19b "ls -l .../f19 (should return error) =============="
845
846 test_19c() {
847         [ $RUNAS_ID -eq $UID ] &&
848                 skip_env "RUNAS_ID = UID = $UID -- skipping"
849
850         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
851 }
852 run_test 19c "$RUNAS touch .../f19 (should return error) =="
853
854 test_19d() {
855         cat $DIR/f19 && error || true
856 }
857 run_test 19d "cat .../f19 (should return error) =============="
858
859 test_20() {
860         touch $DIR/$tfile
861         rm $DIR/$tfile
862         touch $DIR/$tfile
863         rm $DIR/$tfile
864         touch $DIR/$tfile
865         rm $DIR/$tfile
866         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
867 }
868 run_test 20 "touch .../f ; ls -l ..."
869
870 test_21() {
871         test_mkdir $DIR/$tdir
872         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
873         ln -s dangle $DIR/$tdir/link
874         echo foo >> $DIR/$tdir/link
875         cat $DIR/$tdir/dangle
876         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
877         $CHECKSTAT -f -t file $DIR/$tdir/link ||
878                 error "$tdir/link not linked to a file"
879 }
880 run_test 21 "write to dangling link"
881
882 test_22() {
883         local wdir=$DIR/$tdir
884         test_mkdir $wdir
885         chown $RUNAS_ID:$RUNAS_GID $wdir
886         (cd $wdir || error "cd $wdir failed";
887                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
888                 $RUNAS tar xf -)
889         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
890         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
891         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
892                 error "checkstat -u failed"
893 }
894 run_test 22 "unpack tar archive as non-root user"
895
896 # was test_23
897 test_23a() {
898         test_mkdir $DIR/$tdir
899         local file=$DIR/$tdir/$tfile
900
901         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
902         openfile -f O_CREAT:O_EXCL $file &&
903                 error "$file recreate succeeded" || true
904 }
905 run_test 23a "O_CREAT|O_EXCL in subdir"
906
907 test_23b() { # bug 18988
908         test_mkdir $DIR/$tdir
909         local file=$DIR/$tdir/$tfile
910
911         rm -f $file
912         echo foo > $file || error "write filed"
913         echo bar >> $file || error "append filed"
914         $CHECKSTAT -s 8 $file || error "wrong size"
915         rm $file
916 }
917 run_test 23b "O_APPEND check"
918
919 # LU-9409, size with O_APPEND and tiny writes
920 test_23c() {
921         local file=$DIR/$tfile
922
923         # single dd
924         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
925         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
926         rm -f $file
927
928         # racing tiny writes
929         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
930         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
931         wait
932         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
933         rm -f $file
934
935         #racing tiny & normal writes
936         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
937         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
938         wait
939         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
940         rm -f $file
941
942         #racing tiny & normal writes 2, ugly numbers
943         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
944         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
945         wait
946         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
947         rm -f $file
948 }
949 run_test 23c "O_APPEND size checks for tiny writes"
950
951 # LU-11069 file offset is correct after appending writes
952 test_23d() {
953         local file=$DIR/$tfile
954         local offset
955
956         echo CentaurHauls > $file
957         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
958         if ((offset != 26)); then
959                 error "wrong offset, expected 26, got '$offset'"
960         fi
961 }
962 run_test 23d "file offset is correct after appending writes"
963
964 # rename sanity
965 test_24a() {
966         echo '-- same directory rename'
967         test_mkdir $DIR/$tdir
968         touch $DIR/$tdir/$tfile.1
969         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
970         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
971 }
972 run_test 24a "rename file to non-existent target"
973
974 test_24b() {
975         test_mkdir $DIR/$tdir
976         touch $DIR/$tdir/$tfile.{1,2}
977         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
978         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
979         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
980 }
981 run_test 24b "rename file to existing target"
982
983 test_24c() {
984         test_mkdir $DIR/$tdir
985         test_mkdir $DIR/$tdir/d$testnum.1
986         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
987         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
988         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
989 }
990 run_test 24c "rename directory to non-existent target"
991
992 test_24d() {
993         test_mkdir -c1 $DIR/$tdir
994         test_mkdir -c1 $DIR/$tdir/d$testnum.1
995         test_mkdir -c1 $DIR/$tdir/d$testnum.2
996         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
997         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
998         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
999 }
1000 run_test 24d "rename directory to existing target"
1001
1002 test_24e() {
1003         echo '-- cross directory renames --'
1004         test_mkdir $DIR/R5a
1005         test_mkdir $DIR/R5b
1006         touch $DIR/R5a/f
1007         mv $DIR/R5a/f $DIR/R5b/g
1008         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
1009         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
1010 }
1011 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
1012
1013 test_24f() {
1014         test_mkdir $DIR/R6a
1015         test_mkdir $DIR/R6b
1016         touch $DIR/R6a/f $DIR/R6b/g
1017         mv $DIR/R6a/f $DIR/R6b/g
1018         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
1019         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
1020 }
1021 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
1022
1023 test_24g() {
1024         test_mkdir $DIR/R7a
1025         test_mkdir $DIR/R7b
1026         test_mkdir $DIR/R7a/d
1027         mv $DIR/R7a/d $DIR/R7b/e
1028         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
1029         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
1030 }
1031 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
1032
1033 test_24h() {
1034         test_mkdir -c1 $DIR/R8a
1035         test_mkdir -c1 $DIR/R8b
1036         test_mkdir -c1 $DIR/R8a/d
1037         test_mkdir -c1 $DIR/R8b/e
1038         mrename $DIR/R8a/d $DIR/R8b/e
1039         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
1040         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
1041 }
1042 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
1043
1044 test_24i() {
1045         echo "-- rename error cases"
1046         test_mkdir $DIR/R9
1047         test_mkdir $DIR/R9/a
1048         touch $DIR/R9/f
1049         mrename $DIR/R9/f $DIR/R9/a
1050         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
1051         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
1052         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1053 }
1054 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1055
1056 test_24j() {
1057         test_mkdir $DIR/R10
1058         mrename $DIR/R10/f $DIR/R10/g
1059         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1060         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1061         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1062 }
1063 run_test 24j "source does not exist ============================"
1064
1065 test_24k() {
1066         test_mkdir $DIR/R11a
1067         test_mkdir $DIR/R11a/d
1068         touch $DIR/R11a/f
1069         mv $DIR/R11a/f $DIR/R11a/d
1070         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1071         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1072 }
1073 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1074
1075 # bug 2429 - rename foo foo foo creates invalid file
1076 test_24l() {
1077         f="$DIR/f24l"
1078         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1079 }
1080 run_test 24l "Renaming a file to itself ========================"
1081
1082 test_24m() {
1083         f="$DIR/f24m"
1084         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1085         # on ext3 this does not remove either the source or target files
1086         # though the "expected" operation would be to remove the source
1087         $CHECKSTAT -t file ${f} || error "${f} missing"
1088         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1089 }
1090 run_test 24m "Renaming a file to a hard link to itself ========="
1091
1092 test_24n() {
1093     f="$DIR/f24n"
1094     # this stats the old file after it was renamed, so it should fail
1095     touch ${f}
1096     $CHECKSTAT ${f} || error "${f} missing"
1097     mv ${f} ${f}.rename
1098     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1099     $CHECKSTAT -a ${f} || error "${f} exists"
1100 }
1101 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1102
1103 test_24o() {
1104         test_mkdir $DIR/$tdir
1105         rename_many -s random -v -n 10 $DIR/$tdir
1106 }
1107 run_test 24o "rename of files during htree split"
1108
1109 test_24p() {
1110         test_mkdir $DIR/R12a
1111         test_mkdir $DIR/R12b
1112         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1113         mrename $DIR/R12a $DIR/R12b
1114         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1115         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1116         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1117         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1118 }
1119 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1120
1121 cleanup_multiop_pause() {
1122         trap 0
1123         kill -USR1 $MULTIPID
1124 }
1125
1126 test_24q() {
1127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1128
1129         test_mkdir $DIR/R13a
1130         test_mkdir $DIR/R13b
1131         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1132         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1133         MULTIPID=$!
1134
1135         trap cleanup_multiop_pause EXIT
1136         mrename $DIR/R13a $DIR/R13b
1137         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1138         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1139         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1140         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1141         cleanup_multiop_pause
1142         wait $MULTIPID || error "multiop close failed"
1143 }
1144 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1145
1146 test_24r() { #bug 3789
1147         test_mkdir $DIR/R14a
1148         test_mkdir $DIR/R14a/b
1149         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1150         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1151         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1152 }
1153 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1154
1155 test_24s() {
1156         test_mkdir $DIR/R15a
1157         test_mkdir $DIR/R15a/b
1158         test_mkdir $DIR/R15a/b/c
1159         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1160         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1161         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1162 }
1163 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1164
1165 test_24t() {
1166         test_mkdir $DIR/R16a
1167         test_mkdir $DIR/R16a/b
1168         test_mkdir $DIR/R16a/b/c
1169         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1170         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1171         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1172 }
1173 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1174
1175 test_24u() { # bug12192
1176         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1177         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1178 }
1179 run_test 24u "create stripe file"
1180
1181 simple_cleanup_common() {
1182         local createmany=$1
1183         local rc=0
1184
1185         [[ -z "$DIR" || -z "$tdir" || ! -d "$DIR/$tdir" ]] && return 0
1186
1187         local start=$SECONDS
1188
1189         [[ -n "$createmany" ]] && unlinkmany $DIR/$tdir/$tfile $createmany
1190         rm -rf $DIR/$tdir || error "cleanup $DIR/$tdir failed"
1191         rc=$?
1192         wait_delete_completed
1193         echo "cleanup time $((SECONDS - start))"
1194         return $rc
1195 }
1196
1197 max_pages_per_rpc() {
1198         local mdtname="$(printf "MDT%04x" ${1:-0})"
1199         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1200 }
1201
1202 test_24v() {
1203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1204
1205         local nrfiles=${COUNT:-100000}
1206         local fname="$DIR/$tdir/$tfile"
1207
1208         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1209         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1210
1211         test_mkdir "$(dirname $fname)"
1212         # assume MDT0000 has the fewest inodes
1213         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1214         local free_inodes=$(($(mdt_free_inodes 0) * ${stripes/#0/1}))
1215         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1216
1217         stack_trap "simple_cleanup_common $nrfiles"
1218
1219         createmany -m "$fname" $nrfiles
1220
1221         cancel_lru_locks mdc
1222         lctl set_param mdc.*.stats clear
1223
1224         # was previously test_24D: LU-6101
1225         # readdir() returns correct number of entries after cursor reload
1226         local num_ls=$(ls $DIR/$tdir | wc -l)
1227         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1228         local num_all=$(ls -a $DIR/$tdir | wc -l)
1229         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1230                 [ $num_all -ne $((nrfiles + 2)) ]; then
1231                         error "Expected $nrfiles files, got $num_ls " \
1232                                 "($num_uniq unique $num_all .&..)"
1233         fi
1234         # LU-5 large readdir
1235         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1236         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1237         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1238         # take into account of overhead in lu_dirpage header and end mark in
1239         # each page, plus one in rpc_num calculation.
1240         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1241         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1242         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1243         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1244         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1245         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1246         echo "readpages: $mds_readpage rpc_max: $rpc_max-2/+1"
1247         (( $mds_readpage >= $rpc_max - 2 && $mds_readpage <= $rpc_max + 1)) ||
1248                 error "large readdir doesn't take effect: " \
1249                       "$mds_readpage should be about $rpc_max"
1250 }
1251 run_test 24v "list large directory (test hash collision, b=17560)"
1252
1253 test_24w() { # bug21506
1254         SZ1=234852
1255         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1256         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1257         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1258         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1259         [[ "$SZ1" -eq "$SZ2" ]] ||
1260                 error "Error reading at the end of the file $tfile"
1261 }
1262 run_test 24w "Reading a file larger than 4Gb"
1263
1264 test_24x() {
1265         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1267         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1268                 skip "Need MDS version at least 2.7.56"
1269
1270         local MDTIDX=1
1271         local remote_dir=$DIR/$tdir/remote_dir
1272
1273         test_mkdir $DIR/$tdir
1274         $LFS mkdir -i $MDTIDX $remote_dir ||
1275                 error "create remote directory failed"
1276
1277         test_mkdir $DIR/$tdir/src_dir
1278         touch $DIR/$tdir/src_file
1279         test_mkdir $remote_dir/tgt_dir
1280         touch $remote_dir/tgt_file
1281
1282         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1283                 error "rename dir cross MDT failed!"
1284
1285         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1286                 error "rename file cross MDT failed!"
1287
1288         touch $DIR/$tdir/ln_file
1289         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1290                 error "ln file cross MDT failed"
1291
1292         rm -rf $DIR/$tdir || error "Can not delete directories"
1293 }
1294 run_test 24x "cross MDT rename/link"
1295
1296 test_24y() {
1297         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1299
1300         local remote_dir=$DIR/$tdir/remote_dir
1301         local mdtidx=1
1302
1303         test_mkdir $DIR/$tdir
1304         $LFS mkdir -i $mdtidx $remote_dir ||
1305                 error "create remote directory failed"
1306
1307         test_mkdir $remote_dir/src_dir
1308         touch $remote_dir/src_file
1309         test_mkdir $remote_dir/tgt_dir
1310         touch $remote_dir/tgt_file
1311
1312         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1313                 error "rename subdir in the same remote dir failed!"
1314
1315         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1316                 error "rename files in the same remote dir failed!"
1317
1318         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1319                 error "link files in the same remote dir failed!"
1320
1321         rm -rf $DIR/$tdir || error "Can not delete directories"
1322 }
1323 run_test 24y "rename/link on the same dir should succeed"
1324
1325 test_24z() {
1326         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1327         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1328                 skip "Need MDS version at least 2.12.51"
1329
1330         local index
1331
1332         for index in 0 1; do
1333                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1334                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1335         done
1336
1337         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1338
1339         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1340         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1341
1342         local mdts=$(comma_list $(mdts_nodes))
1343
1344         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1345         stack_trap "do_nodes $mdts $LCTL \
1346                 set_param mdt.*.enable_remote_rename=1" EXIT
1347
1348         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1349
1350         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1351         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1352 }
1353 run_test 24z "cross-MDT rename is done as cp"
1354
1355 test_24A() { # LU-3182
1356         local NFILES=5000
1357
1358         test_mkdir $DIR/$tdir
1359         stack_trap "simple_cleanup_common $NFILES"
1360         createmany -m $DIR/$tdir/$tfile $NFILES
1361         local t=$(ls $DIR/$tdir | wc -l)
1362         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1363         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1364
1365         (( $t == $NFILES && $u == $NFILES && $v == NFILES + 2 )) ||
1366                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1367 }
1368 run_test 24A "readdir() returns correct number of entries."
1369
1370 test_24B() { # LU-4805
1371         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1372
1373         local count
1374
1375         test_mkdir $DIR/$tdir
1376         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir/ ||
1377                 error "create striped dir failed"
1378
1379         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1380         [ $count -eq 2 ] || error "Expected 2, got $count"
1381
1382         touch $DIR/$tdir/striped_dir/a
1383
1384         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1385         [ $count -eq 3 ] || error "Expected 3, got $count"
1386
1387         touch $DIR/$tdir/striped_dir/.f
1388
1389         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1390         [ $count -eq 4 ] || error "Expected 4, got $count"
1391
1392         rm -rf $DIR/$tdir || error "Can not delete directories"
1393 }
1394 run_test 24B "readdir for striped dir return correct number of entries"
1395
1396 test_24C() {
1397         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1398
1399         mkdir $DIR/$tdir
1400         mkdir $DIR/$tdir/d0
1401         mkdir $DIR/$tdir/d1
1402
1403         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1404                 error "create striped dir failed"
1405
1406         cd $DIR/$tdir/d0/striped_dir
1407
1408         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1409         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1410         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1411
1412         [ "$d0_ino" = "$parent_ino" ] ||
1413                 error ".. wrong, expect $d0_ino, get $parent_ino"
1414
1415         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1416                 error "mv striped dir failed"
1417
1418         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1419
1420         [ "$d1_ino" = "$parent_ino" ] ||
1421                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1422 }
1423 run_test 24C "check .. in striped dir"
1424
1425 test_24E() {
1426         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1428
1429         mkdir -p $DIR/$tdir
1430         mkdir $DIR/$tdir/src_dir
1431         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1432                 error "create remote source failed"
1433
1434         touch $DIR/$tdir/src_dir/src_child/a
1435
1436         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1437                 error "create remote target dir failed"
1438
1439         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1440                 error "create remote target child failed"
1441
1442         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1443                 error "rename dir cross MDT failed!"
1444
1445         find $DIR/$tdir
1446
1447         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1448                 error "src_child still exists after rename"
1449
1450         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1451                 error "missing file(a) after rename"
1452
1453         rm -rf $DIR/$tdir || error "Can not delete directories"
1454 }
1455 run_test 24E "cross MDT rename/link"
1456
1457 test_24F () {
1458         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1459
1460         local repeats=1000
1461         [ "$SLOW" = "no" ] && repeats=100
1462
1463         mkdir -p $DIR/$tdir
1464
1465         echo "$repeats repeats"
1466         for ((i = 0; i < repeats; i++)); do
1467                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1468                 touch $DIR/$tdir/test/a || error "touch fails"
1469                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1470                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1471         done
1472
1473         true
1474 }
1475 run_test 24F "hash order vs readdir (LU-11330)"
1476
1477 test_24G () {
1478         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1479
1480         local ino1
1481         local ino2
1482
1483         $LFS mkdir -i 0 $DIR/$tdir-0 || error "mkdir $tdir-0"
1484         $LFS mkdir -i 1 $DIR/$tdir-1 || error "mkdir $tdir-1"
1485         touch $DIR/$tdir-0/f1 || error "touch f1"
1486         ln -s $DIR/$tdir-0/f1 $DIR/$tdir-0/s1 || error "ln s1"
1487         ino1=$(stat -c%i $DIR/$tdir-0/s1)
1488         mv $DIR/$tdir-0/s1 $DIR/$tdir-1 || error "mv s1"
1489         ino2=$(stat -c%i $DIR/$tdir-1/s1)
1490         [ $ino1 -ne $ino2 ] || error "s1 should be migrated"
1491 }
1492 run_test 24G "migrate symlink in rename"
1493
1494 test_24H() {
1495         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
1496         [[ $(hostname) != $(facet_active_host mds2) ]] ||
1497                 skip "MDT1 should be on another node"
1498
1499         test_mkdir -i 1 -c 1 $DIR/$tdir
1500 #define OBD_FAIL_FLD_QUERY_REQ           0x1103
1501         do_facet mds2 $LCTL set_param fail_loc=0x80001103
1502         touch $DIR/$tdir/$tfile || error "touch failed"
1503 }
1504 run_test 24H "repeat FLD_QUERY rpc"
1505
1506 test_25a() {
1507         echo '== symlink sanity ============================================='
1508
1509         test_mkdir $DIR/d25
1510         ln -s d25 $DIR/s25
1511         touch $DIR/s25/foo ||
1512                 error "File creation in symlinked directory failed"
1513 }
1514 run_test 25a "create file in symlinked directory ==============="
1515
1516 test_25b() {
1517         [ ! -d $DIR/d25 ] && test_25a
1518         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1519 }
1520 run_test 25b "lookup file in symlinked directory ==============="
1521
1522 test_26a() {
1523         test_mkdir $DIR/d26
1524         test_mkdir $DIR/d26/d26-2
1525         ln -s d26/d26-2 $DIR/s26
1526         touch $DIR/s26/foo || error "File creation failed"
1527 }
1528 run_test 26a "multiple component symlink ======================="
1529
1530 test_26b() {
1531         test_mkdir -p $DIR/$tdir/d26-2
1532         ln -s $tdir/d26-2/foo $DIR/s26-2
1533         touch $DIR/s26-2 || error "File creation failed"
1534 }
1535 run_test 26b "multiple component symlink at end of lookup ======"
1536
1537 test_26c() {
1538         test_mkdir $DIR/d26.2
1539         touch $DIR/d26.2/foo
1540         ln -s d26.2 $DIR/s26.2-1
1541         ln -s s26.2-1 $DIR/s26.2-2
1542         ln -s s26.2-2 $DIR/s26.2-3
1543         chmod 0666 $DIR/s26.2-3/foo
1544 }
1545 run_test 26c "chain of symlinks"
1546
1547 # recursive symlinks (bug 439)
1548 test_26d() {
1549         ln -s d26-3/foo $DIR/d26-3
1550 }
1551 run_test 26d "create multiple component recursive symlink"
1552
1553 test_26e() {
1554         [ ! -h $DIR/d26-3 ] && test_26d
1555         rm $DIR/d26-3
1556 }
1557 run_test 26e "unlink multiple component recursive symlink"
1558
1559 # recursive symlinks (bug 7022)
1560 test_26f() {
1561         test_mkdir $DIR/$tdir
1562         test_mkdir $DIR/$tdir/$tfile
1563         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1564         test_mkdir -p lndir/bar1
1565         test_mkdir $DIR/$tdir/$tfile/$tfile
1566         cd $tfile                || error "cd $tfile failed"
1567         ln -s .. dotdot          || error "ln dotdot failed"
1568         ln -s dotdot/lndir lndir || error "ln lndir failed"
1569         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1570         output=`ls $tfile/$tfile/lndir/bar1`
1571         [ "$output" = bar1 ] && error "unexpected output"
1572         rm -r $tfile             || error "rm $tfile failed"
1573         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1574 }
1575 run_test 26f "rm -r of a directory which has recursive symlink"
1576
1577 test_27a() {
1578         test_mkdir $DIR/$tdir
1579         $LFS getstripe $DIR/$tdir
1580         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1581         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1582         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1583 }
1584 run_test 27a "one stripe file"
1585
1586 test_27b() {
1587         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1588
1589         test_mkdir $DIR/$tdir
1590         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1591         $LFS getstripe -c $DIR/$tdir/$tfile
1592         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1593                 error "two-stripe file doesn't have two stripes"
1594
1595         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1596 }
1597 run_test 27b "create and write to two stripe file"
1598
1599 # 27c family tests specific striping, setstripe -o
1600 test_27ca() {
1601         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1602         test_mkdir -p $DIR/$tdir
1603         local osts="1"
1604
1605         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1606         $LFS getstripe -i $DIR/$tdir/$tfile
1607         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1608                 error "stripe not on specified OST"
1609
1610         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1611 }
1612 run_test 27ca "one stripe on specified OST"
1613
1614 test_27cb() {
1615         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1616         test_mkdir -p $DIR/$tdir
1617         local osts="1,0"
1618         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1619         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1620         echo "$getstripe"
1621
1622         # Strip getstripe output to a space separated list of OSTs
1623         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1624                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1625         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1626                 error "stripes not on specified OSTs"
1627
1628         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1629 }
1630 run_test 27cb "two stripes on specified OSTs"
1631
1632 test_27cc() {
1633         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1634         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1635                 skip "server does not support overstriping"
1636
1637         test_mkdir -p $DIR/$tdir
1638         local osts="0,0"
1639         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1640         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1641         echo "$getstripe"
1642
1643         # Strip getstripe output to a space separated list of OSTs
1644         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1645                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1646         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1647                 error "stripes not on specified OSTs"
1648
1649         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1650 }
1651 run_test 27cc "two stripes on the same OST"
1652
1653 test_27cd() {
1654         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1655         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1656                 skip "server does not support overstriping"
1657         test_mkdir -p $DIR/$tdir
1658         local osts="0,1,1,0"
1659         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1660         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1661         echo "$getstripe"
1662
1663         # Strip getstripe output to a space separated list of OSTs
1664         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1665                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1666         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1667                 error "stripes not on specified OSTs"
1668
1669         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1670 }
1671 run_test 27cd "four stripes on two OSTs"
1672
1673 test_27ce() {
1674         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1675                 skip_env "too many osts, skipping"
1676         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1677                 skip "server does not support overstriping"
1678         # We do one more stripe than we have OSTs
1679         [ $OSTCOUNT -lt 159 ] || large_xattr_enabled ||
1680                 skip_env "ea_inode feature disabled"
1681
1682         test_mkdir -p $DIR/$tdir
1683         local osts=""
1684         for i in $(seq 0 $OSTCOUNT);
1685         do
1686                 osts=$osts"0"
1687                 if [ $i -ne $OSTCOUNT ]; then
1688                         osts=$osts","
1689                 fi
1690         done
1691         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1692         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1693         echo "$getstripe"
1694
1695         # Strip getstripe output to a space separated list of OSTs
1696         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1697                 awk '{print $1}' | tr '\n' ' ' | sed -e 's/[[:space:]]*$//')
1698         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1699                 error "stripes not on specified OSTs"
1700
1701         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1702 }
1703 run_test 27ce "more stripes than OSTs with -o"
1704
1705 test_27cf() {
1706         local osp_proc="osp.$FSNAME-OST0000-osc-MDT000*.active"
1707         local pid=0
1708
1709         test_mkdir -p $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
1710         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=0"
1711         stack_trap "do_facet $SINGLEMDS $LCTL set_param -n $osp_proc=1" EXIT
1712         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 1" ||
1713                 error "failed to set $osp_proc=0"
1714
1715         $LFS setstripe -o 0 $DIR/$tdir/$tfile &
1716         pid=$!
1717         sleep 1
1718         do_facet $SINGLEMDS "$LCTL set_param -n $osp_proc=1"
1719         wait_update_facet $SINGLEMDS "$LCTL get_param -n $osp_proc | grep 0" ||
1720                 error "failed to set $osp_proc=1"
1721         wait $pid
1722         [[ $pid -ne 0 ]] ||
1723                 error "should return error due to $osp_proc=0"
1724 }
1725 run_test 27cf "'setstripe -o' on inactive OSTs should return error"
1726
1727 test_27cg() {
1728         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1729                 skip "server does not support overstriping"
1730         [[ $mds1_FSTYPE != "ldiskfs" ]] && skip_env "ldiskfs only test"
1731         large_xattr_enabled || skip_env "ea_inode feature disabled"
1732
1733         local osts="0"
1734
1735         for ((i=1;i<1000;i++)); do
1736                 osts+=",$((i % OSTCOUNT))"
1737         done
1738
1739         local mdts=$(comma_list $(mdts_nodes))
1740         local before=$(do_nodes $mdts \
1741                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1742                 awk '/many credits/{print $3}' |
1743                 calc_sum)
1744
1745         $LFS setstripe -o $osts $DIR/$tfile || error "setstripe failed"
1746         $LFS getstripe $DIR/$tfile | grep stripe
1747
1748         rm -f $DIR/$tfile || error "can't unlink"
1749
1750         after=$(do_nodes $mdts \
1751                 "$LCTL get_param -n osd-ldiskfs.*MDT*.stats" |
1752                 awk '/many credits/{print $3}' |
1753                 calc_sum)
1754
1755         (( before == after )) ||
1756                 error "too many credits happened: $after > $before"
1757 }
1758 run_test 27cg "1000 shouldn't cause too many credits"
1759
1760 test_27d() {
1761         test_mkdir $DIR/$tdir
1762         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1763                 error "setstripe failed"
1764         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1765         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1766 }
1767 run_test 27d "create file with default settings"
1768
1769 test_27e() {
1770         # LU-5839 adds check for existed layout before setting it
1771         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1772                 skip "Need MDS version at least 2.7.56"
1773
1774         test_mkdir $DIR/$tdir
1775         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1776         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1777         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1778 }
1779 run_test 27e "setstripe existing file (should return error)"
1780
1781 test_27f() {
1782         test_mkdir $DIR/$tdir
1783         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1784                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1785         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1786                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1787         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1788         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1789 }
1790 run_test 27f "setstripe with bad stripe size (should return error)"
1791
1792 test_27g() {
1793         test_mkdir $DIR/$tdir
1794         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1795         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1796                 error "$DIR/$tdir/$tfile has object"
1797 }
1798 run_test 27g "$LFS getstripe with no objects"
1799
1800 test_27ga() {
1801         test_mkdir $DIR/$tdir
1802         touch $DIR/$tdir/$tfile || error "touch failed"
1803         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1804         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1805         local rc=$?
1806         (( rc == 2 )) || error "getstripe did not return ENOENT"
1807 }
1808 run_test 27ga "$LFS getstripe with missing file (should return error)"
1809
1810 test_27i() {
1811         test_mkdir $DIR/$tdir
1812         touch $DIR/$tdir/$tfile || error "touch failed"
1813         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1814                 error "missing objects"
1815 }
1816 run_test 27i "$LFS getstripe with some objects"
1817
1818 test_27j() {
1819         test_mkdir $DIR/$tdir
1820         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1821                 error "setstripe failed" || true
1822 }
1823 run_test 27j "setstripe with bad stripe offset (should return error)"
1824
1825 test_27k() { # bug 2844
1826         test_mkdir $DIR/$tdir
1827         local file=$DIR/$tdir/$tfile
1828         local ll_max_blksize=$((4 * 1024 * 1024))
1829         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1830         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1831         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1832         dd if=/dev/zero of=$file bs=4k count=1
1833         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1834         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1835 }
1836 run_test 27k "limit i_blksize for broken user apps"
1837
1838 test_27l() {
1839         mcreate $DIR/$tfile || error "creating file"
1840         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1841                 error "setstripe should have failed" || true
1842 }
1843 run_test 27l "check setstripe permissions (should return error)"
1844
1845 test_27m() {
1846         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1847
1848         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1849                 skip_env "multiple clients -- skipping"
1850
1851         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1852                    head -n1)
1853         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1854                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1855         fi
1856         stack_trap simple_cleanup_common
1857         test_mkdir $DIR/$tdir
1858         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1859         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1860                 error "dd should fill OST0"
1861         i=2
1862         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1863                 i=$((i + 1))
1864                 [ $i -gt 256 ] && break
1865         done
1866         i=$((i + 1))
1867         touch $DIR/$tdir/$tfile.$i
1868         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1869             awk '{print $1}'| grep -w "0") ] &&
1870                 error "OST0 was full but new created file still use it"
1871         i=$((i + 1))
1872         touch $DIR/$tdir/$tfile.$i
1873         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1874             awk '{print $1}'| grep -w "0") ] &&
1875                 error "OST0 was full but new created file still use it" || true
1876 }
1877 run_test 27m "create file while OST0 was full"
1878
1879 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1880 # if the OST isn't full anymore.
1881 reset_enospc() {
1882         local ostidx=${1:-""}
1883         local delay
1884         local ready
1885         local get_prealloc
1886
1887         local list=$(comma_list $(osts_nodes))
1888         [ "$ostidx" ] && list=$(facet_host ost$((ostidx + 1)))
1889
1890         do_nodes $list lctl set_param fail_loc=0
1891         wait_delete_completed   # initiate all OST_DESTROYs from MDS to OST
1892         delay=$(do_facet $SINGLEMDS lctl get_param -n lov.*.qos_maxage |
1893                 awk '{print $1 * 2;exit;}')
1894         get_prealloc="$LCTL get_param -n osc.*MDT*.prealloc_status |
1895                         grep -v \"^0$\""
1896         wait_update_facet $SINGLEMDS "$get_prealloc" "" $delay
1897 }
1898
1899 test_27n() {
1900         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1902         remote_mds_nodsh && skip "remote MDS with nodsh"
1903         remote_ost_nodsh && skip "remote OST with nodsh"
1904
1905         reset_enospc
1906         rm -f $DIR/$tdir/$tfile
1907         exhaust_precreations 0 0x80000215
1908         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1909         touch $DIR/$tdir/$tfile || error "touch failed"
1910         $LFS getstripe $DIR/$tdir/$tfile
1911         reset_enospc
1912 }
1913 run_test 27n "create file with some full OSTs"
1914
1915 test_27o() {
1916         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1917         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1918         remote_mds_nodsh && skip "remote MDS with nodsh"
1919         remote_ost_nodsh && skip "remote OST with nodsh"
1920
1921         reset_enospc
1922         rm -f $DIR/$tdir/$tfile
1923         exhaust_all_precreations 0x215
1924
1925         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1926
1927         reset_enospc
1928         rm -rf $DIR/$tdir/*
1929 }
1930 run_test 27o "create file with all full OSTs (should error)"
1931
1932 function create_and_checktime() {
1933         local fname=$1
1934         local loops=$2
1935         local i
1936
1937         for ((i=0; i < $loops; i++)); do
1938                 local start=$SECONDS
1939                 multiop $fname-$i Oc
1940                 ((SECONDS-start < TIMEOUT)) ||
1941                         error "creation took " $((SECONDS-$start)) && return 1
1942         done
1943 }
1944
1945 test_27oo() {
1946         local mdts=$(comma_list $(mdts_nodes))
1947
1948         [ $MDS1_VERSION -lt $(version_code 2.13.57) ] &&
1949                 skip "Need MDS version at least 2.13.57"
1950
1951         local f0=$DIR/${tfile}-0
1952         local f1=$DIR/${tfile}-1
1953
1954         wait_delete_completed
1955
1956         # refill precreated objects
1957         $LFS setstripe -i0 -c1 $f0
1958
1959         saved=$(do_facet mds1 $LCTL get_param -n lov.*0000*.qos_threshold_rr)
1960         # force QoS allocation policy
1961         do_nodes $mdts $LCTL set_param lov.*.qos_threshold_rr=0%
1962         stack_trap "do_nodes $mdts $LCTL set_param \
1963                 lov.*.qos_threshold_rr=$saved" EXIT
1964         sleep_maxage
1965
1966         # one OST is unavailable, but still have few objects preallocated
1967         stop ost1
1968         stack_trap "start ost1 $(ostdevname 1) $OST_MOUNT_OPTS; \
1969                 rm -rf $f1 $DIR/$tdir*" EXIT
1970
1971         for ((i=0; i < 7; i++)); do
1972                 mkdir $DIR/$tdir$i || error "can't create dir"
1973                 $LFS setstripe -c$((OSTCOUNT-1)) $DIR/$tdir$i ||
1974                         error "can't set striping"
1975         done
1976         for ((i=0; i < 7; i++)); do
1977                 create_and_checktime $DIR/$tdir$i/$tfile 100 &
1978         done
1979         wait
1980 }
1981 run_test 27oo "don't let few threads to reserve too many objects"
1982
1983 test_27p() {
1984         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1986         remote_mds_nodsh && skip "remote MDS with nodsh"
1987         remote_ost_nodsh && skip "remote OST with nodsh"
1988
1989         reset_enospc
1990         rm -f $DIR/$tdir/$tfile
1991         test_mkdir $DIR/$tdir
1992
1993         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1994         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1995         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1996
1997         exhaust_precreations 0 0x80000215
1998         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1999         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
2000         $LFS getstripe $DIR/$tdir/$tfile
2001
2002         reset_enospc
2003 }
2004 run_test 27p "append to a truncated file with some full OSTs"
2005
2006 test_27q() {
2007         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2009         remote_mds_nodsh && skip "remote MDS with nodsh"
2010         remote_ost_nodsh && skip "remote OST with nodsh"
2011
2012         reset_enospc
2013         rm -f $DIR/$tdir/$tfile
2014
2015         mkdir_on_mdt0 $DIR/$tdir
2016         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
2017         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
2018                 error "truncate $DIR/$tdir/$tfile failed"
2019         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
2020
2021         exhaust_all_precreations 0x215
2022
2023         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
2024         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
2025
2026         reset_enospc
2027 }
2028 run_test 27q "append to truncated file with all OSTs full (should error)"
2029
2030 test_27r() {
2031         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2033         remote_mds_nodsh && skip "remote MDS with nodsh"
2034         remote_ost_nodsh && skip "remote OST with nodsh"
2035
2036         reset_enospc
2037         rm -f $DIR/$tdir/$tfile
2038         exhaust_precreations 0 0x80000215
2039
2040         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
2041
2042         reset_enospc
2043 }
2044 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
2045
2046 test_27s() { # bug 10725
2047         test_mkdir $DIR/$tdir
2048         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
2049         local stripe_count=0
2050         [ $OSTCOUNT -eq 1 ] || stripe_count=2
2051         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
2052                 error "stripe width >= 2^32 succeeded" || true
2053
2054 }
2055 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
2056
2057 test_27t() { # bug 10864
2058         WDIR=$(pwd)
2059         WLFS=$(which lfs)
2060         cd $DIR
2061         touch $tfile
2062         $WLFS getstripe $tfile
2063         cd $WDIR
2064 }
2065 run_test 27t "check that utils parse path correctly"
2066
2067 test_27u() { # bug 4900
2068         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2069         remote_mds_nodsh && skip "remote MDS with nodsh"
2070
2071         local index
2072         local list=$(comma_list $(mdts_nodes))
2073
2074 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
2075         do_nodes $list $LCTL set_param fail_loc=0x139
2076         test_mkdir -p $DIR/$tdir
2077         stack_trap "simple_cleanup_common 1000"
2078         createmany -o $DIR/$tdir/$tfile 1000
2079         do_nodes $list $LCTL set_param fail_loc=0
2080
2081         TLOG=$TMP/$tfile.getstripe
2082         $LFS getstripe $DIR/$tdir > $TLOG
2083         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
2084         [[ $OBJS -gt 0 ]] &&
2085                 error "$OBJS objects created on OST-0. See $TLOG" ||
2086                 rm -f $TLOG
2087 }
2088 run_test 27u "skip object creation on OSC w/o objects"
2089
2090 test_27v() { # bug 4900
2091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2093         remote_mds_nodsh && skip "remote MDS with nodsh"
2094         remote_ost_nodsh && skip "remote OST with nodsh"
2095
2096         exhaust_all_precreations 0x215
2097         reset_enospc
2098
2099         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
2100
2101         touch $DIR/$tdir/$tfile
2102         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
2103         # all except ost1
2104         for (( i=1; i < OSTCOUNT; i++ )); do
2105                 do_facet ost$i lctl set_param fail_loc=0x705
2106         done
2107         local START=`date +%s`
2108         createmany -o $DIR/$tdir/$tfile 32
2109
2110         local FINISH=`date +%s`
2111         local TIMEOUT=`lctl get_param -n timeout`
2112         local PROCESS=$((FINISH - START))
2113         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
2114                error "$FINISH - $START >= $TIMEOUT / 2"
2115         sleep $((TIMEOUT / 2 - PROCESS))
2116         reset_enospc
2117 }
2118 run_test 27v "skip object creation on slow OST"
2119
2120 test_27w() { # bug 10997
2121         test_mkdir $DIR/$tdir
2122         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
2123         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
2124                 error "stripe size $size != 65536" || true
2125         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
2126                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
2127 }
2128 run_test 27w "check $LFS setstripe -S and getstrip -d options"
2129
2130 test_27wa() {
2131         [[ $OSTCOUNT -lt 2 ]] &&
2132                 skip_env "skipping multiple stripe count/offset test"
2133
2134         test_mkdir $DIR/$tdir
2135         for i in $(seq 1 $OSTCOUNT); do
2136                 offset=$((i - 1))
2137                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
2138                         error "setstripe -c $i -i $offset failed"
2139                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
2140                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
2141                 [ $count -ne $i ] && error "stripe count $count != $i" || true
2142                 [ $index -ne $offset ] &&
2143                         error "stripe offset $index != $offset" || true
2144         done
2145 }
2146 run_test 27wa "check $LFS setstripe -c -i options"
2147
2148 test_27x() {
2149         remote_ost_nodsh && skip "remote OST with nodsh"
2150         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2152
2153         OFFSET=$(($OSTCOUNT - 1))
2154         OSTIDX=0
2155         local OST=$(ostname_from_index $OSTIDX)
2156
2157         test_mkdir $DIR/$tdir
2158         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2159         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2160         sleep_maxage
2161         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2162         for i in $(seq 0 $OFFSET); do
2163                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2164                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2165                 error "OST0 was degraded but new created file still use it"
2166         done
2167         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2168 }
2169 run_test 27x "create files while OST0 is degraded"
2170
2171 test_27y() {
2172         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2173         remote_mds_nodsh && skip "remote MDS with nodsh"
2174         remote_ost_nodsh && skip "remote OST with nodsh"
2175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2176
2177         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2178         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2179                 osp.$mdtosc.prealloc_last_id)
2180         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2181                 osp.$mdtosc.prealloc_next_id)
2182         local fcount=$((last_id - next_id))
2183         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2184         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2185
2186         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2187                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2188         local OST_DEACTIVE_IDX=-1
2189         local OSC
2190         local OSTIDX
2191         local OST
2192
2193         for OSC in $MDS_OSCS; do
2194                 OST=$(osc_to_ost $OSC)
2195                 OSTIDX=$(index_from_ostuuid $OST)
2196                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2197                         OST_DEACTIVE_IDX=$OSTIDX
2198                 fi
2199                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2200                         echo $OSC "is Deactivated:"
2201                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2202                 fi
2203         done
2204
2205         OSTIDX=$(index_from_ostuuid $OST)
2206         test_mkdir $DIR/$tdir
2207         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2208
2209         for OSC in $MDS_OSCS; do
2210                 OST=$(osc_to_ost $OSC)
2211                 OSTIDX=$(index_from_ostuuid $OST)
2212                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2213                         echo $OST "is degraded:"
2214                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2215                                                 obdfilter.$OST.degraded=1
2216                 fi
2217         done
2218
2219         sleep_maxage
2220         createmany -o $DIR/$tdir/$tfile $fcount
2221
2222         for OSC in $MDS_OSCS; do
2223                 OST=$(osc_to_ost $OSC)
2224                 OSTIDX=$(index_from_ostuuid $OST)
2225                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2226                         echo $OST "is recovered from degraded:"
2227                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2228                                                 obdfilter.$OST.degraded=0
2229                 else
2230                         do_facet $SINGLEMDS lctl --device %$OSC activate
2231                 fi
2232         done
2233
2234         # all osp devices get activated, hence -1 stripe count restored
2235         local stripe_count=0
2236
2237         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2238         # devices get activated.
2239         sleep_maxage
2240         $LFS setstripe -c -1 $DIR/$tfile
2241         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2242         rm -f $DIR/$tfile
2243         [ $stripe_count -ne $OSTCOUNT ] &&
2244                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2245         return 0
2246 }
2247 run_test 27y "create files while OST0 is degraded and the rest inactive"
2248
2249 check_seq_oid()
2250 {
2251         log "check file $1"
2252
2253         lmm_count=$($LFS getstripe -c $1)
2254         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2255         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2256
2257         local old_ifs="$IFS"
2258         IFS=$'[:]'
2259         fid=($($LFS path2fid $1))
2260         IFS="$old_ifs"
2261
2262         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2263         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2264
2265         # compare lmm_seq and lu_fid->f_seq
2266         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2267         # compare lmm_object_id and lu_fid->oid
2268         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2269
2270         # check the trusted.fid attribute of the OST objects of the file
2271         local have_obdidx=false
2272         local stripe_nr=0
2273         $LFS getstripe $1 | while read obdidx oid hex seq; do
2274                 # skip lines up to and including "obdidx"
2275                 [ -z "$obdidx" ] && break
2276                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2277                 $have_obdidx || continue
2278
2279                 local ost=$((obdidx + 1))
2280                 local dev=$(ostdevname $ost)
2281                 local oid_hex
2282
2283                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2284
2285                 seq=$(echo $seq | sed -e "s/^0x//g")
2286                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2287                         oid_hex=$(echo $oid)
2288                 else
2289                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2290                 fi
2291                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2292
2293                 local ff=""
2294                 #
2295                 # Don't unmount/remount the OSTs if we don't need to do that.
2296                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2297                 # update too, until that use mount/ll_decode_filter_fid/mount.
2298                 # Re-enable when debugfs will understand new filter_fid.
2299                 #
2300                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2301                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2302                                 $dev 2>/dev/null" | grep "parent=")
2303                 fi
2304                 if [ -z "$ff" ]; then
2305                         stop ost$ost
2306                         mount_fstype ost$ost
2307                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2308                                 $(facet_mntpt ost$ost)/$obj_file)
2309                         unmount_fstype ost$ost
2310                         start ost$ost $dev $OST_MOUNT_OPTS
2311                         clients_up
2312                 fi
2313
2314                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2315
2316                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2317
2318                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2319                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2320                 #
2321                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2322                 #       stripe_size=1048576 component_id=1 component_start=0 \
2323                 #       component_end=33554432
2324                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2325                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2326                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2327                 local ff_pstripe
2328                 if grep -q 'stripe=' <<<$ff; then
2329                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2330                 else
2331                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2332                         # into f_ver in this case.  See comment on ff_parent.
2333                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2334                 fi
2335
2336                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2337                 [ $ff_pseq = $lmm_seq ] ||
2338                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2339                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2340                 [ $ff_poid = $lmm_oid ] ||
2341                         error "FF parent OID $ff_poid != $lmm_oid"
2342                 (($ff_pstripe == $stripe_nr)) ||
2343                         error "FF stripe $ff_pstripe != $stripe_nr"
2344
2345                 stripe_nr=$((stripe_nr + 1))
2346                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2347                         continue
2348                 if grep -q 'stripe_count=' <<<$ff; then
2349                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2350                                             -e 's/ .*//' <<<$ff)
2351                         [ $lmm_count = $ff_scnt ] ||
2352                                 error "FF stripe count $lmm_count != $ff_scnt"
2353                 fi
2354         done
2355 }
2356
2357 test_27z() {
2358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2359         remote_ost_nodsh && skip "remote OST with nodsh"
2360
2361         test_mkdir $DIR/$tdir
2362         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2363                 { error "setstripe -c -1 failed"; return 1; }
2364         # We need to send a write to every object to get parent FID info set.
2365         # This _should_ also work for setattr, but does not currently.
2366         # touch $DIR/$tdir/$tfile-1 ||
2367         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2368                 { error "dd $tfile-1 failed"; return 2; }
2369         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2370                 { error "setstripe -c -1 failed"; return 3; }
2371         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2372                 { error "dd $tfile-2 failed"; return 4; }
2373
2374         # make sure write RPCs have been sent to OSTs
2375         sync; sleep 5; sync
2376
2377         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2378         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2379 }
2380 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2381
2382 test_27A() { # b=19102
2383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2384
2385         save_layout_restore_at_exit $MOUNT
2386         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2387         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2388                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2389         local default_size=$($LFS getstripe -S $MOUNT)
2390         local default_offset=$($LFS getstripe -i $MOUNT)
2391         local dsize=$(do_facet $SINGLEMDS \
2392                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2393         [ $default_size -eq $dsize ] ||
2394                 error "stripe size $default_size != $dsize"
2395         [ $default_offset -eq -1 ] ||
2396                 error "stripe offset $default_offset != -1"
2397 }
2398 run_test 27A "check filesystem-wide default LOV EA values"
2399
2400 test_27B() { # LU-2523
2401         test_mkdir $DIR/$tdir
2402         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2403         touch $DIR/$tdir/f0
2404         # open f1 with O_LOV_DELAY_CREATE
2405         # rename f0 onto f1
2406         # call setstripe ioctl on open file descriptor for f1
2407         # close
2408         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2409                 $DIR/$tdir/f0
2410
2411         rm -f $DIR/$tdir/f1
2412         # open f1 with O_LOV_DELAY_CREATE
2413         # unlink f1
2414         # call setstripe ioctl on open file descriptor for f1
2415         # close
2416         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2417
2418         # Allow multiop to fail in imitation of NFS's busted semantics.
2419         true
2420 }
2421 run_test 27B "call setstripe on open unlinked file/rename victim"
2422
2423 # 27C family tests full striping and overstriping
2424 test_27Ca() { #LU-2871
2425         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2426
2427         declare -a ost_idx
2428         local index
2429         local found
2430         local i
2431         local j
2432
2433         test_mkdir $DIR/$tdir
2434         cd $DIR/$tdir
2435         for i in $(seq 0 $((OSTCOUNT - 1))); do
2436                 # set stripe across all OSTs starting from OST$i
2437                 $LFS setstripe -i $i -c -1 $tfile$i
2438                 # get striping information
2439                 ost_idx=($($LFS getstripe $tfile$i |
2440                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2441                 echo "OST Index: ${ost_idx[*]}"
2442
2443                 # check the layout
2444                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2445                         error "${#ost_idx[@]} != $OSTCOUNT"
2446
2447                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2448                         found=0
2449                         for j in "${ost_idx[@]}"; do
2450                                 if [ $index -eq $j ]; then
2451                                         found=1
2452                                         break
2453                                 fi
2454                         done
2455                         [ $found = 1 ] ||
2456                                 error "Can not find $index in ${ost_idx[*]}"
2457                 done
2458         done
2459 }
2460 run_test 27Ca "check full striping across all OSTs"
2461
2462 test_27Cb() {
2463         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2464                 skip "server does not support overstriping"
2465         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2466                 skip_env "too many osts, skipping"
2467
2468         test_mkdir -p $DIR/$tdir
2469         local setcount=$(($OSTCOUNT * 2))
2470         [ $setcount -lt 160 ] || large_xattr_enabled ||
2471                 skip_env "ea_inode feature disabled"
2472
2473         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2474                 error "setstripe failed"
2475
2476         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2477         [ $count -eq $setcount ] ||
2478                 error "stripe count $count, should be $setcount"
2479
2480         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2481                 error "overstriped should be set in pattern"
2482
2483         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2484                 error "dd failed"
2485 }
2486 run_test 27Cb "more stripes than OSTs with -C"
2487
2488 test_27Cc() {
2489         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2490                 skip "server does not support overstriping"
2491         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2492
2493         test_mkdir -p $DIR/$tdir
2494         local setcount=$(($OSTCOUNT - 1))
2495
2496         [ $setcount -lt 160 ] || large_xattr_enabled ||
2497                 skip_env "ea_inode feature disabled"
2498
2499         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2500                 error "setstripe failed"
2501
2502         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2503         [ $count -eq $setcount ] ||
2504                 error "stripe count $count, should be $setcount"
2505
2506         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2507                 error "overstriped should not be set in pattern"
2508
2509         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2510                 error "dd failed"
2511 }
2512 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2513
2514 test_27Cd() {
2515         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2516                 skip "server does not support overstriping"
2517         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2518         large_xattr_enabled || skip_env "ea_inode feature disabled"
2519
2520         force_new_seq_all
2521
2522         test_mkdir -p $DIR/$tdir
2523         local setcount=$LOV_MAX_STRIPE_COUNT
2524
2525         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2526                 error "setstripe failed"
2527
2528         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2529         [ $count -eq $setcount ] ||
2530                 error "stripe count $count, should be $setcount"
2531
2532         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2533                 error "overstriped should be set in pattern"
2534
2535         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2536                 error "dd failed"
2537
2538         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2539 }
2540 run_test 27Cd "test maximum stripe count"
2541
2542 test_27Ce() {
2543         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2544                 skip "server does not support overstriping"
2545         test_mkdir -p $DIR/$tdir
2546
2547         pool_add $TESTNAME || error "Pool creation failed"
2548         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2549
2550         local setcount=8
2551
2552         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2553                 error "setstripe failed"
2554
2555         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2556         [ $count -eq $setcount ] ||
2557                 error "stripe count $count, should be $setcount"
2558
2559         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2560                 error "overstriped should be set in pattern"
2561
2562         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2563                 error "dd failed"
2564
2565         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2566 }
2567 run_test 27Ce "test pool with overstriping"
2568
2569 test_27Cf() {
2570         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2571                 skip "server does not support overstriping"
2572         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2573                 skip_env "too many osts, skipping"
2574
2575         test_mkdir -p $DIR/$tdir
2576
2577         local setcount=$(($OSTCOUNT * 2))
2578         [ $setcount -lt 160 ] || large_xattr_enabled ||
2579                 skip_env "ea_inode feature disabled"
2580
2581         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2582                 error "setstripe failed"
2583
2584         echo 1 > $DIR/$tdir/$tfile
2585
2586         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2587         [ $count -eq $setcount ] ||
2588                 error "stripe count $count, should be $setcount"
2589
2590         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2591                 error "overstriped should be set in pattern"
2592
2593         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2594                 error "dd failed"
2595
2596         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2597 }
2598 run_test 27Cf "test default inheritance with overstriping"
2599
2600 test_27Cg() {
2601         $LFS setstripe -o 0,$OSTCOUNT $DIR/$tfile
2602         [ $? -ne 0 ] || error "must be an error for not existent OST#"
2603 }
2604 run_test 27Cg "test setstripe with wrong OST idx"
2605
2606 test_27D() {
2607         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2608         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2609         remote_mds_nodsh && skip "remote MDS with nodsh"
2610
2611         local POOL=${POOL:-testpool}
2612         local first_ost=0
2613         local last_ost=$(($OSTCOUNT - 1))
2614         local ost_step=1
2615         local ost_list=$(seq $first_ost $ost_step $last_ost)
2616         local ost_range="$first_ost $last_ost $ost_step"
2617
2618         test_mkdir $DIR/$tdir
2619         pool_add $POOL || error "pool_add failed"
2620         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2621
2622         local skip27D
2623         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2624                 skip27D+="-s 29"
2625         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2626                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2627                         skip27D+=" -s 30,31"
2628         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2629           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2630                 skip27D+=" -s 32,33"
2631         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2632                 skip27D+=" -s 34"
2633         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2634                 error "llapi_layout_test failed"
2635
2636         destroy_test_pools || error "destroy test pools failed"
2637 }
2638 run_test 27D "validate llapi_layout API"
2639
2640 # Verify that default_easize is increased from its initial value after
2641 # accessing a widely striped file.
2642 test_27E() {
2643         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2644         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2645                 skip "client does not have LU-3338 fix"
2646
2647         # 72 bytes is the minimum space required to store striping
2648         # information for a file striped across one OST:
2649         # (sizeof(struct lov_user_md_v3) +
2650         #  sizeof(struct lov_user_ost_data_v1))
2651         local min_easize=72
2652         $LCTL set_param -n llite.*.default_easize $min_easize ||
2653                 error "lctl set_param failed"
2654         local easize=$($LCTL get_param -n llite.*.default_easize)
2655
2656         [ $easize -eq $min_easize ] ||
2657                 error "failed to set default_easize"
2658
2659         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2660                 error "setstripe failed"
2661         # In order to ensure stat() call actually talks to MDS we need to
2662         # do something drastic to this file to shake off all lock, e.g.
2663         # rename it (kills lookup lock forcing cache cleaning)
2664         mv $DIR/$tfile $DIR/${tfile}-1
2665         ls -l $DIR/${tfile}-1
2666         rm $DIR/${tfile}-1
2667
2668         easize=$($LCTL get_param -n llite.*.default_easize)
2669
2670         [ $easize -gt $min_easize ] ||
2671                 error "default_easize not updated"
2672 }
2673 run_test 27E "check that default extended attribute size properly increases"
2674
2675 test_27F() { # LU-5346/LU-7975
2676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2677         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2678         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2679                 skip "Need MDS version at least 2.8.51"
2680         remote_ost_nodsh && skip "remote OST with nodsh"
2681
2682         test_mkdir $DIR/$tdir
2683         rm -f $DIR/$tdir/f0
2684         $LFS setstripe -c 2 $DIR/$tdir
2685
2686         # stop all OSTs to reproduce situation for LU-7975 ticket
2687         for num in $(seq $OSTCOUNT); do
2688                 stop ost$num
2689         done
2690
2691         # open/create f0 with O_LOV_DELAY_CREATE
2692         # truncate f0 to a non-0 size
2693         # close
2694         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2695
2696         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2697         # open/write it again to force delayed layout creation
2698         cat /etc/hosts > $DIR/$tdir/f0 &
2699         catpid=$!
2700
2701         # restart OSTs
2702         for num in $(seq $OSTCOUNT); do
2703                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2704                         error "ost$num failed to start"
2705         done
2706
2707         wait $catpid || error "cat failed"
2708
2709         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2710         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2711                 error "wrong stripecount"
2712
2713 }
2714 run_test 27F "Client resend delayed layout creation with non-zero size"
2715
2716 test_27G() { #LU-10629
2717         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2718                 skip "Need MDS version at least 2.11.51"
2719         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2720         remote_mds_nodsh && skip "remote MDS with nodsh"
2721         local POOL=${POOL:-testpool}
2722         local ostrange="0 0 1"
2723
2724         test_mkdir $DIR/$tdir
2725         touch $DIR/$tdir/$tfile.nopool
2726         pool_add $POOL || error "pool_add failed"
2727         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2728         $LFS setstripe -p $POOL $DIR/$tdir
2729
2730         local pool=$($LFS getstripe -p $DIR/$tdir)
2731
2732         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2733         touch $DIR/$tdir/$tfile.default
2734         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2735         $LFS find $DIR/$tdir -type f --pool $POOL
2736         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2737         [[ "$found" == "2" ]] ||
2738                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2739
2740         $LFS setstripe -d $DIR/$tdir
2741
2742         pool=$($LFS getstripe -p -d $DIR/$tdir)
2743
2744         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2745 }
2746 run_test 27G "Clear OST pool from stripe"
2747
2748 test_27H() {
2749         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2750                 skip "Need MDS version newer than 2.11.54"
2751         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2752         test_mkdir $DIR/$tdir
2753         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2754         touch $DIR/$tdir/$tfile
2755         $LFS getstripe -c $DIR/$tdir/$tfile
2756         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2757                 error "two-stripe file doesn't have two stripes"
2758
2759         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2760         $LFS getstripe -y $DIR/$tdir/$tfile
2761         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2762              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2763                 error "expected l_ost_idx: [02]$ not matched"
2764
2765         # make sure ost list has been cleared
2766         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2767         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2768                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2769         touch $DIR/$tdir/f3
2770         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2771 }
2772 run_test 27H "Set specific OSTs stripe"
2773
2774 test_27I() {
2775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2776         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2777         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2778                 skip "Need MDS version newer than 2.12.52"
2779         local pool=$TESTNAME
2780         local ostrange="1 1 1"
2781
2782         save_layout_restore_at_exit $MOUNT
2783         $LFS setstripe -c 2 -i 0 $MOUNT
2784         pool_add $pool || error "pool_add failed"
2785         pool_add_targets $pool $ostrange ||
2786                 error "pool_add_targets failed"
2787         test_mkdir $DIR/$tdir
2788         $LFS setstripe -p $pool $DIR/$tdir
2789         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2790         $LFS getstripe $DIR/$tdir/$tfile
2791 }
2792 run_test 27I "check that root dir striping does not break parent dir one"
2793
2794 test_27J() {
2795         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2796                 skip "Need MDS version newer than 2.12.51"
2797
2798         test_mkdir $DIR/$tdir
2799         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2800         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2801
2802         # create foreign file (raw way)
2803         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2804                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2805
2806         ! $LFS setstripe --foreign --flags foo \
2807                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2808                         error "creating $tfile with '--flags foo' should fail"
2809
2810         ! $LFS setstripe --foreign --flags 0xffffffff \
2811                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2812                         error "creating $tfile w/ 0xffffffff flags should fail"
2813
2814         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2815                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2816
2817         # verify foreign file (raw way)
2818         parse_foreign_file -f $DIR/$tdir/$tfile |
2819                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2820                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2821         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2822                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2823         parse_foreign_file -f $DIR/$tdir/$tfile |
2824                 grep "lov_foreign_size: 73" ||
2825                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2826         parse_foreign_file -f $DIR/$tdir/$tfile |
2827                 grep "lov_foreign_type: 1" ||
2828                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2829         parse_foreign_file -f $DIR/$tdir/$tfile |
2830                 grep "lov_foreign_flags: 0x0000DA08" ||
2831                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2832         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2833                 grep "lov_foreign_value: 0x" |
2834                 sed -e 's/lov_foreign_value: 0x//')
2835         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2836         [[ $lov = ${lov2// /} ]] ||
2837                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2838
2839         # create foreign file (lfs + API)
2840         $LFS setstripe --foreign=none --flags 0xda08 \
2841                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2842                 error "$DIR/$tdir/${tfile}2: create failed"
2843
2844         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2845                 grep "lfm_magic:.*0x0BD70BD0" ||
2846                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2847         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2848         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2849                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2850         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2851                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2852         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2853                 grep "lfm_flags:.*0x0000DA08" ||
2854                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2855         $LFS getstripe $DIR/$tdir/${tfile}2 |
2856                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2857                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2858
2859         # modify striping should fail
2860         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2861                 error "$DIR/$tdir/$tfile: setstripe should fail"
2862         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2863                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2864
2865         # R/W should fail
2866         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2867         cat $DIR/$tdir/${tfile}2 &&
2868                 error "$DIR/$tdir/${tfile}2: read should fail"
2869         cat /etc/passwd > $DIR/$tdir/$tfile &&
2870                 error "$DIR/$tdir/$tfile: write should fail"
2871         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2872                 error "$DIR/$tdir/${tfile}2: write should fail"
2873
2874         # chmod should work
2875         chmod 222 $DIR/$tdir/$tfile ||
2876                 error "$DIR/$tdir/$tfile: chmod failed"
2877         chmod 222 $DIR/$tdir/${tfile}2 ||
2878                 error "$DIR/$tdir/${tfile}2: chmod failed"
2879
2880         # chown should work
2881         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2882                 error "$DIR/$tdir/$tfile: chown failed"
2883         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2884                 error "$DIR/$tdir/${tfile}2: chown failed"
2885
2886         # rename should work
2887         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2888                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2889         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2890                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2891
2892         #remove foreign file
2893         rm $DIR/$tdir/${tfile}.new ||
2894                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2895         rm $DIR/$tdir/${tfile}2.new ||
2896                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2897 }
2898 run_test 27J "basic ops on file with foreign LOV"
2899
2900 test_27K() {
2901         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2902                 skip "Need MDS version newer than 2.12.49"
2903
2904         test_mkdir $DIR/$tdir
2905         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2906         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2907
2908         # create foreign dir (raw way)
2909         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2910                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2911
2912         ! $LFS setdirstripe --foreign --flags foo \
2913                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2914                         error "creating $tdir with '--flags foo' should fail"
2915
2916         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2917                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2918                         error "creating $tdir w/ 0xffffffff flags should fail"
2919
2920         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2921                 error "create_foreign_dir FAILED"
2922
2923         # verify foreign dir (raw way)
2924         parse_foreign_dir -d $DIR/$tdir/$tdir |
2925                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2926                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2927         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2928                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2929         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2930                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2931         parse_foreign_dir -d $DIR/$tdir/$tdir |
2932                 grep "lmv_foreign_flags: 55813$" ||
2933                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2934         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2935                 grep "lmv_foreign_value: 0x" |
2936                 sed 's/lmv_foreign_value: 0x//')
2937         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2938                 sed 's/ //g')
2939         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2940
2941         # create foreign dir (lfs + API)
2942         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2943                 $DIR/$tdir/${tdir}2 ||
2944                 error "$DIR/$tdir/${tdir}2: create failed"
2945
2946         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2947
2948         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2949                 grep "lfm_magic:.*0x0CD50CD0" ||
2950                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2951         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2952         # - sizeof(lfm_type) - sizeof(lfm_flags)
2953         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2954                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2955         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2956                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2957         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2958                 grep "lfm_flags:.*0x0000DA05" ||
2959                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2960         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2961                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2962                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2963
2964         # file create in dir should fail
2965         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2966         touch $DIR/$tdir/${tdir}2/$tfile &&
2967                 error "$DIR/${tdir}2: file create should fail"
2968
2969         # chmod should work
2970         chmod 777 $DIR/$tdir/$tdir ||
2971                 error "$DIR/$tdir: chmod failed"
2972         chmod 777 $DIR/$tdir/${tdir}2 ||
2973                 error "$DIR/${tdir}2: chmod failed"
2974
2975         # chown should work
2976         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2977                 error "$DIR/$tdir: chown failed"
2978         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2979                 error "$DIR/${tdir}2: chown failed"
2980
2981         # rename should work
2982         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2983                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2984         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2985                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2986
2987         #remove foreign dir
2988         rmdir $DIR/$tdir/${tdir}.new ||
2989                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2990         rmdir $DIR/$tdir/${tdir}2.new ||
2991                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2992 }
2993 run_test 27K "basic ops on dir with foreign LMV"
2994
2995 test_27L() {
2996         remote_mds_nodsh && skip "remote MDS with nodsh"
2997
2998         local POOL=${POOL:-$TESTNAME}
2999
3000         pool_add $POOL || error "pool_add failed"
3001
3002         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
3003                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
3004                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
3005 }
3006 run_test 27L "lfs pool_list gives correct pool name"
3007
3008 test_27M() {
3009         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3010                 skip "Need MDS version >= than 2.12.57"
3011         remote_mds_nodsh && skip "remote MDS with nodsh"
3012         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3013
3014         # Set default striping on directory
3015         local setcount=4
3016         local stripe_opt
3017         local mdts=$(comma_list $(mdts_nodes))
3018
3019         # if we run against a 2.12 server which lacks overstring support
3020         # then the connect_flag will not report overstriping, even if client
3021         # is 2.14+
3022         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3023                 stripe_opt="-C $setcount"
3024         elif (( $OSTCOUNT >= $setcount )); then
3025                 stripe_opt="-c $setcount"
3026         else
3027                 skip "server does not support overstriping"
3028         fi
3029
3030         test_mkdir $DIR/$tdir
3031
3032         # Validate existing append_* params and ensure restore
3033         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3034         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3035         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3036
3037         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3038         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3039         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3040
3041         $LFS setstripe $stripe_opt $DIR/$tdir
3042
3043         echo 1 > $DIR/$tdir/${tfile}.1
3044         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3045         [ $count -eq $setcount ] ||
3046                 error "(1) stripe count $count, should be $setcount"
3047
3048         local appendcount=$orig_count
3049         echo 1 >> $DIR/$tdir/${tfile}.2_append
3050         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3051         [ $count -eq $appendcount ] ||
3052                 error "(2)stripe count $count, should be $appendcount for append"
3053
3054         # Disable O_APPEND striping, verify it works
3055         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3056
3057         # Should now get the default striping, which is 4
3058         setcount=4
3059         echo 1 >> $DIR/$tdir/${tfile}.3_append
3060         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3061         [ $count -eq $setcount ] ||
3062                 error "(3) stripe count $count, should be $setcount"
3063
3064         # Try changing the stripe count for append files
3065         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3066
3067         # Append striping is now 2 (directory default is still 4)
3068         appendcount=2
3069         echo 1 >> $DIR/$tdir/${tfile}.4_append
3070         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3071         [ $count -eq $appendcount ] ||
3072                 error "(4) stripe count $count, should be $appendcount for append"
3073
3074         # Test append stripe count of -1
3075         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3076         appendcount=$OSTCOUNT
3077         echo 1 >> $DIR/$tdir/${tfile}.5
3078         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3079         [ $count -eq $appendcount ] ||
3080                 error "(5) stripe count $count, should be $appendcount for append"
3081
3082         # Set append striping back to default of 1
3083         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3084
3085         # Try a new default striping, PFL + DOM
3086         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3087
3088         # Create normal DOM file, DOM returns stripe count == 0
3089         setcount=0
3090         touch $DIR/$tdir/${tfile}.6
3091         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3092         [ $count -eq $setcount ] ||
3093                 error "(6) stripe count $count, should be $setcount"
3094
3095         # Show
3096         appendcount=1
3097         echo 1 >> $DIR/$tdir/${tfile}.7_append
3098         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3099         [ $count -eq $appendcount ] ||
3100                 error "(7) stripe count $count, should be $appendcount for append"
3101
3102         # Clean up DOM layout
3103         $LFS setstripe -d $DIR/$tdir
3104
3105         save_layout_restore_at_exit $MOUNT
3106         # Now test that append striping works when layout is from root
3107         $LFS setstripe -c 2 $MOUNT
3108         # Make a special directory for this
3109         mkdir $DIR/${tdir}/${tdir}.2
3110
3111         # Verify for normal file
3112         setcount=2
3113         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3114         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3115         [ $count -eq $setcount ] ||
3116                 error "(8) stripe count $count, should be $setcount"
3117
3118         appendcount=1
3119         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3120         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3121         [ $count -eq $appendcount ] ||
3122                 error "(9) stripe count $count, should be $appendcount for append"
3123
3124         # Now test O_APPEND striping with pools
3125         pool_add $TESTNAME || error "pool creation failed"
3126         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3127         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3128
3129         echo 1 >> $DIR/$tdir/${tfile}.10_append
3130
3131         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3132         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3133
3134         # Check that count is still correct
3135         appendcount=1
3136         echo 1 >> $DIR/$tdir/${tfile}.11_append
3137         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3138         [ $count -eq $appendcount ] ||
3139                 error "(11) stripe count $count, should be $appendcount for append"
3140
3141         # Disable O_APPEND stripe count, verify pool works separately
3142         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3143
3144         echo 1 >> $DIR/$tdir/${tfile}.12_append
3145
3146         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3147         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3148
3149         # Remove pool setting, verify it's not applied
3150         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3151
3152         echo 1 >> $DIR/$tdir/${tfile}.13_append
3153
3154         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3155         [ "$pool" = "" ] || error "(13) pool found: $pool"
3156 }
3157 run_test 27M "test O_APPEND striping"
3158
3159 test_27N() {
3160         combined_mgs_mds && skip "needs separate MGS/MDT"
3161
3162         pool_add $TESTNAME || error "pool_add failed"
3163         do_facet mgs "$LCTL pool_list $FSNAME" |
3164                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3165                 error "lctl pool_list on MGS failed"
3166 }
3167 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3168
3169 clean_foreign_symlink() {
3170         trap 0
3171         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3172         for i in $DIR/$tdir/* ; do
3173                 $LFS unlink_foreign $i || true
3174         done
3175 }
3176
3177 test_27O() {
3178         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3179                 skip "Need MDS version newer than 2.12.51"
3180
3181         test_mkdir $DIR/$tdir
3182         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3183         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3184
3185         trap clean_foreign_symlink EXIT
3186
3187         # enable foreign_symlink behaviour
3188         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3189
3190         # foreign symlink LOV format is a partial path by default
3191
3192         # create foreign file (lfs + API)
3193         $LFS setstripe --foreign=symlink --flags 0xda05 \
3194                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3195                 error "$DIR/$tdir/${tfile}: create failed"
3196
3197         $LFS getstripe -v $DIR/$tdir/${tfile} |
3198                 grep "lfm_magic:.*0x0BD70BD0" ||
3199                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3200         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3201                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3202         $LFS getstripe -v $DIR/$tdir/${tfile} |
3203                 grep "lfm_flags:.*0x0000DA05" ||
3204                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3205         $LFS getstripe $DIR/$tdir/${tfile} |
3206                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3207                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3208
3209         # modify striping should fail
3210         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3211                 error "$DIR/$tdir/$tfile: setstripe should fail"
3212
3213         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3214         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3215         cat /etc/passwd > $DIR/$tdir/$tfile &&
3216                 error "$DIR/$tdir/$tfile: write should fail"
3217
3218         # rename should succeed
3219         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3220                 error "$DIR/$tdir/$tfile: rename has failed"
3221
3222         #remove foreign_symlink file should fail
3223         rm $DIR/$tdir/${tfile}.new &&
3224                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3225
3226         #test fake symlink
3227         mkdir /tmp/${uuid1} ||
3228                 error "/tmp/${uuid1}: mkdir has failed"
3229         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3230                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3231         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3232         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3233                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3234         #read should succeed now
3235         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3236                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3237         #write should succeed now
3238         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3239                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3240         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3241                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3242         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3243                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3244
3245         #check that getstripe still works
3246         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3247                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3248
3249         # chmod should still succeed
3250         chmod 644 $DIR/$tdir/${tfile}.new ||
3251                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3252
3253         # chown should still succeed
3254         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3255                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3256
3257         # rename should still succeed
3258         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3259                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3260
3261         #remove foreign_symlink file should still fail
3262         rm $DIR/$tdir/${tfile} &&
3263                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3264
3265         #use special ioctl() to unlink foreign_symlink file
3266         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3267                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3268
3269 }
3270 run_test 27O "basic ops on foreign file of symlink type"
3271
3272 test_27P() {
3273         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3274                 skip "Need MDS version newer than 2.12.49"
3275
3276         test_mkdir $DIR/$tdir
3277         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3278         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3279
3280         trap clean_foreign_symlink EXIT
3281
3282         # enable foreign_symlink behaviour
3283         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3284
3285         # foreign symlink LMV format is a partial path by default
3286
3287         # create foreign dir (lfs + API)
3288         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3289                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3290                 error "$DIR/$tdir/${tdir}: create failed"
3291
3292         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3293
3294         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3295                 grep "lfm_magic:.*0x0CD50CD0" ||
3296                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3297         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3298                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3299         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3300                 grep "lfm_flags:.*0x0000DA05" ||
3301                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3302         $LFS getdirstripe $DIR/$tdir/${tdir} |
3303                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3304                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3305
3306         # file create in dir should fail
3307         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3308         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3309
3310         # rename should succeed
3311         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3312                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3313
3314         #remove foreign_symlink dir should fail
3315         rmdir $DIR/$tdir/${tdir}.new &&
3316                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3317
3318         #test fake symlink
3319         mkdir -p /tmp/${uuid1}/${uuid2} ||
3320                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3321         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3322                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3323         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3324         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3325                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3326         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3327                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3328
3329         #check that getstripe fails now that foreign_symlink enabled
3330         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3331                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3332
3333         # file create in dir should work now
3334         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3335                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3336         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3337                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3338         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3339                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3340
3341         # chmod should still succeed
3342         chmod 755 $DIR/$tdir/${tdir}.new ||
3343                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3344
3345         # chown should still succeed
3346         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3347                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3348
3349         # rename should still succeed
3350         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3351                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3352
3353         #remove foreign_symlink dir should still fail
3354         rmdir $DIR/$tdir/${tdir} &&
3355                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3356
3357         #use special ioctl() to unlink foreign_symlink file
3358         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3359                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3360
3361         #created file should still exist
3362         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3363                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3364         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3365                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3366 }
3367 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3368
3369 test_27Q() {
3370         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3371         stack_trap "rm -f $TMP/$tfile*"
3372
3373         test_mkdir $DIR/$tdir-1
3374         test_mkdir $DIR/$tdir-2
3375
3376         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3377         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3378
3379         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3380         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3381
3382         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3383         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3384
3385         # Create some bad symlinks and ensure that we don't loop
3386         # forever or something. These should return ELOOP (40) and
3387         # ENOENT (2) but I don't want to test for that because there's
3388         # always some weirdo architecture that needs to ruin
3389         # everything by defining these error numbers differently.
3390
3391         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3392         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3393
3394         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3395         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3396
3397         return 0
3398 }
3399 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3400
3401 test_27R() {
3402         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3403                 skip "need MDS 2.14.55 or later"
3404         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3405
3406         local testdir="$DIR/$tdir"
3407         test_mkdir -p $testdir
3408         stack_trap "rm -rf $testdir"
3409         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3410
3411         local f1="$testdir/f1"
3412         touch $f1 || error "failed to touch $f1"
3413         local count=$($LFS getstripe -c $f1)
3414         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3415
3416         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3417         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3418
3419         local maxcount=$(($OSTCOUNT - 1))
3420         local mdts=$(comma_list $(mdts_nodes))
3421         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3422         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3423
3424         local f2="$testdir/f2"
3425         touch $f2 || error "failed to touch $f2"
3426         local count=$($LFS getstripe -c $f2)
3427         (( $count == $maxcount )) || error "wrong stripe count"
3428 }
3429 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3430
3431 test_27T() {
3432         [ $(facet_host client) == $(facet_host ost1) ] &&
3433                 skip "need ost1 and client on different nodes"
3434
3435 #define OBD_FAIL_OSC_NO_GRANT            0x411
3436         $LCTL set_param fail_loc=0x20000411 fail_val=1
3437 #define OBD_FAIL_OST_ENOSPC              0x215
3438         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3439         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3440         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3441                 error "multiop failed"
3442 }
3443 run_test 27T "no eio on close on partial write due to enosp"
3444
3445 test_27U() {
3446         local dir=$DIR/$tdir
3447         local file=$dir/$tfile
3448         local append_pool=${TESTNAME}-append
3449         local normal_pool=${TESTNAME}-normal
3450         local pool
3451         local stripe_count
3452         local stripe_count2
3453         local mdts=$(comma_list $(mdts_nodes))
3454
3455         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3456                 skip "Need MDS version at least 2.15.51 for append pool feature"
3457
3458         # Validate existing append_* params and ensure restore
3459         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3460         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3461         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3462
3463         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3464         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3465         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3466
3467         pool_add $append_pool || error "pool creation failed"
3468         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3469
3470         pool_add $normal_pool || error "pool creation failed"
3471         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3472
3473         test_mkdir $dir
3474         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3475
3476         echo XXX >> $file.1
3477         $LFS getstripe $file.1
3478
3479         pool=$($LFS getstripe -p $file.1)
3480         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3481
3482         stripe_count2=$($LFS getstripe -c $file.1)
3483         ((stripe_count2 == stripe_count)) ||
3484                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3485
3486         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3487
3488         echo XXX >> $file.2
3489         $LFS getstripe $file.2
3490
3491         pool=$($LFS getstripe -p $file.2)
3492         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3493
3494         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3495
3496         echo XXX >> $file.3
3497         $LFS getstripe $file.3
3498
3499         stripe_count2=$($LFS getstripe -c $file.3)
3500         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3501 }
3502 run_test 27U "append pool and stripe count work with composite default layout"
3503
3504 # createtest also checks that device nodes are created and
3505 # then visible correctly (#2091)
3506 test_28() { # bug 2091
3507         test_mkdir $DIR/d28
3508         $CREATETEST $DIR/d28/ct || error "createtest failed"
3509 }
3510 run_test 28 "create/mknod/mkdir with bad file types ============"
3511
3512 test_29() {
3513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3514
3515         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3516                 disable_opencache
3517                 stack_trap "restore_opencache"
3518         }
3519
3520         sync; sleep 1; sync # flush out any dirty pages from previous tests
3521         cancel_lru_locks
3522         test_mkdir $DIR/d29
3523         touch $DIR/d29/foo
3524         log 'first d29'
3525         ls -l $DIR/d29
3526
3527         declare -i LOCKCOUNTORIG=0
3528         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3529                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3530         done
3531         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3532
3533         declare -i LOCKUNUSEDCOUNTORIG=0
3534         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3535                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3536         done
3537
3538         log 'second d29'
3539         ls -l $DIR/d29
3540         log 'done'
3541
3542         declare -i LOCKCOUNTCURRENT=0
3543         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3544                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3545         done
3546
3547         declare -i LOCKUNUSEDCOUNTCURRENT=0
3548         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3549                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3550         done
3551
3552         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3553                 $LCTL set_param -n ldlm.dump_namespaces ""
3554                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3555                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3556                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3557                 return 2
3558         fi
3559         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3560                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3561                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3562                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3563                 return 3
3564         fi
3565 }
3566 run_test 29 "IT_GETATTR regression  ============================"
3567
3568 test_30a() { # was test_30
3569         cp $(which ls) $DIR || cp /bin/ls $DIR
3570         $DIR/ls / || error "Can't execute binary from lustre"
3571         rm $DIR/ls
3572 }
3573 run_test 30a "execute binary from Lustre (execve) =============="
3574
3575 test_30b() {
3576         cp `which ls` $DIR || cp /bin/ls $DIR
3577         chmod go+rx $DIR/ls
3578         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3579         rm $DIR/ls
3580 }
3581 run_test 30b "execute binary from Lustre as non-root ==========="
3582
3583 test_30c() { # b=22376
3584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3585
3586         cp $(which ls) $DIR || cp /bin/ls $DIR
3587         chmod a-rw $DIR/ls
3588         cancel_lru_locks mdc
3589         cancel_lru_locks osc
3590         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3591         rm -f $DIR/ls
3592 }
3593 run_test 30c "execute binary from Lustre without read perms ===="
3594
3595 test_30d() {
3596         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3597
3598         for i in {1..10}; do
3599                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3600                 local PID=$!
3601                 sleep 1
3602                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3603                 wait $PID || error "executing dd from Lustre failed"
3604                 rm -f $DIR/$tfile
3605         done
3606
3607         rm -f $DIR/dd
3608 }
3609 run_test 30d "execute binary from Lustre while clear locks"
3610
3611 test_31a() {
3612         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3613         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3614 }
3615 run_test 31a "open-unlink file =================================="
3616
3617 test_31b() {
3618         touch $DIR/f31 || error "touch $DIR/f31 failed"
3619         ln $DIR/f31 $DIR/f31b || error "ln failed"
3620         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3621         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3622 }
3623 run_test 31b "unlink file with multiple links while open ======="
3624
3625 test_31c() {
3626         touch $DIR/f31 || error "touch $DIR/f31 failed"
3627         ln $DIR/f31 $DIR/f31c || error "ln failed"
3628         multiop_bg_pause $DIR/f31 O_uc ||
3629                 error "multiop_bg_pause for $DIR/f31 failed"
3630         MULTIPID=$!
3631         $MULTIOP $DIR/f31c Ouc
3632         kill -USR1 $MULTIPID
3633         wait $MULTIPID
3634 }
3635 run_test 31c "open-unlink file with multiple links ============="
3636
3637 test_31d() {
3638         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3639         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3640 }
3641 run_test 31d "remove of open directory ========================="
3642
3643 test_31e() { # bug 2904
3644         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3645 }
3646 run_test 31e "remove of open non-empty directory ==============="
3647
3648 test_31f() { # bug 4554
3649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3650
3651         set -vx
3652         test_mkdir $DIR/d31f
3653         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3654         cp /etc/hosts $DIR/d31f
3655         ls -l $DIR/d31f
3656         $LFS getstripe $DIR/d31f/hosts
3657         multiop_bg_pause $DIR/d31f D_c || return 1
3658         MULTIPID=$!
3659
3660         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3661         test_mkdir $DIR/d31f
3662         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3663         cp /etc/hosts $DIR/d31f
3664         ls -l $DIR/d31f
3665         $LFS getstripe $DIR/d31f/hosts
3666         multiop_bg_pause $DIR/d31f D_c || return 1
3667         MULTIPID2=$!
3668
3669         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3670         wait $MULTIPID || error "first opendir $MULTIPID failed"
3671
3672         sleep 6
3673
3674         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3675         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3676         set +vx
3677 }
3678 run_test 31f "remove of open directory with open-unlink file ==="
3679
3680 test_31g() {
3681         echo "-- cross directory link --"
3682         test_mkdir -c1 $DIR/${tdir}ga
3683         test_mkdir -c1 $DIR/${tdir}gb
3684         touch $DIR/${tdir}ga/f
3685         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3686         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3687         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3688         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3689         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3690 }
3691 run_test 31g "cross directory link==============="
3692
3693 test_31h() {
3694         echo "-- cross directory link --"
3695         test_mkdir -c1 $DIR/${tdir}
3696         test_mkdir -c1 $DIR/${tdir}/dir
3697         touch $DIR/${tdir}/f
3698         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3699         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3700         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3701         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3702         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3703 }
3704 run_test 31h "cross directory link under child==============="
3705
3706 test_31i() {
3707         echo "-- cross directory link --"
3708         test_mkdir -c1 $DIR/$tdir
3709         test_mkdir -c1 $DIR/$tdir/dir
3710         touch $DIR/$tdir/dir/f
3711         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3712         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3713         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3714         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3715         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3716 }
3717 run_test 31i "cross directory link under parent==============="
3718
3719 test_31j() {
3720         test_mkdir -c1 -p $DIR/$tdir
3721         test_mkdir -c1 -p $DIR/$tdir/dir1
3722         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3723         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3724         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3725         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3726         return 0
3727 }
3728 run_test 31j "link for directory==============="
3729
3730 test_31k() {
3731         test_mkdir -c1 -p $DIR/$tdir
3732         touch $DIR/$tdir/s
3733         touch $DIR/$tdir/exist
3734         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3735         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3736         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3737         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3738         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3739         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3740         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3741         return 0
3742 }
3743 run_test 31k "link to file: the same, non-existing, dir==============="
3744
3745 test_31l() {
3746         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3747
3748         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3749         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3750                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3751
3752         touch $DIR/$tfile || error "create failed"
3753         mkdir $DIR/$tdir || error "mkdir failed"
3754         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3755 }
3756 run_test 31l "link to file: target dir has trailing slash"
3757
3758 test_31m() {
3759         mkdir $DIR/d31m
3760         touch $DIR/d31m/s
3761         mkdir $DIR/d31m2
3762         touch $DIR/d31m2/exist
3763         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3764         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3765         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3766         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3767         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3768         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3769         return 0
3770 }
3771 run_test 31m "link to file: the same, non-existing, dir==============="
3772
3773 test_31n() {
3774         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3775         nlink=$(stat --format=%h $DIR/$tfile)
3776         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3777         local fd=$(free_fd)
3778         local cmd="exec $fd<$DIR/$tfile"
3779         eval $cmd
3780         cmd="exec $fd<&-"
3781         trap "eval $cmd" EXIT
3782         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3783         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3784         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3785         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3786         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3787         eval $cmd
3788 }
3789 run_test 31n "check link count of unlinked file"
3790
3791 link_one() {
3792         local tempfile=$(mktemp $1_XXXXXX)
3793         mlink $tempfile $1 2> /dev/null &&
3794                 echo "$BASHPID: link $tempfile to $1 succeeded"
3795         munlink $tempfile
3796 }
3797
3798 test_31o() { # LU-2901
3799         test_mkdir $DIR/$tdir
3800         for LOOP in $(seq 100); do
3801                 rm -f $DIR/$tdir/$tfile*
3802                 for THREAD in $(seq 8); do
3803                         link_one $DIR/$tdir/$tfile.$LOOP &
3804                 done
3805                 wait
3806                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3807                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3808                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3809                         break || true
3810         done
3811 }
3812 run_test 31o "duplicate hard links with same filename"
3813
3814 test_31p() {
3815         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3816
3817         test_mkdir $DIR/$tdir
3818         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3819         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3820
3821         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3822                 error "open unlink test1 failed"
3823         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3824                 error "open unlink test2 failed"
3825
3826         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3827                 error "test1 still exists"
3828         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3829                 error "test2 still exists"
3830 }
3831 run_test 31p "remove of open striped directory"
3832
3833 test_31q() {
3834         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3835
3836         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3837         index=$($LFS getdirstripe -i $DIR/$tdir)
3838         [ $index -eq 3 ] || error "first stripe index $index != 3"
3839         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3840         [ $index -eq 1 ] || error "second stripe index $index != 1"
3841
3842         # when "-c <stripe_count>" is set, the number of MDTs specified after
3843         # "-i" should equal to the stripe count
3844         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3845 }
3846 run_test 31q "create striped directory on specific MDTs"
3847
3848 #LU-14949
3849 test_31r() {
3850         touch $DIR/$tfile.target
3851         touch $DIR/$tfile.source
3852
3853         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3854         $LCTL set_param fail_loc=0x1419 fail_val=3
3855         cat $DIR/$tfile.target &
3856         CATPID=$!
3857
3858         # Guarantee open is waiting before we get here
3859         sleep 1
3860         mv $DIR/$tfile.source $DIR/$tfile.target
3861
3862         wait $CATPID
3863         RC=$?
3864         if [[ $RC -ne 0 ]]; then
3865                 error "open with cat failed, rc=$RC"
3866         fi
3867 }
3868 run_test 31r "open-rename(replace) race"
3869
3870 cleanup_test32_mount() {
3871         local rc=0
3872         trap 0
3873         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3874         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3875         losetup -d $loopdev || true
3876         rm -rf $DIR/$tdir
3877         return $rc
3878 }
3879
3880 test_32a() {
3881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3882
3883         echo "== more mountpoints and symlinks ================="
3884         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3885         trap cleanup_test32_mount EXIT
3886         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3887         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3888                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3889         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3890                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3891         cleanup_test32_mount
3892 }
3893 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3894
3895 test_32b() {
3896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3897
3898         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3899         trap cleanup_test32_mount EXIT
3900         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3901         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3902                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3903         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3904                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3905         cleanup_test32_mount
3906 }
3907 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3908
3909 test_32c() {
3910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3911
3912         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3913         trap cleanup_test32_mount EXIT
3914         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3915         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3916                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3917         test_mkdir -p $DIR/$tdir/d2/test_dir
3918         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3919                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3920         cleanup_test32_mount
3921 }
3922 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3923
3924 test_32d() {
3925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3926
3927         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3928         trap cleanup_test32_mount EXIT
3929         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3930         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3931                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3932         test_mkdir -p $DIR/$tdir/d2/test_dir
3933         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3934                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3935         cleanup_test32_mount
3936 }
3937 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3938
3939 test_32e() {
3940         rm -fr $DIR/$tdir
3941         test_mkdir -p $DIR/$tdir/tmp
3942         local tmp_dir=$DIR/$tdir/tmp
3943         ln -s $DIR/$tdir $tmp_dir/symlink11
3944         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3945         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3946         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3947 }
3948 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3949
3950 test_32f() {
3951         rm -fr $DIR/$tdir
3952         test_mkdir -p $DIR/$tdir/tmp
3953         local tmp_dir=$DIR/$tdir/tmp
3954         ln -s $DIR/$tdir $tmp_dir/symlink11
3955         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3956         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3957         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3958 }
3959 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3960
3961 test_32g() {
3962         local tmp_dir=$DIR/$tdir/tmp
3963         test_mkdir -p $tmp_dir
3964         test_mkdir $DIR/${tdir}2
3965         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3966         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3967         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3968         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3969         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3970         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3971 }
3972 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3973
3974 test_32h() {
3975         rm -fr $DIR/$tdir $DIR/${tdir}2
3976         tmp_dir=$DIR/$tdir/tmp
3977         test_mkdir -p $tmp_dir
3978         test_mkdir $DIR/${tdir}2
3979         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3980         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3981         ls $tmp_dir/symlink12 || error "listing symlink12"
3982         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3983 }
3984 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3985
3986 test_32i() {
3987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3988
3989         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3990         trap cleanup_test32_mount EXIT
3991         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3992         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3993                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3994         touch $DIR/$tdir/test_file
3995         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3996                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3997         cleanup_test32_mount
3998 }
3999 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
4000
4001 test_32j() {
4002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4003
4004         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4005         trap cleanup_test32_mount EXIT
4006         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4007         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4008                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4009         touch $DIR/$tdir/test_file
4010         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4011                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4012         cleanup_test32_mount
4013 }
4014 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4015
4016 test_32k() {
4017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4018
4019         rm -fr $DIR/$tdir
4020         trap cleanup_test32_mount EXIT
4021         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4022         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4023                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4024         test_mkdir -p $DIR/$tdir/d2
4025         touch $DIR/$tdir/d2/test_file || error "touch failed"
4026         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4027                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4028         cleanup_test32_mount
4029 }
4030 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4031
4032 test_32l() {
4033         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4034
4035         rm -fr $DIR/$tdir
4036         trap cleanup_test32_mount EXIT
4037         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4038         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4039                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4040         test_mkdir -p $DIR/$tdir/d2
4041         touch $DIR/$tdir/d2/test_file || error "touch failed"
4042         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4043                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4044         cleanup_test32_mount
4045 }
4046 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4047
4048 test_32m() {
4049         rm -fr $DIR/d32m
4050         test_mkdir -p $DIR/d32m/tmp
4051         TMP_DIR=$DIR/d32m/tmp
4052         ln -s $DIR $TMP_DIR/symlink11
4053         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4054         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4055                 error "symlink11 not a link"
4056         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4057                 error "symlink01 not a link"
4058 }
4059 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4060
4061 test_32n() {
4062         rm -fr $DIR/d32n
4063         test_mkdir -p $DIR/d32n/tmp
4064         TMP_DIR=$DIR/d32n/tmp
4065         ln -s $DIR $TMP_DIR/symlink11
4066         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4067         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4068         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4069 }
4070 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4071
4072 test_32o() {
4073         touch $DIR/$tfile
4074         test_mkdir -p $DIR/d32o/tmp
4075         TMP_DIR=$DIR/d32o/tmp
4076         ln -s $DIR/$tfile $TMP_DIR/symlink12
4077         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4078         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4079                 error "symlink12 not a link"
4080         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4081         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4082                 error "$DIR/d32o/tmp/symlink12 not file type"
4083         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4084                 error "$DIR/d32o/symlink02 not file type"
4085 }
4086 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4087
4088 test_32p() {
4089         log 32p_1
4090         rm -fr $DIR/d32p
4091         log 32p_2
4092         rm -f $DIR/$tfile
4093         log 32p_3
4094         touch $DIR/$tfile
4095         log 32p_4
4096         test_mkdir -p $DIR/d32p/tmp
4097         log 32p_5
4098         TMP_DIR=$DIR/d32p/tmp
4099         log 32p_6
4100         ln -s $DIR/$tfile $TMP_DIR/symlink12
4101         log 32p_7
4102         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4103         log 32p_8
4104         cat $DIR/d32p/tmp/symlink12 ||
4105                 error "Can't open $DIR/d32p/tmp/symlink12"
4106         log 32p_9
4107         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4108         log 32p_10
4109 }
4110 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4111
4112 test_32q() {
4113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4114
4115         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4116         trap cleanup_test32_mount EXIT
4117         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4118         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4119         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4120                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4121         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4122         cleanup_test32_mount
4123 }
4124 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4125
4126 test_32r() {
4127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4128
4129         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4130         trap cleanup_test32_mount EXIT
4131         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4132         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4133         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4134                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4135         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4136         cleanup_test32_mount
4137 }
4138 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4139
4140 test_33aa() {
4141         rm -f $DIR/$tfile
4142         touch $DIR/$tfile
4143         chmod 444 $DIR/$tfile
4144         chown $RUNAS_ID $DIR/$tfile
4145         log 33_1
4146         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4147         log 33_2
4148 }
4149 run_test 33aa "write file with mode 444 (should return error)"
4150
4151 test_33a() {
4152         rm -fr $DIR/$tdir
4153         test_mkdir $DIR/$tdir
4154         chown $RUNAS_ID $DIR/$tdir
4155         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4156                 error "$RUNAS create $tdir/$tfile failed"
4157         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4158                 error "open RDWR" || true
4159 }
4160 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4161
4162 test_33b() {
4163         rm -fr $DIR/$tdir
4164         test_mkdir $DIR/$tdir
4165         chown $RUNAS_ID $DIR/$tdir
4166         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4167 }
4168 run_test 33b "test open file with malformed flags (No panic)"
4169
4170 test_33c() {
4171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4172         remote_ost_nodsh && skip "remote OST with nodsh"
4173
4174         local ostnum
4175         local ostname
4176         local write_bytes
4177         local all_zeros
4178
4179         all_zeros=true
4180         test_mkdir $DIR/$tdir
4181         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4182
4183         sync
4184         for ostnum in $(seq $OSTCOUNT); do
4185                 # test-framework's OST numbering is one-based, while Lustre's
4186                 # is zero-based
4187                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4188                 # check if at least some write_bytes stats are counted
4189                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4190                               obdfilter.$ostname.stats |
4191                               awk '/^write_bytes/ {print $7}' )
4192                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4193                 if (( ${write_bytes:-0} > 0 )); then
4194                         all_zeros=false
4195                         break
4196                 fi
4197         done
4198
4199         $all_zeros || return 0
4200
4201         # Write four bytes
4202         echo foo > $DIR/$tdir/bar
4203         # Really write them
4204         sync
4205
4206         # Total up write_bytes after writing.  We'd better find non-zeros.
4207         for ostnum in $(seq $OSTCOUNT); do
4208                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4209                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4210                               obdfilter/$ostname/stats |
4211                               awk '/^write_bytes/ {print $7}' )
4212                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4213                 if (( ${write_bytes:-0} > 0 )); then
4214                         all_zeros=false
4215                         break
4216                 fi
4217         done
4218
4219         if $all_zeros; then
4220                 for ostnum in $(seq $OSTCOUNT); do
4221                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4222                         echo "Check write_bytes is in obdfilter.*.stats:"
4223                         do_facet ost$ostnum lctl get_param -n \
4224                                 obdfilter.$ostname.stats
4225                 done
4226                 error "OST not keeping write_bytes stats (b=22312)"
4227         fi
4228 }
4229 run_test 33c "test write_bytes stats"
4230
4231 test_33d() {
4232         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4234
4235         local MDTIDX=1
4236         local remote_dir=$DIR/$tdir/remote_dir
4237
4238         test_mkdir $DIR/$tdir
4239         $LFS mkdir -i $MDTIDX $remote_dir ||
4240                 error "create remote directory failed"
4241
4242         touch $remote_dir/$tfile
4243         chmod 444 $remote_dir/$tfile
4244         chown $RUNAS_ID $remote_dir/$tfile
4245
4246         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4247
4248         chown $RUNAS_ID $remote_dir
4249         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4250                                         error "create" || true
4251         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4252                                     error "open RDWR" || true
4253         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4254 }
4255 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4256
4257 test_33e() {
4258         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4259
4260         mkdir $DIR/$tdir
4261
4262         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4263         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4264         mkdir $DIR/$tdir/local_dir
4265
4266         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4267         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4268         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4269
4270         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4271                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4272
4273         rmdir $DIR/$tdir/* || error "rmdir failed"
4274
4275         umask 777
4276         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4277         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4278         mkdir $DIR/$tdir/local_dir
4279
4280         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4281         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4282         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4283
4284         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4285                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4286
4287         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4288
4289         umask 000
4290         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4291         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4292         mkdir $DIR/$tdir/local_dir
4293
4294         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4295         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4296         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4297
4298         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4299                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4300 }
4301 run_test 33e "mkdir and striped directory should have same mode"
4302
4303 cleanup_33f() {
4304         trap 0
4305         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4306 }
4307
4308 test_33f() {
4309         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4310         remote_mds_nodsh && skip "remote MDS with nodsh"
4311
4312         mkdir $DIR/$tdir
4313         chmod go+rwx $DIR/$tdir
4314         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4315         trap cleanup_33f EXIT
4316
4317         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4318                 error "cannot create striped directory"
4319
4320         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4321                 error "cannot create files in striped directory"
4322
4323         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4324                 error "cannot remove files in striped directory"
4325
4326         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4327                 error "cannot remove striped directory"
4328
4329         cleanup_33f
4330 }
4331 run_test 33f "nonroot user can create, access, and remove a striped directory"
4332
4333 test_33g() {
4334         mkdir -p $DIR/$tdir/dir2
4335
4336         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4337         echo $err
4338         [[ $err =~ "exists" ]] || error "Not exists error"
4339 }
4340 run_test 33g "nonroot user create already existing root created file"
4341
4342 sub_33h() {
4343         local hash_type=$1
4344         local count=250
4345
4346         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4347                 error "lfs mkdir -H $hash_type $tdir failed"
4348         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4349
4350         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4351         local index2
4352         local fname
4353
4354         for fname in $DIR/$tdir/$tfile.bak \
4355                      $DIR/$tdir/$tfile.SAV \
4356                      $DIR/$tdir/$tfile.orig \
4357                      $DIR/$tdir/$tfile~; do
4358                 touch $fname || error "touch $fname failed"
4359                 index2=$($LFS getstripe -m $fname)
4360                 (( $index == $index2 )) ||
4361                         error "$fname MDT index mismatch $index != $index2"
4362         done
4363
4364         local failed=0
4365         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4366         local pattern
4367
4368         for pattern in ${patterns[*]}; do
4369                 echo "pattern $pattern"
4370                 fname=$DIR/$tdir/$pattern
4371                 for (( i = 0; i < $count; i++ )); do
4372                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4373                                 error "mktemp $DIR/$tdir/$pattern failed"
4374                         index2=$($LFS getstripe -m $fname)
4375                         (( $index == $index2 )) && continue
4376
4377                         failed=$((failed + 1))
4378                         echo "$fname MDT index mismatch $index != $index2"
4379                 done
4380         done
4381
4382         echo "$failed/$count MDT index mismatches, expect ~2-4"
4383         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4384
4385         local same=0
4386         local expect
4387
4388         # verify that "crush" is still broken with all files on same MDT,
4389         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4390         [[ "$hash_type" == "crush" ]] && expect=$count ||
4391                 expect=$((count / MDSCOUNT))
4392
4393         # crush2 doesn't put all-numeric suffixes on the same MDT,
4394         # filename like $tfile.12345678 should *not* be considered temp
4395         for pattern in ${patterns[*]}; do
4396                 local base=${pattern%%X*}
4397                 local suff=${pattern#$base}
4398
4399                 echo "pattern $pattern"
4400                 for (( i = 0; i < $count; i++ )); do
4401                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4402                         touch $fname || error "touch $fname failed"
4403                         index2=$($LFS getstripe -m $fname)
4404                         (( $index != $index2 )) && continue
4405
4406                         same=$((same + 1))
4407                 done
4408         done
4409
4410         # the number of "bad" hashes is random, as it depends on the random
4411         # filenames generated by "mktemp".  Allow some margin in the results.
4412         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4413         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4414            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4415                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4416         same=0
4417
4418         # crush2 doesn't put suffixes with special characters on the same MDT
4419         # filename like $tfile.txt.1234 should *not* be considered temp
4420         for pattern in ${patterns[*]}; do
4421                 local base=${pattern%%X*}
4422                 local suff=${pattern#$base}
4423
4424                 pattern=$base...${suff/XXX}
4425                 echo "pattern=$pattern"
4426                 for (( i = 0; i < $count; i++ )); do
4427                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4428                                 error "touch $fname failed"
4429                         index2=$($LFS getstripe -m $fname)
4430                         (( $index != $index2 )) && continue
4431
4432                         same=$((same + 1))
4433                 done
4434         done
4435
4436         # the number of "bad" hashes is random, as it depends on the random
4437         # filenames generated by "mktemp".  Allow some margin in the results.
4438         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4439         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4440            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4441                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4442 }
4443
4444 test_33h() {
4445         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4446         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4447                 skip "Need MDS version at least 2.13.50"
4448
4449         sub_33h crush
4450 }
4451 run_test 33h "temp file is located on the same MDT as target (crush)"
4452
4453 test_33hh() {
4454         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4455         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4456         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4457                 skip "Need MDS version at least 2.15.0 for crush2"
4458
4459         sub_33h crush2
4460 }
4461 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4462
4463 test_33i()
4464 {
4465         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4466
4467         local FNAME=$(str_repeat 'f' 250)
4468
4469         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4470         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4471
4472         local count
4473         local total
4474
4475         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4476
4477         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4478
4479         lctl --device %$MDC deactivate
4480         stack_trap "lctl --device %$MDC activate"
4481         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4482         total=$(\ls -l $DIR/$tdir | wc -l)
4483         # "ls -l" will list total in the first line
4484         total=$((total - 1))
4485         (( total + count == 1000 )) ||
4486                 error "ls list $total files, $count files on MDT1"
4487 }
4488 run_test 33i "striped directory can be accessed when one MDT is down"
4489
4490 test_33j() {
4491         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4492
4493         mkdir -p $DIR/$tdir/
4494
4495         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4496                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4497
4498         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4499                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4500
4501         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4502                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4503
4504         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4505                 error "-D was not specified, but still failed"
4506 }
4507 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4508
4509 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4510 test_34a() {
4511         rm -f $DIR/f34
4512         $MCREATE $DIR/f34 || error "mcreate failed"
4513         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4514                 error "getstripe failed"
4515         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4516         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4517                 error "getstripe failed"
4518         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4519                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4520 }
4521 run_test 34a "truncate file that has not been opened ==========="
4522
4523 test_34b() {
4524         [ ! -f $DIR/f34 ] && test_34a
4525         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4526                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4527         $OPENFILE -f O_RDONLY $DIR/f34
4528         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4529                 error "getstripe failed"
4530         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4531                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4532 }
4533 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4534
4535 test_34c() {
4536         [ ! -f $DIR/f34 ] && test_34a
4537         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4538                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4539         $OPENFILE -f O_RDWR $DIR/f34
4540         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4541                 error "$LFS getstripe failed"
4542         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4543                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4544 }
4545 run_test 34c "O_RDWR opening file-with-size works =============="
4546
4547 test_34d() {
4548         [ ! -f $DIR/f34 ] && test_34a
4549         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4550                 error "dd failed"
4551         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4552                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4553         rm $DIR/f34
4554 }
4555 run_test 34d "write to sparse file ============================="
4556
4557 test_34e() {
4558         rm -f $DIR/f34e
4559         $MCREATE $DIR/f34e || error "mcreate failed"
4560         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4561         $CHECKSTAT -s 1000 $DIR/f34e ||
4562                 error "Size of $DIR/f34e not equal to 1000 bytes"
4563         $OPENFILE -f O_RDWR $DIR/f34e
4564         $CHECKSTAT -s 1000 $DIR/f34e ||
4565                 error "Size of $DIR/f34e not equal to 1000 bytes"
4566 }
4567 run_test 34e "create objects, some with size and some without =="
4568
4569 test_34f() { # bug 6242, 6243
4570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4571
4572         SIZE34F=48000
4573         rm -f $DIR/f34f
4574         $MCREATE $DIR/f34f || error "mcreate failed"
4575         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4576         dd if=$DIR/f34f of=$TMP/f34f
4577         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4578         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4579         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4580         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4581         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4582 }
4583 run_test 34f "read from a file with no objects until EOF ======="
4584
4585 test_34g() {
4586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4587
4588         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4589                 error "dd failed"
4590         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4591         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4592                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4593         cancel_lru_locks osc
4594         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4595                 error "wrong size after lock cancel"
4596
4597         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4598         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4599                 error "expanding truncate failed"
4600         cancel_lru_locks osc
4601         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4602                 error "wrong expanded size after lock cancel"
4603 }
4604 run_test 34g "truncate long file ==============================="
4605
4606 test_34h() {
4607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4608
4609         local gid=10
4610         local sz=1000
4611
4612         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4613         sync # Flush the cache so that multiop below does not block on cache
4614              # flush when getting the group lock
4615         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4616         MULTIPID=$!
4617
4618         # Since just timed wait is not good enough, let's do a sync write
4619         # that way we are sure enough time for a roundtrip + processing
4620         # passed + 2 seconds of extra margin.
4621         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4622         rm $DIR/${tfile}-1
4623         sleep 2
4624
4625         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4626                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4627                 kill -9 $MULTIPID
4628         fi
4629         wait $MULTIPID
4630         local nsz=`stat -c %s $DIR/$tfile`
4631         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4632 }
4633 run_test 34h "ftruncate file under grouplock should not block"
4634
4635 test_35a() {
4636         cp /bin/sh $DIR/f35a
4637         chmod 444 $DIR/f35a
4638         chown $RUNAS_ID $DIR/f35a
4639         $RUNAS $DIR/f35a && error || true
4640         rm $DIR/f35a
4641 }
4642 run_test 35a "exec file with mode 444 (should return and not leak)"
4643
4644 test_36a() {
4645         rm -f $DIR/f36
4646         utime $DIR/f36 || error "utime failed for MDS"
4647 }
4648 run_test 36a "MDS utime check (mknod, utime)"
4649
4650 test_36b() {
4651         echo "" > $DIR/f36
4652         utime $DIR/f36 || error "utime failed for OST"
4653 }
4654 run_test 36b "OST utime check (open, utime)"
4655
4656 test_36c() {
4657         rm -f $DIR/d36/f36
4658         test_mkdir $DIR/d36
4659         chown $RUNAS_ID $DIR/d36
4660         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4661 }
4662 run_test 36c "non-root MDS utime check (mknod, utime)"
4663
4664 test_36d() {
4665         [ ! -d $DIR/d36 ] && test_36c
4666         echo "" > $DIR/d36/f36
4667         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4668 }
4669 run_test 36d "non-root OST utime check (open, utime)"
4670
4671 test_36e() {
4672         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4673
4674         test_mkdir $DIR/$tdir
4675         touch $DIR/$tdir/$tfile
4676         $RUNAS utime $DIR/$tdir/$tfile &&
4677                 error "utime worked, expected failure" || true
4678 }
4679 run_test 36e "utime on non-owned file (should return error)"
4680
4681 subr_36fh() {
4682         local fl="$1"
4683         local LANG_SAVE=$LANG
4684         local LC_LANG_SAVE=$LC_LANG
4685         export LANG=C LC_LANG=C # for date language
4686
4687         DATESTR="Dec 20  2000"
4688         test_mkdir $DIR/$tdir
4689         lctl set_param fail_loc=$fl
4690         date; date +%s
4691         cp /etc/hosts $DIR/$tdir/$tfile
4692         sync & # write RPC generated with "current" inode timestamp, but delayed
4693         sleep 1
4694         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4695         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4696         cancel_lru_locks $OSC
4697         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4698         date; date +%s
4699         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4700                 echo "BEFORE: $LS_BEFORE" && \
4701                 echo "AFTER : $LS_AFTER" && \
4702                 echo "WANT  : $DATESTR" && \
4703                 error "$DIR/$tdir/$tfile timestamps changed" || true
4704
4705         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4706 }
4707
4708 test_36f() {
4709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4710
4711         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4712         subr_36fh "0x80000214"
4713 }
4714 run_test 36f "utime on file racing with OST BRW write =========="
4715
4716 test_36g() {
4717         remote_ost_nodsh && skip "remote OST with nodsh"
4718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4719         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4720                 skip "Need MDS version at least 2.12.51"
4721
4722         local fmd_max_age
4723         local fmd
4724         local facet="ost1"
4725         local tgt="obdfilter"
4726
4727         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4728
4729         test_mkdir $DIR/$tdir
4730         fmd_max_age=$(do_facet $facet \
4731                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4732                 head -n 1")
4733
4734         echo "FMD max age: ${fmd_max_age}s"
4735         touch $DIR/$tdir/$tfile
4736         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4737                 gawk '{cnt=cnt+$1}  END{print cnt}')
4738         echo "FMD before: $fmd"
4739         [[ $fmd == 0 ]] &&
4740                 error "FMD wasn't create by touch"
4741         sleep $((fmd_max_age + 12))
4742         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4743                 gawk '{cnt=cnt+$1}  END{print cnt}')
4744         echo "FMD after: $fmd"
4745         [[ $fmd == 0 ]] ||
4746                 error "FMD wasn't expired by ping"
4747 }
4748 run_test 36g "FMD cache expiry ====================="
4749
4750 test_36h() {
4751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4752
4753         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4754         subr_36fh "0x80000227"
4755 }
4756 run_test 36h "utime on file racing with OST BRW write =========="
4757
4758 test_36i() {
4759         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4760
4761         test_mkdir $DIR/$tdir
4762         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4763
4764         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4765         local new_mtime=$((mtime + 200))
4766
4767         #change Modify time of striped dir
4768         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4769                         error "change mtime failed"
4770
4771         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4772
4773         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4774 }
4775 run_test 36i "change mtime on striped directory"
4776
4777 # test_37 - duplicate with tests 32q 32r
4778
4779 test_38() {
4780         local file=$DIR/$tfile
4781         touch $file
4782         openfile -f O_DIRECTORY $file
4783         local RC=$?
4784         local ENOTDIR=20
4785         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4786         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4787 }
4788 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4789
4790 test_39a() { # was test_39
4791         touch $DIR/$tfile
4792         touch $DIR/${tfile}2
4793 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4794 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4795 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4796         sleep 2
4797         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4798         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4799                 echo "mtime"
4800                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4801                 echo "atime"
4802                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4803                 echo "ctime"
4804                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4805                 error "O_TRUNC didn't change timestamps"
4806         fi
4807 }
4808 run_test 39a "mtime changed on create"
4809
4810 test_39b() {
4811         test_mkdir -c1 $DIR/$tdir
4812         cp -p /etc/passwd $DIR/$tdir/fopen
4813         cp -p /etc/passwd $DIR/$tdir/flink
4814         cp -p /etc/passwd $DIR/$tdir/funlink
4815         cp -p /etc/passwd $DIR/$tdir/frename
4816         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4817
4818         sleep 1
4819         echo "aaaaaa" >> $DIR/$tdir/fopen
4820         echo "aaaaaa" >> $DIR/$tdir/flink
4821         echo "aaaaaa" >> $DIR/$tdir/funlink
4822         echo "aaaaaa" >> $DIR/$tdir/frename
4823
4824         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4825         local link_new=`stat -c %Y $DIR/$tdir/flink`
4826         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4827         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4828
4829         cat $DIR/$tdir/fopen > /dev/null
4830         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4831         rm -f $DIR/$tdir/funlink2
4832         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4833
4834         for (( i=0; i < 2; i++ )) ; do
4835                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4836                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4837                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4838                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4839
4840                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4841                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4842                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4843                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4844
4845                 cancel_lru_locks $OSC
4846                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4847         done
4848 }
4849 run_test 39b "mtime change on open, link, unlink, rename  ======"
4850
4851 # this should be set to past
4852 TEST_39_MTIME=`date -d "1 year ago" +%s`
4853
4854 # bug 11063
4855 test_39c() {
4856         touch $DIR1/$tfile
4857         sleep 2
4858         local mtime0=`stat -c %Y $DIR1/$tfile`
4859
4860         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4861         local mtime1=`stat -c %Y $DIR1/$tfile`
4862         [ "$mtime1" = $TEST_39_MTIME ] || \
4863                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4864
4865         local d1=`date +%s`
4866         echo hello >> $DIR1/$tfile
4867         local d2=`date +%s`
4868         local mtime2=`stat -c %Y $DIR1/$tfile`
4869         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4870                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4871
4872         mv $DIR1/$tfile $DIR1/$tfile-1
4873
4874         for (( i=0; i < 2; i++ )) ; do
4875                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4876                 [ "$mtime2" = "$mtime3" ] || \
4877                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4878
4879                 cancel_lru_locks $OSC
4880                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4881         done
4882 }
4883 run_test 39c "mtime change on rename ==========================="
4884
4885 # bug 21114
4886 test_39d() {
4887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4888
4889         touch $DIR1/$tfile
4890         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4891
4892         for (( i=0; i < 2; i++ )) ; do
4893                 local mtime=`stat -c %Y $DIR1/$tfile`
4894                 [ $mtime = $TEST_39_MTIME ] || \
4895                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4896
4897                 cancel_lru_locks $OSC
4898                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4899         done
4900 }
4901 run_test 39d "create, utime, stat =============================="
4902
4903 # bug 21114
4904 test_39e() {
4905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4906
4907         touch $DIR1/$tfile
4908         local mtime1=`stat -c %Y $DIR1/$tfile`
4909
4910         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4911
4912         for (( i=0; i < 2; i++ )) ; do
4913                 local mtime2=`stat -c %Y $DIR1/$tfile`
4914                 [ $mtime2 = $TEST_39_MTIME ] || \
4915                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4916
4917                 cancel_lru_locks $OSC
4918                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4919         done
4920 }
4921 run_test 39e "create, stat, utime, stat ========================"
4922
4923 # bug 21114
4924 test_39f() {
4925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4926
4927         touch $DIR1/$tfile
4928         mtime1=`stat -c %Y $DIR1/$tfile`
4929
4930         sleep 2
4931         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4932
4933         for (( i=0; i < 2; i++ )) ; do
4934                 local mtime2=`stat -c %Y $DIR1/$tfile`
4935                 [ $mtime2 = $TEST_39_MTIME ] || \
4936                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4937
4938                 cancel_lru_locks $OSC
4939                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4940         done
4941 }
4942 run_test 39f "create, stat, sleep, utime, stat ================="
4943
4944 # bug 11063
4945 test_39g() {
4946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4947
4948         echo hello >> $DIR1/$tfile
4949         local mtime1=`stat -c %Y $DIR1/$tfile`
4950
4951         sleep 2
4952         chmod o+r $DIR1/$tfile
4953
4954         for (( i=0; i < 2; i++ )) ; do
4955                 local mtime2=`stat -c %Y $DIR1/$tfile`
4956                 [ "$mtime1" = "$mtime2" ] || \
4957                         error "lost mtime: $mtime2, should be $mtime1"
4958
4959                 cancel_lru_locks $OSC
4960                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4961         done
4962 }
4963 run_test 39g "write, chmod, stat ==============================="
4964
4965 # bug 11063
4966 test_39h() {
4967         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4968
4969         touch $DIR1/$tfile
4970         sleep 1
4971
4972         local d1=`date`
4973         echo hello >> $DIR1/$tfile
4974         local mtime1=`stat -c %Y $DIR1/$tfile`
4975
4976         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4977         local d2=`date`
4978         if [ "$d1" != "$d2" ]; then
4979                 echo "write and touch not within one second"
4980         else
4981                 for (( i=0; i < 2; i++ )) ; do
4982                         local mtime2=`stat -c %Y $DIR1/$tfile`
4983                         [ "$mtime2" = $TEST_39_MTIME ] || \
4984                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4985
4986                         cancel_lru_locks $OSC
4987                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4988                 done
4989         fi
4990 }
4991 run_test 39h "write, utime within one second, stat ============="
4992
4993 test_39i() {
4994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4995
4996         touch $DIR1/$tfile
4997         sleep 1
4998
4999         echo hello >> $DIR1/$tfile
5000         local mtime1=`stat -c %Y $DIR1/$tfile`
5001
5002         mv $DIR1/$tfile $DIR1/$tfile-1
5003
5004         for (( i=0; i < 2; i++ )) ; do
5005                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5006
5007                 [ "$mtime1" = "$mtime2" ] || \
5008                         error "lost mtime: $mtime2, should be $mtime1"
5009
5010                 cancel_lru_locks $OSC
5011                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5012         done
5013 }
5014 run_test 39i "write, rename, stat =============================="
5015
5016 test_39j() {
5017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5018
5019         start_full_debug_logging
5020         touch $DIR1/$tfile
5021         sleep 1
5022
5023         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5024         lctl set_param fail_loc=0x80000412
5025         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5026                 error "multiop failed"
5027         local multipid=$!
5028         local mtime1=`stat -c %Y $DIR1/$tfile`
5029
5030         mv $DIR1/$tfile $DIR1/$tfile-1
5031
5032         kill -USR1 $multipid
5033         wait $multipid || error "multiop close failed"
5034
5035         for (( i=0; i < 2; i++ )) ; do
5036                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5037                 [ "$mtime1" = "$mtime2" ] ||
5038                         error "mtime is lost on close: $mtime2, " \
5039                               "should be $mtime1"
5040
5041                 cancel_lru_locks
5042                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5043         done
5044         lctl set_param fail_loc=0
5045         stop_full_debug_logging
5046 }
5047 run_test 39j "write, rename, close, stat ======================="
5048
5049 test_39k() {
5050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5051
5052         touch $DIR1/$tfile
5053         sleep 1
5054
5055         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5056         local multipid=$!
5057         local mtime1=`stat -c %Y $DIR1/$tfile`
5058
5059         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5060
5061         kill -USR1 $multipid
5062         wait $multipid || error "multiop close failed"
5063
5064         for (( i=0; i < 2; i++ )) ; do
5065                 local mtime2=`stat -c %Y $DIR1/$tfile`
5066
5067                 [ "$mtime2" = $TEST_39_MTIME ] || \
5068                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5069
5070                 cancel_lru_locks
5071                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5072         done
5073 }
5074 run_test 39k "write, utime, close, stat ========================"
5075
5076 # this should be set to future
5077 TEST_39_ATIME=`date -d "1 year" +%s`
5078
5079 test_39l() {
5080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5081         remote_mds_nodsh && skip "remote MDS with nodsh"
5082
5083         local atime_diff=$(do_facet $SINGLEMDS \
5084                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5085         rm -rf $DIR/$tdir
5086         mkdir_on_mdt0 $DIR/$tdir
5087
5088         # test setting directory atime to future
5089         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5090         local atime=$(stat -c %X $DIR/$tdir)
5091         [ "$atime" = $TEST_39_ATIME ] ||
5092                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5093
5094         # test setting directory atime from future to now
5095         local now=$(date +%s)
5096         touch -a -d @$now $DIR/$tdir
5097
5098         atime=$(stat -c %X $DIR/$tdir)
5099         [ "$atime" -eq "$now"  ] ||
5100                 error "atime is not updated from future: $atime, $now"
5101
5102         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5103         sleep 3
5104
5105         # test setting directory atime when now > dir atime + atime_diff
5106         local d1=$(date +%s)
5107         ls $DIR/$tdir
5108         local d2=$(date +%s)
5109         cancel_lru_locks mdc
5110         atime=$(stat -c %X $DIR/$tdir)
5111         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5112                 error "atime is not updated  : $atime, should be $d2"
5113
5114         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5115         sleep 3
5116
5117         # test not setting directory atime when now < dir atime + atime_diff
5118         ls $DIR/$tdir
5119         cancel_lru_locks mdc
5120         atime=$(stat -c %X $DIR/$tdir)
5121         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5122                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5123
5124         do_facet $SINGLEMDS \
5125                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5126 }
5127 run_test 39l "directory atime update ==========================="
5128
5129 test_39m() {
5130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5131
5132         touch $DIR1/$tfile
5133         sleep 2
5134         local far_past_mtime=$(date -d "May 29 1953" +%s)
5135         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5136
5137         touch -m -d @$far_past_mtime $DIR1/$tfile
5138         touch -a -d @$far_past_atime $DIR1/$tfile
5139
5140         for (( i=0; i < 2; i++ )) ; do
5141                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5142                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5143                         error "atime or mtime set incorrectly"
5144
5145                 cancel_lru_locks $OSC
5146                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5147         done
5148 }
5149 run_test 39m "test atime and mtime before 1970"
5150
5151 test_39n() { # LU-3832
5152         remote_mds_nodsh && skip "remote MDS with nodsh"
5153
5154         local atime_diff=$(do_facet $SINGLEMDS \
5155                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5156         local atime0
5157         local atime1
5158         local atime2
5159
5160         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5161
5162         rm -rf $DIR/$tfile
5163         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5164         atime0=$(stat -c %X $DIR/$tfile)
5165
5166         sleep 5
5167         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5168         atime1=$(stat -c %X $DIR/$tfile)
5169
5170         sleep 5
5171         cancel_lru_locks mdc
5172         cancel_lru_locks osc
5173         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5174         atime2=$(stat -c %X $DIR/$tfile)
5175
5176         do_facet $SINGLEMDS \
5177                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5178
5179         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5180         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5181 }
5182 run_test 39n "check that O_NOATIME is honored"
5183
5184 test_39o() {
5185         TESTDIR=$DIR/$tdir/$tfile
5186         [ -e $TESTDIR ] && rm -rf $TESTDIR
5187         mkdir -p $TESTDIR
5188         cd $TESTDIR
5189         links1=2
5190         ls
5191         mkdir a b
5192         ls
5193         links2=$(stat -c %h .)
5194         [ $(($links1 + 2)) != $links2 ] &&
5195                 error "wrong links count $(($links1 + 2)) != $links2"
5196         rmdir b
5197         links3=$(stat -c %h .)
5198         [ $(($links1 + 1)) != $links3 ] &&
5199                 error "wrong links count $links1 != $links3"
5200         return 0
5201 }
5202 run_test 39o "directory cached attributes updated after create"
5203
5204 test_39p() {
5205         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5206
5207         local MDTIDX=1
5208         TESTDIR=$DIR/$tdir/$tdir
5209         [ -e $TESTDIR ] && rm -rf $TESTDIR
5210         test_mkdir -p $TESTDIR
5211         cd $TESTDIR
5212         links1=2
5213         ls
5214         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5215         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5216         ls
5217         links2=$(stat -c %h .)
5218         [ $(($links1 + 2)) != $links2 ] &&
5219                 error "wrong links count $(($links1 + 2)) != $links2"
5220         rmdir remote_dir2
5221         links3=$(stat -c %h .)
5222         [ $(($links1 + 1)) != $links3 ] &&
5223                 error "wrong links count $links1 != $links3"
5224         return 0
5225 }
5226 run_test 39p "remote directory cached attributes updated after create ========"
5227
5228 test_39r() {
5229         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5230                 skip "no atime update on old OST"
5231         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5232                 skip_env "ldiskfs only test"
5233         fi
5234
5235         local saved_adiff
5236         saved_adiff=$(do_facet ost1 \
5237                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5238         stack_trap "do_facet ost1 \
5239                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5240
5241         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5242
5243         $LFS setstripe -i 0 $DIR/$tfile
5244         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5245                 error "can't write initial file"
5246         cancel_lru_locks osc
5247
5248         # exceed atime_diff and access file
5249         sleep 10
5250         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5251                 error "can't udpate atime"
5252
5253         local atime_cli=$(stat -c %X $DIR/$tfile)
5254         echo "client atime: $atime_cli"
5255         # allow atime update to be written to device
5256         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5257         sleep 5
5258
5259         local ostdev=$(ostdevname 1)
5260         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5261         local seq=${fid[3]#0x}
5262         local oid=${fid[1]}
5263         local oid_hex
5264
5265         if [ $seq == 0 ]; then
5266                 oid_hex=${fid[1]}
5267         else
5268                 oid_hex=${fid[2]#0x}
5269         fi
5270         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5271         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5272
5273         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5274         local atime_ost=$(do_facet ost1 "$cmd" |&
5275                           awk -F'[: ]' '/atime:/ { print $4 }')
5276         (( atime_cli == atime_ost )) ||
5277                 error "atime on client $atime_cli != ost $atime_ost"
5278 }
5279 run_test 39r "lazy atime update on OST"
5280
5281 test_39q() { # LU-8041
5282         local testdir=$DIR/$tdir
5283         mkdir -p $testdir
5284         multiop_bg_pause $testdir D_c || error "multiop failed"
5285         local multipid=$!
5286         cancel_lru_locks mdc
5287         kill -USR1 $multipid
5288         local atime=$(stat -c %X $testdir)
5289         [ "$atime" -ne 0 ] || error "atime is zero"
5290 }
5291 run_test 39q "close won't zero out atime"
5292
5293 test_39s() {
5294         local atime0
5295         local atime1
5296         local atime2
5297         local atime3
5298         local atime4
5299
5300         umount_client $MOUNT
5301         mount_client $MOUNT relatime
5302
5303         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5304         atime0=$(stat -c %X $DIR/$tfile)
5305
5306         # First read updates atime
5307         sleep 1
5308         cat $DIR/$tfile >/dev/null
5309         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5310
5311         # Next reads do not update atime
5312         sleep 1
5313         cat $DIR/$tfile >/dev/null
5314         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5315
5316         # If mtime is greater than atime, atime is updated
5317         sleep 1
5318         touch -m $DIR/$tfile # (mtime = now)
5319         sleep 1
5320         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5321         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5322
5323         # Next reads do not update atime
5324         sleep 1
5325         cat $DIR/$tfile >/dev/null
5326         atime4=$(stat -c %X $DIR/$tfile)
5327
5328         # Remount the client to clear 'relatime' option
5329         remount_client $MOUNT
5330
5331         (( atime0 < atime1 )) ||
5332                 error "atime $atime0 should be smaller than $atime1"
5333         (( atime1 == atime2 )) ||
5334                 error "atime $atime1 was updated to $atime2"
5335         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5336         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5337 }
5338 run_test 39s "relatime is supported"
5339
5340 test_40() {
5341         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5342         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5343                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5344         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5345                 error "$tfile is not 4096 bytes in size"
5346 }
5347 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5348
5349 test_41() {
5350         # bug 1553
5351         small_write $DIR/f41 18
5352 }
5353 run_test 41 "test small file write + fstat ====================="
5354
5355 count_ost_writes() {
5356         lctl get_param -n ${OSC}.*.stats |
5357                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5358                         END { printf("%0.0f", writes) }'
5359 }
5360
5361 # decent default
5362 WRITEBACK_SAVE=500
5363 DIRTY_RATIO_SAVE=40
5364 MAX_DIRTY_RATIO=50
5365 BG_DIRTY_RATIO_SAVE=10
5366 MAX_BG_DIRTY_RATIO=25
5367
5368 start_writeback() {
5369         trap 0
5370         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5371         # dirty_ratio, dirty_background_ratio
5372         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5373                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5374                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5375                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5376         else
5377                 # if file not here, we are a 2.4 kernel
5378                 kill -CONT `pidof kupdated`
5379         fi
5380 }
5381
5382 stop_writeback() {
5383         # setup the trap first, so someone cannot exit the test at the
5384         # exact wrong time and mess up a machine
5385         trap start_writeback EXIT
5386         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5387         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5388                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5389                 sysctl -w vm.dirty_writeback_centisecs=0
5390                 sysctl -w vm.dirty_writeback_centisecs=0
5391                 # save and increase /proc/sys/vm/dirty_ratio
5392                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5393                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5394                 # save and increase /proc/sys/vm/dirty_background_ratio
5395                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5396                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5397         else
5398                 # if file not here, we are a 2.4 kernel
5399                 kill -STOP `pidof kupdated`
5400         fi
5401 }
5402
5403 # ensure that all stripes have some grant before we test client-side cache
5404 setup_test42() {
5405         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5406                 dd if=/dev/zero of=$i bs=4k count=1
5407                 rm $i
5408         done
5409 }
5410
5411 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5412 # file truncation, and file removal.
5413 test_42a() {
5414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5415
5416         setup_test42
5417         cancel_lru_locks $OSC
5418         stop_writeback
5419         sync; sleep 1; sync # just to be safe
5420         BEFOREWRITES=`count_ost_writes`
5421         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5422         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5423         AFTERWRITES=`count_ost_writes`
5424         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5425                 error "$BEFOREWRITES < $AFTERWRITES"
5426         start_writeback
5427 }
5428 run_test 42a "ensure that we don't flush on close"
5429
5430 test_42b() {
5431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5432
5433         setup_test42
5434         cancel_lru_locks $OSC
5435         stop_writeback
5436         sync
5437         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5438         BEFOREWRITES=$(count_ost_writes)
5439         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5440         AFTERWRITES=$(count_ost_writes)
5441         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5442                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5443         fi
5444         BEFOREWRITES=$(count_ost_writes)
5445         sync || error "sync: $?"
5446         AFTERWRITES=$(count_ost_writes)
5447         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5448                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5449         fi
5450         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5451         start_writeback
5452         return 0
5453 }
5454 run_test 42b "test destroy of file with cached dirty data ======"
5455
5456 # if these tests just want to test the effect of truncation,
5457 # they have to be very careful.  consider:
5458 # - the first open gets a {0,EOF}PR lock
5459 # - the first write conflicts and gets a {0, count-1}PW
5460 # - the rest of the writes are under {count,EOF}PW
5461 # - the open for truncate tries to match a {0,EOF}PR
5462 #   for the filesize and cancels the PWs.
5463 # any number of fixes (don't get {0,EOF} on open, match
5464 # composite locks, do smarter file size management) fix
5465 # this, but for now we want these tests to verify that
5466 # the cancellation with truncate intent works, so we
5467 # start the file with a full-file pw lock to match against
5468 # until the truncate.
5469 trunc_test() {
5470         test=$1
5471         file=$DIR/$test
5472         offset=$2
5473         cancel_lru_locks $OSC
5474         stop_writeback
5475         # prime the file with 0,EOF PW to match
5476         touch $file
5477         $TRUNCATE $file 0
5478         sync; sync
5479         # now the real test..
5480         dd if=/dev/zero of=$file bs=1024 count=100
5481         BEFOREWRITES=`count_ost_writes`
5482         $TRUNCATE $file $offset
5483         cancel_lru_locks $OSC
5484         AFTERWRITES=`count_ost_writes`
5485         start_writeback
5486 }
5487
5488 test_42c() {
5489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5490
5491         trunc_test 42c 1024
5492         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5493                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5494         rm $file
5495 }
5496 run_test 42c "test partial truncate of file with cached dirty data"
5497
5498 test_42d() {
5499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5500
5501         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5502         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5503         $LCTL set_param debug=+cache
5504
5505         trunc_test 42d 0
5506         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5507                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5508         rm $file
5509 }
5510 run_test 42d "test complete truncate of file with cached dirty data"
5511
5512 test_42e() { # bug22074
5513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5514
5515         local TDIR=$DIR/${tdir}e
5516         local pages=16 # hardcoded 16 pages, don't change it.
5517         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5518         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5519         local max_dirty_mb
5520         local warmup_files
5521
5522         test_mkdir $DIR/${tdir}e
5523         $LFS setstripe -c 1 $TDIR
5524         createmany -o $TDIR/f $files
5525
5526         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5527
5528         # we assume that with $OSTCOUNT files, at least one of them will
5529         # be allocated on OST0.
5530         warmup_files=$((OSTCOUNT * max_dirty_mb))
5531         createmany -o $TDIR/w $warmup_files
5532
5533         # write a large amount of data into one file and sync, to get good
5534         # avail_grant number from OST.
5535         for ((i=0; i<$warmup_files; i++)); do
5536                 idx=$($LFS getstripe -i $TDIR/w$i)
5537                 [ $idx -ne 0 ] && continue
5538                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5539                 break
5540         done
5541         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5542         sync
5543         $LCTL get_param $proc_osc0/cur_dirty_bytes
5544         $LCTL get_param $proc_osc0/cur_grant_bytes
5545
5546         # create as much dirty pages as we can while not to trigger the actual
5547         # RPCs directly. but depends on the env, VFS may trigger flush during this
5548         # period, hopefully we are good.
5549         for ((i=0; i<$warmup_files; i++)); do
5550                 idx=$($LFS getstripe -i $TDIR/w$i)
5551                 [ $idx -ne 0 ] && continue
5552                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5553         done
5554         $LCTL get_param $proc_osc0/cur_dirty_bytes
5555         $LCTL get_param $proc_osc0/cur_grant_bytes
5556
5557         # perform the real test
5558         $LCTL set_param $proc_osc0/rpc_stats 0
5559         for ((;i<$files; i++)); do
5560                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5561                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5562         done
5563         sync
5564         $LCTL get_param $proc_osc0/rpc_stats
5565
5566         local percent=0
5567         local have_ppr=false
5568         $LCTL get_param $proc_osc0/rpc_stats |
5569                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5570                         # skip lines until we are at the RPC histogram data
5571                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5572                         $have_ppr || continue
5573
5574                         # we only want the percent stat for < 16 pages
5575                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5576
5577                         percent=$((percent + WPCT))
5578                         if [[ $percent -gt 15 ]]; then
5579                                 error "less than 16-pages write RPCs" \
5580                                       "$percent% > 15%"
5581                                 break
5582                         fi
5583                 done
5584         rm -rf $TDIR
5585 }
5586 run_test 42e "verify sub-RPC writes are not done synchronously"
5587
5588 test_43A() { # was test_43
5589         test_mkdir $DIR/$tdir
5590         cp -p /bin/ls $DIR/$tdir/$tfile
5591         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5592         pid=$!
5593         # give multiop a chance to open
5594         sleep 1
5595
5596         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5597         kill -USR1 $pid
5598         # Wait for multiop to exit
5599         wait $pid
5600 }
5601 run_test 43A "execution of file opened for write should return -ETXTBSY"
5602
5603 test_43a() {
5604         test_mkdir $DIR/$tdir
5605         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5606         $DIR/$tdir/sleep 60 &
5607         SLEEP_PID=$!
5608         # Make sure exec of $tdir/sleep wins race with truncate
5609         sleep 1
5610         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5611         kill $SLEEP_PID
5612 }
5613 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5614
5615 test_43b() {
5616         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5617
5618         test_mkdir $DIR/$tdir
5619         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5620         $DIR/$tdir/sleep 60 &
5621         SLEEP_PID=$!
5622         # Make sure exec of $tdir/sleep wins race with truncate
5623         sleep 1
5624         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5625         kill $SLEEP_PID
5626 }
5627 run_test 43b "truncate of file being executed should return -ETXTBSY"
5628
5629 test_43c() {
5630         local testdir="$DIR/$tdir"
5631         test_mkdir $testdir
5632         cp $SHELL $testdir/
5633         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5634                 ( cd $testdir && md5sum -c )
5635 }
5636 run_test 43c "md5sum of copy into lustre"
5637
5638 test_44A() { # was test_44
5639         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5640
5641         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5642         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5643 }
5644 run_test 44A "zero length read from a sparse stripe"
5645
5646 test_44a() {
5647         local nstripe=$($LFS getstripe -c -d $DIR)
5648         [ -z "$nstripe" ] && skip "can't get stripe info"
5649         [[ $nstripe -gt $OSTCOUNT ]] &&
5650                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5651
5652         local stride=$($LFS getstripe -S -d $DIR)
5653         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5654                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5655         fi
5656
5657         OFFSETS="0 $((stride/2)) $((stride-1))"
5658         for offset in $OFFSETS; do
5659                 for i in $(seq 0 $((nstripe-1))); do
5660                         local GLOBALOFFSETS=""
5661                         # size in Bytes
5662                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5663                         local myfn=$DIR/d44a-$size
5664                         echo "--------writing $myfn at $size"
5665                         ll_sparseness_write $myfn $size ||
5666                                 error "ll_sparseness_write"
5667                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5668                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5669                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5670
5671                         for j in $(seq 0 $((nstripe-1))); do
5672                                 # size in Bytes
5673                                 size=$((((j + $nstripe )*$stride + $offset)))
5674                                 ll_sparseness_write $myfn $size ||
5675                                         error "ll_sparseness_write"
5676                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5677                         done
5678                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5679                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5680                         rm -f $myfn
5681                 done
5682         done
5683 }
5684 run_test 44a "test sparse pwrite ==============================="
5685
5686 dirty_osc_total() {
5687         tot=0
5688         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5689                 tot=$(($tot + $d))
5690         done
5691         echo $tot
5692 }
5693 do_dirty_record() {
5694         before=`dirty_osc_total`
5695         echo executing "\"$*\""
5696         eval $*
5697         after=`dirty_osc_total`
5698         echo before $before, after $after
5699 }
5700 test_45() {
5701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5702
5703         f="$DIR/f45"
5704         # Obtain grants from OST if it supports it
5705         echo blah > ${f}_grant
5706         stop_writeback
5707         sync
5708         do_dirty_record "echo blah > $f"
5709         [[ $before -eq $after ]] && error "write wasn't cached"
5710         do_dirty_record "> $f"
5711         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5712         do_dirty_record "echo blah > $f"
5713         [[ $before -eq $after ]] && error "write wasn't cached"
5714         do_dirty_record "sync"
5715         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5716         do_dirty_record "echo blah > $f"
5717         [[ $before -eq $after ]] && error "write wasn't cached"
5718         do_dirty_record "cancel_lru_locks osc"
5719         [[ $before -gt $after ]] ||
5720                 error "lock cancellation didn't lower dirty count"
5721         start_writeback
5722 }
5723 run_test 45 "osc io page accounting ============================"
5724
5725 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5726 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5727 # objects offset and an assert hit when an rpc was built with 1023's mapped
5728 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5729 test_46() {
5730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5731
5732         f="$DIR/f46"
5733         stop_writeback
5734         sync
5735         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5736         sync
5737         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5738         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5739         sync
5740         start_writeback
5741 }
5742 run_test 46 "dirtying a previously written page ================"
5743
5744 # test_47 is removed "Device nodes check" is moved to test_28
5745
5746 test_48a() { # bug 2399
5747         [ "$mds1_FSTYPE" = "zfs" ] &&
5748         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5749                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5750
5751         test_mkdir $DIR/$tdir
5752         cd $DIR/$tdir
5753         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5754         test_mkdir $DIR/$tdir
5755         touch foo || error "'touch foo' failed after recreating cwd"
5756         test_mkdir bar
5757         touch .foo || error "'touch .foo' failed after recreating cwd"
5758         test_mkdir .bar
5759         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5760         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5761         cd . || error "'cd .' failed after recreating cwd"
5762         mkdir . && error "'mkdir .' worked after recreating cwd"
5763         rmdir . && error "'rmdir .' worked after recreating cwd"
5764         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5765         cd .. || error "'cd ..' failed after recreating cwd"
5766 }
5767 run_test 48a "Access renamed working dir (should return errors)="
5768
5769 test_48b() { # bug 2399
5770         rm -rf $DIR/$tdir
5771         test_mkdir $DIR/$tdir
5772         cd $DIR/$tdir
5773         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5774         touch foo && error "'touch foo' worked after removing cwd"
5775         mkdir foo && error "'mkdir foo' worked after removing cwd"
5776         touch .foo && error "'touch .foo' worked after removing cwd"
5777         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5778         ls . > /dev/null && error "'ls .' worked after removing cwd"
5779         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5780         mkdir . && error "'mkdir .' worked after removing cwd"
5781         rmdir . && error "'rmdir .' worked after removing cwd"
5782         ln -s . foo && error "'ln -s .' worked after removing cwd"
5783         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5784 }
5785 run_test 48b "Access removed working dir (should return errors)="
5786
5787 test_48c() { # bug 2350
5788         #lctl set_param debug=-1
5789         #set -vx
5790         rm -rf $DIR/$tdir
5791         test_mkdir -p $DIR/$tdir/dir
5792         cd $DIR/$tdir/dir
5793         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5794         $TRACE touch foo && error "touch foo worked after removing cwd"
5795         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5796         touch .foo && error "touch .foo worked after removing cwd"
5797         mkdir .foo && error "mkdir .foo worked after removing cwd"
5798         $TRACE ls . && error "'ls .' worked after removing cwd"
5799         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5800         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5801         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5802         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5803         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5804 }
5805 run_test 48c "Access removed working subdir (should return errors)"
5806
5807 test_48d() { # bug 2350
5808         #lctl set_param debug=-1
5809         #set -vx
5810         rm -rf $DIR/$tdir
5811         test_mkdir -p $DIR/$tdir/dir
5812         cd $DIR/$tdir/dir
5813         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5814         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5815         $TRACE touch foo && error "'touch foo' worked after removing parent"
5816         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5817         touch .foo && error "'touch .foo' worked after removing parent"
5818         mkdir .foo && error "mkdir .foo worked after removing parent"
5819         $TRACE ls . && error "'ls .' worked after removing parent"
5820         $TRACE ls .. && error "'ls ..' worked after removing parent"
5821         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5822         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5823         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5824         true
5825 }
5826 run_test 48d "Access removed parent subdir (should return errors)"
5827
5828 test_48e() { # bug 4134
5829         #lctl set_param debug=-1
5830         #set -vx
5831         rm -rf $DIR/$tdir
5832         test_mkdir -p $DIR/$tdir/dir
5833         cd $DIR/$tdir/dir
5834         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5835         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5836         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5837         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5838         # On a buggy kernel addition of "touch foo" after cd .. will
5839         # produce kernel oops in lookup_hash_it
5840         touch ../foo && error "'cd ..' worked after recreate parent"
5841         cd $DIR
5842         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5843 }
5844 run_test 48e "Access to recreated parent subdir (should return errors)"
5845
5846 test_48f() {
5847         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5848                 skip "need MDS >= 2.13.55"
5849         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5850         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5851                 skip "needs different host for mdt1 mdt2"
5852         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5853
5854         $LFS mkdir -i0 $DIR/$tdir
5855         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5856
5857         for d in sub1 sub2 sub3; do
5858                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5859                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5860                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5861         done
5862
5863         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5864 }
5865 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5866
5867 test_49() { # LU-1030
5868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5869         remote_ost_nodsh && skip "remote OST with nodsh"
5870
5871         # get ost1 size - $FSNAME-OST0000
5872         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5873                 awk '{ print $4 }')
5874         # write 800M at maximum
5875         [[ $ost1_size -lt 2 ]] && ost1_size=2
5876         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5877
5878         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5879         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5880         local dd_pid=$!
5881
5882         # change max_pages_per_rpc while writing the file
5883         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5884         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5885         # loop until dd process exits
5886         while ps ax -opid | grep -wq $dd_pid; do
5887                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5888                 sleep $((RANDOM % 5 + 1))
5889         done
5890         # restore original max_pages_per_rpc
5891         $LCTL set_param $osc1_mppc=$orig_mppc
5892         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5893 }
5894 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5895
5896 test_50() {
5897         # bug 1485
5898         test_mkdir $DIR/$tdir
5899         cd $DIR/$tdir
5900         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5901 }
5902 run_test 50 "special situations: /proc symlinks  ==============="
5903
5904 test_51a() {    # was test_51
5905         # bug 1516 - create an empty entry right after ".." then split dir
5906         test_mkdir -c1 $DIR/$tdir
5907         touch $DIR/$tdir/foo
5908         $MCREATE $DIR/$tdir/bar
5909         rm $DIR/$tdir/foo
5910         createmany -m $DIR/$tdir/longfile 201
5911         FNUM=202
5912         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5913                 $MCREATE $DIR/$tdir/longfile$FNUM
5914                 FNUM=$(($FNUM + 1))
5915                 echo -n "+"
5916         done
5917         echo
5918         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5919 }
5920 run_test 51a "special situations: split htree with empty entry =="
5921
5922 cleanup_print_lfs_df () {
5923         trap 0
5924         $LFS df
5925         $LFS df -i
5926 }
5927
5928 test_51b() {
5929         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5930
5931         local dir=$DIR/$tdir
5932         local nrdirs=$((65536 + 100))
5933
5934         # cleanup the directory
5935         rm -fr $dir
5936
5937         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5938
5939         $LFS df
5940         $LFS df -i
5941         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5942         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5943         [[ $numfree -lt $nrdirs ]] &&
5944                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5945
5946         # need to check free space for the directories as well
5947         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5948         numfree=$(( blkfree / $(fs_inode_ksize) ))
5949         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5950
5951         trap cleanup_print_lfs_df EXIT
5952
5953         # create files
5954         createmany -d $dir/d $nrdirs || {
5955                 unlinkmany $dir/d $nrdirs
5956                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5957         }
5958
5959         # really created :
5960         nrdirs=$(ls -U $dir | wc -l)
5961
5962         # unlink all but 100 subdirectories, then check it still works
5963         local left=100
5964         local delete=$((nrdirs - left))
5965
5966         $LFS df
5967         $LFS df -i
5968
5969         # for ldiskfs the nlink count should be 1, but this is OSD specific
5970         # and so this is listed for informational purposes only
5971         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5972         unlinkmany -d $dir/d $delete ||
5973                 error "unlink of first $delete subdirs failed"
5974
5975         echo "nlink between: $(stat -c %h $dir)"
5976         local found=$(ls -U $dir | wc -l)
5977         [ $found -ne $left ] &&
5978                 error "can't find subdirs: found only $found, expected $left"
5979
5980         unlinkmany -d $dir/d $delete $left ||
5981                 error "unlink of second $left subdirs failed"
5982         # regardless of whether the backing filesystem tracks nlink accurately
5983         # or not, the nlink count shouldn't be more than "." and ".." here
5984         local after=$(stat -c %h $dir)
5985         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5986                 echo "nlink after: $after"
5987
5988         cleanup_print_lfs_df
5989 }
5990 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5991
5992 test_51d_sub() {
5993         local stripecount=$1
5994         local nfiles=$2
5995
5996         log "create files with stripecount=$stripecount"
5997         $LFS setstripe -C $stripecount $DIR/$tdir
5998         createmany -o $DIR/$tdir/t- $nfiles
5999         $LFS getstripe $DIR/$tdir > $TMP/$tfile
6000         for ((n = 0; n < $OSTCOUNT; n++)); do
6001                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
6002                            END { printf("%0.0f", objs) }' $TMP/$tfile)
6003                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
6004                             '($1 == '$n') { objs += 1 } \
6005                             END { printf("%0.0f", objs) }')
6006                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6007         done
6008         unlinkmany $DIR/$tdir/t- $nfiles
6009         rm  -f $TMP/$tfile
6010
6011         local nlast
6012         local min=4
6013         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6014
6015         # For some combinations of stripecount and OSTCOUNT current code
6016         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6017         # than others. Rather than skipping this test entirely, check that
6018         # and keep testing to ensure imbalance does not get worse. LU-15282
6019         (( (OSTCOUNT == 6 && stripecount == 4) ||
6020            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6021            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6022         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6023                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6024                         { $LFS df && $LFS df -i &&
6025                         error "stripecount=$stripecount: " \
6026                               "OST $n has fewer objects vs. OST $nlast " \
6027                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6028                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6029                         { $LFS df && $LFS df -i &&
6030                         error "stripecount=$stripecount: " \
6031                               "OST $n has more objects vs. OST $nlast " \
6032                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6033
6034                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6035                         { $LFS df && $LFS df -i &&
6036                         error "stripecount=$stripecount: " \
6037                               "OST $n has fewer #0 objects vs. OST $nlast " \
6038                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6039                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6040                         { $LFS df && $LFS df -i &&
6041                         error "stripecount=$stripecount: " \
6042                               "OST $n has more #0 objects vs. OST $nlast " \
6043                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6044         done
6045 }
6046
6047 test_51d() {
6048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6049         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6050
6051         local stripecount
6052         local per_ost=100
6053         local nfiles=$((per_ost * OSTCOUNT))
6054         local mdts=$(comma_list $(mdts_nodes))
6055         local param="osp.*.create_count"
6056         local qos_old=$(do_facet mds1 \
6057                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6058
6059         do_nodes $mdts \
6060                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6061         stack_trap "do_nodes $mdts \
6062                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6063
6064         test_mkdir $DIR/$tdir
6065         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6066         (( dirstripes > 0 )) || dirstripes=1
6067
6068         # Ensure enough OST objects precreated for tests to pass without
6069         # running out of objects.  This is an LOV r-r OST algorithm test,
6070         # not an OST object precreation test.
6071         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6072         (( old >= nfiles )) ||
6073         {
6074                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6075
6076                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6077                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6078
6079                 # trigger precreation from all MDTs for all OSTs
6080                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6081                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6082                 done
6083         }
6084
6085         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6086                 sleep 8  # allow object precreation to catch up
6087                 test_51d_sub $stripecount $nfiles
6088         done
6089 }
6090 run_test 51d "check LOV round-robin OST object distribution"
6091
6092 test_51e() {
6093         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6094                 skip_env "ldiskfs only test"
6095         fi
6096
6097         test_mkdir -c1 $DIR/$tdir
6098         test_mkdir -c1 $DIR/$tdir/d0
6099
6100         touch $DIR/$tdir/d0/foo
6101         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6102                 error "file exceed 65000 nlink limit!"
6103         unlinkmany $DIR/$tdir/d0/f- 65001
6104         return 0
6105 }
6106 run_test 51e "check file nlink limit"
6107
6108 test_51f() {
6109         test_mkdir $DIR/$tdir
6110
6111         local max=100000
6112         local ulimit_old=$(ulimit -n)
6113         local spare=20 # number of spare fd's for scripts/libraries, etc.
6114         local mdt=$($LFS getstripe -m $DIR/$tdir)
6115         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6116
6117         echo "MDT$mdt numfree=$numfree, max=$max"
6118         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6119         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6120                 while ! ulimit -n $((numfree + spare)); do
6121                         numfree=$((numfree * 3 / 4))
6122                 done
6123                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6124         else
6125                 echo "left ulimit at $ulimit_old"
6126         fi
6127
6128         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6129                 unlinkmany $DIR/$tdir/f $numfree
6130                 error "create+open $numfree files in $DIR/$tdir failed"
6131         }
6132         ulimit -n $ulimit_old
6133
6134         # if createmany exits at 120s there will be fewer than $numfree files
6135         unlinkmany $DIR/$tdir/f $numfree || true
6136 }
6137 run_test 51f "check many open files limit"
6138
6139 test_52a() {
6140         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6141         test_mkdir $DIR/$tdir
6142         touch $DIR/$tdir/foo
6143         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6144         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6145         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6146         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6147         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6148                                         error "link worked"
6149         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6150         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6151         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6152                                                      error "lsattr"
6153         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6154         cp -r $DIR/$tdir $TMP/
6155         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6156 }
6157 run_test 52a "append-only flag test (should return errors)"
6158
6159 test_52b() {
6160         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6161         test_mkdir $DIR/$tdir
6162         touch $DIR/$tdir/foo
6163         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6164         cat test > $DIR/$tdir/foo && error "cat test worked"
6165         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6166         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6167         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6168                                         error "link worked"
6169         echo foo >> $DIR/$tdir/foo && error "echo worked"
6170         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6171         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6172         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6173         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6174                                                         error "lsattr"
6175         chattr -i $DIR/$tdir/foo || error "chattr failed"
6176
6177         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6178 }
6179 run_test 52b "immutable flag test (should return errors) ======="
6180
6181 test_53() {
6182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6183         remote_mds_nodsh && skip "remote MDS with nodsh"
6184         remote_ost_nodsh && skip "remote OST with nodsh"
6185
6186         local param
6187         local param_seq
6188         local ostname
6189         local mds_last
6190         local mds_last_seq
6191         local ost_last
6192         local ost_last_seq
6193         local ost_last_id
6194         local ostnum
6195         local node
6196         local found=false
6197         local support_last_seq=true
6198
6199         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6200                 support_last_seq=false
6201
6202         # only test MDT0000
6203         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6204         local value
6205         for value in $(do_facet $SINGLEMDS \
6206                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6207                 param=$(echo ${value[0]} | cut -d "=" -f1)
6208                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6209
6210                 if $support_last_seq; then
6211                         param_seq=$(echo $param |
6212                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6213                         mds_last_seq=$(do_facet $SINGLEMDS \
6214                                        $LCTL get_param -n $param_seq)
6215                 fi
6216                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6217
6218                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6219                 node=$(facet_active_host ost$((ostnum+1)))
6220                 param="obdfilter.$ostname.last_id"
6221                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6222                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6223                         ost_last_id=$ost_last
6224
6225                         if $support_last_seq; then
6226                                 ost_last_id=$(echo $ost_last |
6227                                               awk -F':' '{print $2}' |
6228                                               sed -e "s/^0x//g")
6229                                 ost_last_seq=$(echo $ost_last |
6230                                                awk -F':' '{print $1}')
6231                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6232                         fi
6233
6234                         if [[ $ost_last_id != $mds_last ]]; then
6235                                 error "$ost_last_id != $mds_last"
6236                         else
6237                                 found=true
6238                                 break
6239                         fi
6240                 done
6241         done
6242         $found || error "can not match last_seq/last_id for $mdtosc"
6243         return 0
6244 }
6245 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6246
6247 test_54a() {
6248         LANG=C perl -MSocket -e ';' || skip "no Socket perl module installed"
6249
6250         LANG=C $SOCKETSERVER $DIR/socket ||
6251                 error "$SOCKETSERVER $DIR/socket failed: $?"
6252         LANG=C $SOCKETCLIENT $DIR/socket ||
6253                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6254         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6255 }
6256 run_test 54a "unix domain socket test =========================="
6257
6258 test_54b() {
6259         f="$DIR/f54b"
6260         mknod $f c 1 3
6261         chmod 0666 $f
6262         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6263 }
6264 run_test 54b "char device works in lustre ======================"
6265
6266 find_loop_dev() {
6267         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6268         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6269         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6270
6271         for i in $(seq 3 7); do
6272                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6273                 LOOPDEV=$LOOPBASE$i
6274                 LOOPNUM=$i
6275                 break
6276         done
6277 }
6278
6279 cleanup_54c() {
6280         local rc=0
6281         loopdev="$DIR/loop54c"
6282
6283         trap 0
6284         $UMOUNT $DIR/$tdir || rc=$?
6285         losetup -d $loopdev || true
6286         losetup -d $LOOPDEV || true
6287         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6288         return $rc
6289 }
6290
6291 test_54c() {
6292         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6293
6294         loopdev="$DIR/loop54c"
6295
6296         find_loop_dev
6297         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6298         trap cleanup_54c EXIT
6299         mknod $loopdev b 7 $LOOPNUM
6300         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6301         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6302         losetup $loopdev $DIR/$tfile ||
6303                 error "can't set up $loopdev for $DIR/$tfile"
6304         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6305         test_mkdir $DIR/$tdir
6306         mount -t ext2 $loopdev $DIR/$tdir ||
6307                 error "error mounting $loopdev on $DIR/$tdir"
6308         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6309                 error "dd write"
6310         df $DIR/$tdir
6311         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6312                 error "dd read"
6313         cleanup_54c
6314 }
6315 run_test 54c "block device works in lustre ====================="
6316
6317 test_54d() {
6318         local pipe="$DIR/$tfile.pipe"
6319         local string="aaaaaa"
6320
6321         mknod $pipe p
6322         echo -n "$string" > $pipe &
6323         local result=$(cat $pipe)
6324         [[ "$result" == "$string" ]] || error "$result != $string"
6325 }
6326 run_test 54d "fifo device works in lustre ======================"
6327
6328 test_54e() {
6329         f="$DIR/f54e"
6330         string="aaaaaa"
6331         cp -aL /dev/console $f
6332         echo $string > $f || error "echo $string to $f failed"
6333 }
6334 run_test 54e "console/tty device works in lustre ======================"
6335
6336 test_56a() {
6337         local numfiles=3
6338         local numdirs=2
6339         local dir=$DIR/$tdir
6340
6341         rm -rf $dir
6342         test_mkdir -p $dir/dir
6343         for i in $(seq $numfiles); do
6344                 touch $dir/file$i
6345                 touch $dir/dir/file$i
6346         done
6347
6348         local numcomp=$($LFS getstripe --component-count $dir)
6349
6350         [[ $numcomp == 0 ]] && numcomp=1
6351
6352         # test lfs getstripe with --recursive
6353         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6354
6355         [[ $filenum -eq $((numfiles * 2)) ]] ||
6356                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6357         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6358         [[ $filenum -eq $numfiles ]] ||
6359                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6360         echo "$LFS getstripe showed obdidx or l_ost_idx"
6361
6362         # test lfs getstripe with file instead of dir
6363         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6364         [[ $filenum -eq 1 ]] ||
6365                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6366         echo "$LFS getstripe file1 passed"
6367
6368         #test lfs getstripe with --verbose
6369         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6370         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6371                 error "$LFS getstripe --verbose $dir: "\
6372                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6373         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6374                 error "$LFS getstripe $dir: showed lmm_magic"
6375
6376         #test lfs getstripe with -v prints lmm_fid
6377         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6378         local countfids=$((numdirs + numfiles * numcomp))
6379         [[ $filenum -eq $countfids ]] ||
6380                 error "$LFS getstripe -v $dir: "\
6381                       "got $filenum want $countfids lmm_fid"
6382         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6383                 error "$LFS getstripe $dir: showed lmm_fid by default"
6384         echo "$LFS getstripe --verbose passed"
6385
6386         #check for FID information
6387         local fid1=$($LFS getstripe --fid $dir/file1)
6388         local fid2=$($LFS getstripe --verbose $dir/file1 |
6389                      awk '/lmm_fid: / { print $2; exit; }')
6390         local fid3=$($LFS path2fid $dir/file1)
6391
6392         [ "$fid1" != "$fid2" ] &&
6393                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6394         [ "$fid1" != "$fid3" ] &&
6395                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6396         echo "$LFS getstripe --fid passed"
6397
6398         #test lfs getstripe with --obd
6399         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6400                 error "$LFS getstripe --obd wrong_uuid: should return error"
6401
6402         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6403
6404         local ostidx=1
6405         local obduuid=$(ostuuid_from_index $ostidx)
6406         local found=$($LFS getstripe -r --obd $obduuid $dir |
6407                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6408
6409         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6410         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6411                 ((filenum--))
6412         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6413                 ((filenum--))
6414
6415         [[ $found -eq $filenum ]] ||
6416                 error "$LFS getstripe --obd: found $found expect $filenum"
6417         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6418                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6419                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6420                 error "$LFS getstripe --obd: should not show file on other obd"
6421         echo "$LFS getstripe --obd passed"
6422 }
6423 run_test 56a "check $LFS getstripe"
6424
6425 test_56b() {
6426         local dir=$DIR/$tdir
6427         local numdirs=3
6428
6429         test_mkdir $dir
6430         for i in $(seq $numdirs); do
6431                 test_mkdir $dir/dir$i
6432         done
6433
6434         # test lfs getdirstripe default mode is non-recursion, which is
6435         # different from lfs getstripe
6436         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6437
6438         [[ $dircnt -eq 1 ]] ||
6439                 error "$LFS getdirstripe: found $dircnt, not 1"
6440         dircnt=$($LFS getdirstripe --recursive $dir |
6441                 grep -c lmv_stripe_count)
6442         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6443                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6444 }
6445 run_test 56b "check $LFS getdirstripe"
6446
6447 test_56bb() {
6448         verify_yaml_available || skip_env "YAML verification not installed"
6449         local output_file=$DIR/$tfile.out
6450
6451         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6452
6453         cat $output_file
6454         cat $output_file | verify_yaml || error "layout is not valid YAML"
6455 }
6456 run_test 56bb "check $LFS getdirstripe layout is YAML"
6457
6458 test_56c() {
6459         remote_ost_nodsh && skip "remote OST with nodsh"
6460
6461         local ost_idx=0
6462         local ost_name=$(ostname_from_index $ost_idx)
6463         local old_status=$(ost_dev_status $ost_idx)
6464         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6465
6466         [[ -z "$old_status" ]] ||
6467                 skip_env "OST $ost_name is in $old_status status"
6468
6469         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6470         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6471                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6472         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6473                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6474                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6475         fi
6476
6477         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6478                 error "$LFS df -v showing inactive devices"
6479         sleep_maxage
6480
6481         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6482
6483         [[ "$new_status" =~ "D" ]] ||
6484                 error "$ost_name status is '$new_status', missing 'D'"
6485         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6486                 [[ "$new_status" =~ "N" ]] ||
6487                         error "$ost_name status is '$new_status', missing 'N'"
6488         fi
6489         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6490                 [[ "$new_status" =~ "f" ]] ||
6491                         error "$ost_name status is '$new_status', missing 'f'"
6492         fi
6493
6494         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6495         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6496                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6497         [[ -z "$p" ]] && restore_lustre_params < $p || true
6498         sleep_maxage
6499
6500         new_status=$(ost_dev_status $ost_idx)
6501         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6502                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6503         # can't check 'f' as devices may actually be on flash
6504 }
6505 run_test 56c "check 'lfs df' showing device status"
6506
6507 test_56d() {
6508         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6509         local osts=$($LFS df -v $MOUNT | grep -c OST)
6510
6511         $LFS df $MOUNT
6512
6513         (( mdts == MDSCOUNT )) ||
6514                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6515         (( osts == OSTCOUNT )) ||
6516                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6517 }
6518 run_test 56d "'lfs df -v' prints only configured devices"
6519
6520 test_56e() {
6521         err_enoent=2 # No such file or directory
6522         err_eopnotsupp=95 # Operation not supported
6523
6524         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6525         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6526
6527         # Check for handling of path not exists
6528         output=$($LFS df $enoent_mnt 2>&1)
6529         ret=$?
6530
6531         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6532         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6533                 error "expect failure $err_enoent, not $ret"
6534
6535         # Check for handling of non-Lustre FS
6536         output=$($LFS df $notsup_mnt)
6537         ret=$?
6538
6539         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6540         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6541                 error "expect success $err_eopnotsupp, not $ret"
6542
6543         # Check for multiple LustreFS argument
6544         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6545         ret=$?
6546
6547         [[ $output -eq 3 && $ret -eq 0 ]] ||
6548                 error "expect success 3, not $output, rc = $ret"
6549
6550         # Check for correct non-Lustre FS handling among multiple
6551         # LustreFS argument
6552         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6553                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6554         ret=$?
6555
6556         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6557                 error "expect success 2, not $output, rc = $ret"
6558 }
6559 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6560
6561 NUMFILES=3
6562 NUMDIRS=3
6563 setup_56() {
6564         local local_tdir="$1"
6565         local local_numfiles="$2"
6566         local local_numdirs="$3"
6567         local dir_params="$4"
6568         local dir_stripe_params="$5"
6569
6570         if [ ! -d "$local_tdir" ] ; then
6571                 test_mkdir -p $dir_stripe_params $local_tdir
6572                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6573                 for i in $(seq $local_numfiles) ; do
6574                         touch $local_tdir/file$i
6575                 done
6576                 for i in $(seq $local_numdirs) ; do
6577                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6578                         for j in $(seq $local_numfiles) ; do
6579                                 touch $local_tdir/dir$i/file$j
6580                         done
6581                 done
6582         fi
6583 }
6584
6585 setup_56_special() {
6586         local local_tdir=$1
6587         local local_numfiles=$2
6588         local local_numdirs=$3
6589
6590         setup_56 $local_tdir $local_numfiles $local_numdirs
6591
6592         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6593                 for i in $(seq $local_numfiles) ; do
6594                         mknod $local_tdir/loop${i}b b 7 $i
6595                         mknod $local_tdir/null${i}c c 1 3
6596                         ln -s $local_tdir/file1 $local_tdir/link${i}
6597                 done
6598                 for i in $(seq $local_numdirs) ; do
6599                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6600                         mknod $local_tdir/dir$i/null${i}c c 1 3
6601                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6602                 done
6603         fi
6604 }
6605
6606 test_56g() {
6607         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6608         local expected=$(($NUMDIRS + 2))
6609
6610         setup_56 $dir $NUMFILES $NUMDIRS
6611
6612         # test lfs find with -name
6613         for i in $(seq $NUMFILES) ; do
6614                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6615
6616                 [ $nums -eq $expected ] ||
6617                         error "lfs find -name '*$i' $dir wrong: "\
6618                               "found $nums, expected $expected"
6619         done
6620 }
6621 run_test 56g "check lfs find -name"
6622
6623 test_56h() {
6624         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6625         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6626
6627         setup_56 $dir $NUMFILES $NUMDIRS
6628
6629         # test lfs find with ! -name
6630         for i in $(seq $NUMFILES) ; do
6631                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6632
6633                 [ $nums -eq $expected ] ||
6634                         error "lfs find ! -name '*$i' $dir wrong: "\
6635                               "found $nums, expected $expected"
6636         done
6637 }
6638 run_test 56h "check lfs find ! -name"
6639
6640 test_56i() {
6641         local dir=$DIR/$tdir
6642
6643         test_mkdir $dir
6644
6645         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6646         local out=$($cmd)
6647
6648         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6649 }
6650 run_test 56i "check 'lfs find -ost UUID' skips directories"
6651
6652 test_56j() {
6653         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6654
6655         setup_56_special $dir $NUMFILES $NUMDIRS
6656
6657         local expected=$((NUMDIRS + 1))
6658         local cmd="$LFS find -type d $dir"
6659         local nums=$($cmd | wc -l)
6660
6661         [ $nums -eq $expected ] ||
6662                 error "'$cmd' wrong: found $nums, expected $expected"
6663 }
6664 run_test 56j "check lfs find -type d"
6665
6666 test_56k() {
6667         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6668
6669         setup_56_special $dir $NUMFILES $NUMDIRS
6670
6671         local expected=$(((NUMDIRS + 1) * NUMFILES))
6672         local cmd="$LFS find -type f $dir"
6673         local nums=$($cmd | wc -l)
6674
6675         [ $nums -eq $expected ] ||
6676                 error "'$cmd' wrong: found $nums, expected $expected"
6677 }
6678 run_test 56k "check lfs find -type f"
6679
6680 test_56l() {
6681         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6682
6683         setup_56_special $dir $NUMFILES $NUMDIRS
6684
6685         local expected=$((NUMDIRS + NUMFILES))
6686         local cmd="$LFS find -type b $dir"
6687         local nums=$($cmd | wc -l)
6688
6689         [ $nums -eq $expected ] ||
6690                 error "'$cmd' wrong: found $nums, expected $expected"
6691 }
6692 run_test 56l "check lfs find -type b"
6693
6694 test_56m() {
6695         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6696
6697         setup_56_special $dir $NUMFILES $NUMDIRS
6698
6699         local expected=$((NUMDIRS + NUMFILES))
6700         local cmd="$LFS find -type c $dir"
6701         local nums=$($cmd | wc -l)
6702         [ $nums -eq $expected ] ||
6703                 error "'$cmd' wrong: found $nums, expected $expected"
6704 }
6705 run_test 56m "check lfs find -type c"
6706
6707 test_56n() {
6708         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6709         setup_56_special $dir $NUMFILES $NUMDIRS
6710
6711         local expected=$((NUMDIRS + NUMFILES))
6712         local cmd="$LFS find -type l $dir"
6713         local nums=$($cmd | wc -l)
6714
6715         [ $nums -eq $expected ] ||
6716                 error "'$cmd' wrong: found $nums, expected $expected"
6717 }
6718 run_test 56n "check lfs find -type l"
6719
6720 test_56o() {
6721         local dir=$DIR/$tdir
6722
6723         setup_56 $dir $NUMFILES $NUMDIRS
6724         utime $dir/file1 > /dev/null || error "utime (1)"
6725         utime $dir/file2 > /dev/null || error "utime (2)"
6726         utime $dir/dir1 > /dev/null || error "utime (3)"
6727         utime $dir/dir2 > /dev/null || error "utime (4)"
6728         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6729         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6730
6731         local expected=4
6732         local nums=$($LFS find -mtime +0 $dir | wc -l)
6733
6734         [ $nums -eq $expected ] ||
6735                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6736
6737         expected=12
6738         cmd="$LFS find -mtime 0 $dir"
6739         nums=$($cmd | wc -l)
6740         [ $nums -eq $expected ] ||
6741                 error "'$cmd' wrong: found $nums, expected $expected"
6742 }
6743 run_test 56o "check lfs find -mtime for old files"
6744
6745 test_56ob() {
6746         local dir=$DIR/$tdir
6747         local expected=1
6748         local count=0
6749
6750         # just to make sure there is something that won't be found
6751         test_mkdir $dir
6752         touch $dir/$tfile.now
6753
6754         for age in year week day hour min; do
6755                 count=$((count + 1))
6756
6757                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6758                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6759                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6760
6761                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6762                 local nums=$($cmd | wc -l)
6763                 [ $nums -eq $expected ] ||
6764                         error "'$cmd' wrong: found $nums, expected $expected"
6765
6766                 cmd="$LFS find $dir -atime $count${age:0:1}"
6767                 nums=$($cmd | wc -l)
6768                 [ $nums -eq $expected ] ||
6769                         error "'$cmd' wrong: found $nums, expected $expected"
6770         done
6771
6772         sleep 2
6773         cmd="$LFS find $dir -ctime +1s -type f"
6774         nums=$($cmd | wc -l)
6775         (( $nums == $count * 2 + 1)) ||
6776                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6777 }
6778 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6779
6780 test_newerXY_base() {
6781         local x=$1
6782         local y=$2
6783         local dir=$DIR/$tdir
6784         local ref
6785         local negref
6786
6787         if [ $y == "t" ]; then
6788                 if [ $x == "b" ]; then
6789                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6790                 else
6791                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6792                 fi
6793         else
6794                 ref=$DIR/$tfile.newer.$x$y
6795                 touch $ref || error "touch $ref failed"
6796         fi
6797
6798         echo "before = $ref"
6799         sleep 2
6800         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6801         sleep 2
6802         if [ $y == "t" ]; then
6803                 if [ $x == "b" ]; then
6804                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6805                 else
6806                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6807                 fi
6808         else
6809                 negref=$DIR/$tfile.negnewer.$x$y
6810                 touch $negref || error "touch $negref failed"
6811         fi
6812
6813         echo "after = $negref"
6814         local cmd="$LFS find $dir -newer$x$y $ref"
6815         local nums=$(eval $cmd | wc -l)
6816         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6817
6818         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6819                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6820
6821         cmd="$LFS find $dir ! -newer$x$y $negref"
6822         nums=$(eval $cmd | wc -l)
6823         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6824                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6825
6826         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6827         nums=$(eval $cmd | wc -l)
6828         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6829                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6830
6831         rm -rf $DIR/*
6832 }
6833
6834 test_56oc() {
6835         test_newerXY_base "a" "a"
6836         test_newerXY_base "a" "m"
6837         test_newerXY_base "a" "c"
6838         test_newerXY_base "m" "a"
6839         test_newerXY_base "m" "m"
6840         test_newerXY_base "m" "c"
6841         test_newerXY_base "c" "a"
6842         test_newerXY_base "c" "m"
6843         test_newerXY_base "c" "c"
6844
6845         test_newerXY_base "a" "t"
6846         test_newerXY_base "m" "t"
6847         test_newerXY_base "c" "t"
6848
6849         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6850            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6851                 ! btime_supported && echo "btime unsupported" && return 0
6852
6853         test_newerXY_base "b" "b"
6854         test_newerXY_base "b" "t"
6855 }
6856 run_test 56oc "check lfs find -newerXY work"
6857
6858 btime_supported() {
6859         local dir=$DIR/$tdir
6860         local rc
6861
6862         mkdir -p $dir
6863         touch $dir/$tfile
6864         $LFS find $dir -btime -1d -type f
6865         rc=$?
6866         rm -rf $dir
6867         return $rc
6868 }
6869
6870 test_56od() {
6871         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6872                 ! btime_supported && skip "btime unsupported on MDS"
6873
6874         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6875                 ! btime_supported && skip "btime unsupported on clients"
6876
6877         local dir=$DIR/$tdir
6878         local ref=$DIR/$tfile.ref
6879         local negref=$DIR/$tfile.negref
6880
6881         mkdir $dir || error "mkdir $dir failed"
6882         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6883         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6884         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6885         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6886         touch $ref || error "touch $ref failed"
6887         # sleep 3 seconds at least
6888         sleep 3
6889
6890         local before=$(do_facet mds1 date +%s)
6891         local skew=$(($(date +%s) - before + 1))
6892
6893         if (( skew < 0 && skew > -5 )); then
6894                 sleep $((0 - skew + 1))
6895                 skew=0
6896         fi
6897
6898         # Set the dir stripe params to limit files all on MDT0,
6899         # otherwise we need to calc the max clock skew between
6900         # the client and MDTs.
6901         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6902         sleep 2
6903         touch $negref || error "touch $negref failed"
6904
6905         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6906         local nums=$($cmd | wc -l)
6907         local expected=$(((NUMFILES + 1) * NUMDIRS))
6908
6909         [ $nums -eq $expected ] ||
6910                 error "'$cmd' wrong: found $nums, expected $expected"
6911
6912         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6913         nums=$($cmd | wc -l)
6914         expected=$((NUMFILES + 1))
6915         [ $nums -eq $expected ] ||
6916                 error "'$cmd' wrong: found $nums, expected $expected"
6917
6918         [ $skew -lt 0 ] && return
6919
6920         local after=$(do_facet mds1 date +%s)
6921         local age=$((after - before + 1 + skew))
6922
6923         cmd="$LFS find $dir -btime -${age}s -type f"
6924         nums=$($cmd | wc -l)
6925         expected=$(((NUMFILES + 1) * NUMDIRS))
6926
6927         echo "Clock skew between client and server: $skew, age:$age"
6928         [ $nums -eq $expected ] ||
6929                 error "'$cmd' wrong: found $nums, expected $expected"
6930
6931         expected=$(($NUMDIRS + 1))
6932         cmd="$LFS find $dir -btime -${age}s -type d"
6933         nums=$($cmd | wc -l)
6934         [ $nums -eq $expected ] ||
6935                 error "'$cmd' wrong: found $nums, expected $expected"
6936         rm -f $ref $negref || error "Failed to remove $ref $negref"
6937 }
6938 run_test 56od "check lfs find -btime with units"
6939
6940 test_56p() {
6941         [ $RUNAS_ID -eq $UID ] &&
6942                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6943
6944         local dir=$DIR/$tdir
6945
6946         setup_56 $dir $NUMFILES $NUMDIRS
6947         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6948
6949         local expected=$NUMFILES
6950         local cmd="$LFS find -uid $RUNAS_ID $dir"
6951         local nums=$($cmd | wc -l)
6952
6953         [ $nums -eq $expected ] ||
6954                 error "'$cmd' wrong: found $nums, expected $expected"
6955
6956         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6957         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6958         nums=$($cmd | wc -l)
6959         [ $nums -eq $expected ] ||
6960                 error "'$cmd' wrong: found $nums, expected $expected"
6961 }
6962 run_test 56p "check lfs find -uid and ! -uid"
6963
6964 test_56q() {
6965         [ $RUNAS_ID -eq $UID ] &&
6966                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6967
6968         local dir=$DIR/$tdir
6969
6970         setup_56 $dir $NUMFILES $NUMDIRS
6971         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6972
6973         local expected=$NUMFILES
6974         local cmd="$LFS find -gid $RUNAS_GID $dir"
6975         local nums=$($cmd | wc -l)
6976
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979
6980         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6981         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6982         nums=$($cmd | wc -l)
6983         [ $nums -eq $expected ] ||
6984                 error "'$cmd' wrong: found $nums, expected $expected"
6985 }
6986 run_test 56q "check lfs find -gid and ! -gid"
6987
6988 test_56r() {
6989         local dir=$DIR/$tdir
6990
6991         setup_56 $dir $NUMFILES $NUMDIRS
6992
6993         local expected=12
6994         local cmd="$LFS find -size 0 -type f -lazy $dir"
6995         local nums=$($cmd | wc -l)
6996
6997         [ $nums -eq $expected ] ||
6998                 error "'$cmd' wrong: found $nums, expected $expected"
6999         cmd="$LFS find -size 0 -type f $dir"
7000         nums=$($cmd | wc -l)
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003
7004         expected=0
7005         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7006         nums=$($cmd | wc -l)
7007         [ $nums -eq $expected ] ||
7008                 error "'$cmd' wrong: found $nums, expected $expected"
7009         cmd="$LFS find ! -size 0 -type f $dir"
7010         nums=$($cmd | wc -l)
7011         [ $nums -eq $expected ] ||
7012                 error "'$cmd' wrong: found $nums, expected $expected"
7013
7014         echo "test" > $dir/$tfile
7015         echo "test2" > $dir/$tfile.2 && sync
7016         expected=1
7017         cmd="$LFS find -size 5 -type f -lazy $dir"
7018         nums=$($cmd | wc -l)
7019         [ $nums -eq $expected ] ||
7020                 error "'$cmd' wrong: found $nums, expected $expected"
7021         cmd="$LFS find -size 5 -type f $dir"
7022         nums=$($cmd | wc -l)
7023         [ $nums -eq $expected ] ||
7024                 error "'$cmd' wrong: found $nums, expected $expected"
7025
7026         expected=1
7027         cmd="$LFS find -size +5 -type f -lazy $dir"
7028         nums=$($cmd | wc -l)
7029         [ $nums -eq $expected ] ||
7030                 error "'$cmd' wrong: found $nums, expected $expected"
7031         cmd="$LFS find -size +5 -type f $dir"
7032         nums=$($cmd | wc -l)
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035
7036         expected=2
7037         cmd="$LFS find -size +0 -type f -lazy $dir"
7038         nums=$($cmd | wc -l)
7039         [ $nums -eq $expected ] ||
7040                 error "'$cmd' wrong: found $nums, expected $expected"
7041         cmd="$LFS find -size +0 -type f $dir"
7042         nums=$($cmd | wc -l)
7043         [ $nums -eq $expected ] ||
7044                 error "'$cmd' wrong: found $nums, expected $expected"
7045
7046         expected=2
7047         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7048         nums=$($cmd | wc -l)
7049         [ $nums -eq $expected ] ||
7050                 error "'$cmd' wrong: found $nums, expected $expected"
7051         cmd="$LFS find ! -size -5 -type f $dir"
7052         nums=$($cmd | wc -l)
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055
7056         expected=12
7057         cmd="$LFS find -size -5 -type f -lazy $dir"
7058         nums=$($cmd | wc -l)
7059         [ $nums -eq $expected ] ||
7060                 error "'$cmd' wrong: found $nums, expected $expected"
7061         cmd="$LFS find -size -5 -type f $dir"
7062         nums=$($cmd | wc -l)
7063         [ $nums -eq $expected ] ||
7064                 error "'$cmd' wrong: found $nums, expected $expected"
7065 }
7066 run_test 56r "check lfs find -size works"
7067
7068 test_56ra_sub() {
7069         local expected=$1
7070         local glimpses=$2
7071         local cmd="$3"
7072
7073         cancel_lru_locks $OSC
7074
7075         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7076         local nums=$($cmd | wc -l)
7077
7078         [ $nums -eq $expected ] ||
7079                 error "'$cmd' wrong: found $nums, expected $expected"
7080
7081         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7082
7083         if (( rpcs_before + glimpses != rpcs_after )); then
7084                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7085                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7086
7087                 if [[ $glimpses == 0 ]]; then
7088                         error "'$cmd' should not send glimpse RPCs to OST"
7089                 else
7090                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7091                 fi
7092         fi
7093 }
7094
7095 test_56ra() {
7096         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7097                 skip "MDS < 2.12.58 doesn't return LSOM data"
7098         local dir=$DIR/$tdir
7099         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7100
7101         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7102
7103         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7104         $LCTL set_param -n llite.*.statahead_agl=0
7105         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7106
7107         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7108         # open and close all files to ensure LSOM is updated
7109         cancel_lru_locks $OSC
7110         find $dir -type f | xargs cat > /dev/null
7111
7112         #   expect_found  glimpse_rpcs  command_to_run
7113         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7114         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7115         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7116         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7117
7118         echo "test" > $dir/$tfile
7119         echo "test2" > $dir/$tfile.2 && sync
7120         cancel_lru_locks $OSC
7121         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7122
7123         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7124         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7125         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7126         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7127
7128         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7129         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7130         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7131         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7132         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7133         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7134 }
7135 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7136
7137 test_56rb() {
7138         local dir=$DIR/$tdir
7139         local tmp=$TMP/$tfile.log
7140         local mdt_idx;
7141
7142         test_mkdir -p $dir || error "failed to mkdir $dir"
7143         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7144                 error "failed to setstripe $dir/$tfile"
7145         mdt_idx=$($LFS getdirstripe -i $dir)
7146         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7147
7148         stack_trap "rm -f $tmp" EXIT
7149         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7150         ! grep -q obd_uuid $tmp ||
7151                 error "failed to find --size +100K --ost 0 $dir"
7152         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7153         ! grep -q obd_uuid $tmp ||
7154                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7155 }
7156 run_test 56rb "check lfs find --size --ost/--mdt works"
7157
7158 test_56rc() {
7159         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7160         local dir=$DIR/$tdir
7161         local found
7162
7163         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7164         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7165         (( $MDSCOUNT > 2 )) &&
7166                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7167         mkdir $dir/$tdir-{1..10}
7168         touch $dir/$tfile-{1..10}
7169
7170         found=$($LFS find $dir --mdt-count 2 | wc -l)
7171         expect=11
7172         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7173
7174         found=$($LFS find $dir -T +1 | wc -l)
7175         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7176         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7177
7178         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7179         expect=11
7180         (( $found == $expect )) || error "found $found all_char, expect $expect"
7181
7182         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7183         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7184         (( $found == $expect )) || error "found $found all_char, expect $expect"
7185 }
7186 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7187
7188 test_56s() { # LU-611 #LU-9369
7189         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7190
7191         local dir=$DIR/$tdir
7192         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7193
7194         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7195         for i in $(seq $NUMDIRS); do
7196                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7197         done
7198
7199         local expected=$NUMDIRS
7200         local cmd="$LFS find -c $OSTCOUNT $dir"
7201         local nums=$($cmd | wc -l)
7202
7203         [ $nums -eq $expected ] || {
7204                 $LFS getstripe -R $dir
7205                 error "'$cmd' wrong: found $nums, expected $expected"
7206         }
7207
7208         expected=$((NUMDIRS + onestripe))
7209         cmd="$LFS find -stripe-count +0 -type f $dir"
7210         nums=$($cmd | wc -l)
7211         [ $nums -eq $expected ] || {
7212                 $LFS getstripe -R $dir
7213                 error "'$cmd' wrong: found $nums, expected $expected"
7214         }
7215
7216         expected=$onestripe
7217         cmd="$LFS find -stripe-count 1 -type f $dir"
7218         nums=$($cmd | wc -l)
7219         [ $nums -eq $expected ] || {
7220                 $LFS getstripe -R $dir
7221                 error "'$cmd' wrong: found $nums, expected $expected"
7222         }
7223
7224         cmd="$LFS find -stripe-count -2 -type f $dir"
7225         nums=$($cmd | wc -l)
7226         [ $nums -eq $expected ] || {
7227                 $LFS getstripe -R $dir
7228                 error "'$cmd' wrong: found $nums, expected $expected"
7229         }
7230
7231         expected=0
7232         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7233         nums=$($cmd | wc -l)
7234         [ $nums -eq $expected ] || {
7235                 $LFS getstripe -R $dir
7236                 error "'$cmd' wrong: found $nums, expected $expected"
7237         }
7238 }
7239 run_test 56s "check lfs find -stripe-count works"
7240
7241 test_56t() { # LU-611 #LU-9369
7242         local dir=$DIR/$tdir
7243
7244         setup_56 $dir 0 $NUMDIRS
7245         for i in $(seq $NUMDIRS); do
7246                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7247         done
7248
7249         local expected=$NUMDIRS
7250         local cmd="$LFS find -S 8M $dir"
7251         local nums=$($cmd | wc -l)
7252
7253         [ $nums -eq $expected ] || {
7254                 $LFS getstripe -R $dir
7255                 error "'$cmd' wrong: found $nums, expected $expected"
7256         }
7257         rm -rf $dir
7258
7259         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7260
7261         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7262
7263         expected=$(((NUMDIRS + 1) * NUMFILES))
7264         cmd="$LFS find -stripe-size 512k -type f $dir"
7265         nums=$($cmd | wc -l)
7266         [ $nums -eq $expected ] ||
7267                 error "'$cmd' wrong: found $nums, expected $expected"
7268
7269         cmd="$LFS find -stripe-size +320k -type f $dir"
7270         nums=$($cmd | wc -l)
7271         [ $nums -eq $expected ] ||
7272                 error "'$cmd' wrong: found $nums, expected $expected"
7273
7274         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7275         cmd="$LFS find -stripe-size +200k -type f $dir"
7276         nums=$($cmd | wc -l)
7277         [ $nums -eq $expected ] ||
7278                 error "'$cmd' wrong: found $nums, expected $expected"
7279
7280         cmd="$LFS find -stripe-size -640k -type f $dir"
7281         nums=$($cmd | wc -l)
7282         [ $nums -eq $expected ] ||
7283                 error "'$cmd' wrong: found $nums, expected $expected"
7284
7285         expected=4
7286         cmd="$LFS find -stripe-size 256k -type f $dir"
7287         nums=$($cmd | wc -l)
7288         [ $nums -eq $expected ] ||
7289                 error "'$cmd' wrong: found $nums, expected $expected"
7290
7291         cmd="$LFS find -stripe-size -320k -type f $dir"
7292         nums=$($cmd | wc -l)
7293         [ $nums -eq $expected ] ||
7294                 error "'$cmd' wrong: found $nums, expected $expected"
7295
7296         expected=0
7297         cmd="$LFS find -stripe-size 1024k -type f $dir"
7298         nums=$($cmd | wc -l)
7299         [ $nums -eq $expected ] ||
7300                 error "'$cmd' wrong: found $nums, expected $expected"
7301 }
7302 run_test 56t "check lfs find -stripe-size works"
7303
7304 test_56u() { # LU-611
7305         local dir=$DIR/$tdir
7306
7307         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7308
7309         if [[ $OSTCOUNT -gt 1 ]]; then
7310                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7311                 onestripe=4
7312         else
7313                 onestripe=0
7314         fi
7315
7316         local expected=$(((NUMDIRS + 1) * NUMFILES))
7317         local cmd="$LFS find -stripe-index 0 -type f $dir"
7318         local nums=$($cmd | wc -l)
7319
7320         [ $nums -eq $expected ] ||
7321                 error "'$cmd' wrong: found $nums, expected $expected"
7322
7323         expected=$onestripe
7324         cmd="$LFS find -stripe-index 1 -type f $dir"
7325         nums=$($cmd | wc -l)
7326         [ $nums -eq $expected ] ||
7327                 error "'$cmd' wrong: found $nums, expected $expected"
7328
7329         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7330         nums=$($cmd | wc -l)
7331         [ $nums -eq $expected ] ||
7332                 error "'$cmd' wrong: found $nums, expected $expected"
7333
7334         expected=0
7335         # This should produce an error and not return any files
7336         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7337         nums=$($cmd 2>/dev/null | wc -l)
7338         [ $nums -eq $expected ] ||
7339                 error "'$cmd' wrong: found $nums, expected $expected"
7340
7341         if [[ $OSTCOUNT -gt 1 ]]; then
7342                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7343                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7344                 nums=$($cmd | wc -l)
7345                 [ $nums -eq $expected ] ||
7346                         error "'$cmd' wrong: found $nums, expected $expected"
7347         fi
7348 }
7349 run_test 56u "check lfs find -stripe-index works"
7350
7351 test_56v() {
7352         local mdt_idx=0
7353         local dir=$DIR/$tdir
7354
7355         setup_56 $dir $NUMFILES $NUMDIRS
7356
7357         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7358         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7359
7360         for file in $($LFS find -m $UUID $dir); do
7361                 file_midx=$($LFS getstripe -m $file)
7362                 [ $file_midx -eq $mdt_idx ] ||
7363                         error "lfs find -m $UUID != getstripe -m $file_midx"
7364         done
7365 }
7366 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7367
7368 test_56wa() {
7369         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7371
7372         local dir=$DIR/$tdir
7373
7374         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7375
7376         local stripe_size=$($LFS getstripe -S -d $dir) ||
7377                 error "$LFS getstripe -S -d $dir failed"
7378         stripe_size=${stripe_size%% *}
7379
7380         local file_size=$((stripe_size * OSTCOUNT))
7381         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7382         local required_space=$((file_num * file_size))
7383         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7384                            head -n1)
7385         (( free_space >= required_space / 1024 )) ||
7386                 skip_env "need $required_space, have $free_space kbytes"
7387
7388         local dd_bs=65536
7389         local dd_count=$((file_size / dd_bs))
7390
7391         # write data into the files
7392         local i
7393         local j
7394         local file
7395
7396         for ((i = 1; i <= NUMFILES; i++ )); do
7397                 file=$dir/file$i
7398                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7399                         error "write data into $file failed"
7400         done
7401         for ((i = 1; i <= NUMDIRS; i++ )); do
7402                 for ((j = 1; j <= NUMFILES; j++ )); do
7403                         file=$dir/dir$i/file$j
7404                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7405                                 error "write data into $file failed"
7406                 done
7407         done
7408
7409         # $LFS_MIGRATE will fail if hard link migration is unsupported
7410         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7411                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7412                         error "creating links to $dir/dir1/file1 failed"
7413         fi
7414
7415         local expected=-1
7416
7417         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7418
7419         # lfs_migrate file
7420         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7421
7422         echo "$cmd"
7423         eval $cmd || error "$cmd failed"
7424
7425         check_stripe_count $dir/file1 $expected
7426
7427         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7428                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7429                 # OST 1 if it is on OST 0. This file is small enough to
7430                 # be on only one stripe.
7431                 file=$dir/migr_1_ost
7432                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7433                         error "write data into $file failed"
7434                 local obdidx=$($LFS getstripe -i $file)
7435                 local oldmd5=$(md5sum $file)
7436                 local newobdidx=0
7437
7438                 (( obdidx != 0 )) || newobdidx=1
7439                 cmd="$LFS migrate -i $newobdidx $file"
7440                 echo $cmd
7441                 eval $cmd || error "$cmd failed"
7442
7443                 local realobdix=$($LFS getstripe -i $file)
7444                 local newmd5=$(md5sum $file)
7445
7446                 (( $newobdidx == $realobdix )) ||
7447                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7448                 [[ "$oldmd5" == "$newmd5" ]] ||
7449                         error "md5sum differ: $oldmd5, $newmd5"
7450         fi
7451
7452         # lfs_migrate dir
7453         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7454         echo "$cmd"
7455         eval $cmd || error "$cmd failed"
7456
7457         for (( j = 1; j <= NUMFILES; j++ )); do
7458                 check_stripe_count $dir/dir1/file$j $expected
7459         done
7460
7461         # lfs_migrate works with lfs find
7462         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7463              $LFS_MIGRATE -y -c $expected"
7464         echo "$cmd"
7465         eval $cmd || error "$cmd failed"
7466
7467         for (( i = 2; i <= NUMFILES; i++ )); do
7468                 check_stripe_count $dir/file$i $expected
7469         done
7470         for (( i = 2; i <= NUMDIRS; i++ )); do
7471                 for (( j = 1; j <= NUMFILES; j++ )); do
7472                         check_stripe_count $dir/dir$i/file$j $expected
7473                 done
7474         done
7475 }
7476 run_test 56wa "check lfs_migrate -c stripe_count works"
7477
7478 test_56wb() {
7479         local file1=$DIR/$tdir/file1
7480         local create_pool=false
7481         local initial_pool=$($LFS getstripe -p $DIR)
7482         local pool_list=()
7483         local pool=""
7484
7485         echo -n "Creating test dir..."
7486         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7487         echo "done."
7488
7489         echo -n "Creating test file..."
7490         touch $file1 || error "cannot create file"
7491         echo "done."
7492
7493         echo -n "Detecting existing pools..."
7494         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7495
7496         if [ ${#pool_list[@]} -gt 0 ]; then
7497                 echo "${pool_list[@]}"
7498                 for thispool in "${pool_list[@]}"; do
7499                         if [[ -z "$initial_pool" ||
7500                               "$initial_pool" != "$thispool" ]]; then
7501                                 pool="$thispool"
7502                                 echo "Using existing pool '$pool'"
7503                                 break
7504                         fi
7505                 done
7506         else
7507                 echo "none detected."
7508         fi
7509         if [ -z "$pool" ]; then
7510                 pool=${POOL:-testpool}
7511                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7512                 echo -n "Creating pool '$pool'..."
7513                 create_pool=true
7514                 pool_add $pool &> /dev/null ||
7515                         error "pool_add failed"
7516                 echo "done."
7517
7518                 echo -n "Adding target to pool..."
7519                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7520                         error "pool_add_targets failed"
7521                 echo "done."
7522         fi
7523
7524         echo -n "Setting pool using -p option..."
7525         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7526                 error "migrate failed rc = $?"
7527         echo "done."
7528
7529         echo -n "Verifying test file is in pool after migrating..."
7530         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7531                 error "file was not migrated to pool $pool"
7532         echo "done."
7533
7534         echo -n "Removing test file from pool '$pool'..."
7535         # "lfs migrate $file" won't remove the file from the pool
7536         # until some striping information is changed.
7537         $LFS migrate -c 1 $file1 &> /dev/null ||
7538                 error "cannot remove from pool"
7539         [ "$($LFS getstripe -p $file1)" ] &&
7540                 error "pool still set"
7541         echo "done."
7542
7543         echo -n "Setting pool using --pool option..."
7544         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7545                 error "migrate failed rc = $?"
7546         echo "done."
7547
7548         # Clean up
7549         rm -f $file1
7550         if $create_pool; then
7551                 destroy_test_pools 2> /dev/null ||
7552                         error "destroy test pools failed"
7553         fi
7554 }
7555 run_test 56wb "check lfs_migrate pool support"
7556
7557 test_56wc() {
7558         local file1="$DIR/$tdir/$tfile"
7559         local md5
7560         local parent_ssize
7561         local parent_scount
7562         local cur_ssize
7563         local cur_scount
7564         local orig_ssize
7565         local new_scount
7566         local cur_comp
7567
7568         echo -n "Creating test dir..."
7569         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7570         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7571                 error "cannot set stripe by '-S 1M -c 1'"
7572         echo "done"
7573
7574         echo -n "Setting initial stripe for test file..."
7575         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7576                 error "cannot set stripe"
7577         cur_ssize=$($LFS getstripe -S "$file1")
7578         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7579         echo "done."
7580
7581         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7582         stack_trap "rm -f $file1"
7583         md5="$(md5sum $file1)"
7584
7585         # File currently set to -S 512K -c 1
7586
7587         # Ensure -c and -S options are rejected when -R is set
7588         echo -n "Verifying incompatible options are detected..."
7589         $LFS_MIGRATE -R -c 1 "$file1" &&
7590                 error "incompatible -R and -c options not detected"
7591         $LFS_MIGRATE -R -S 1M "$file1" &&
7592                 error "incompatible -R and -S options not detected"
7593         $LFS_MIGRATE -R -p pool "$file1" &&
7594                 error "incompatible -R and -p options not detected"
7595         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7596                 error "incompatible -R and -E options not detected"
7597         $LFS_MIGRATE -R -A "$file1" &&
7598                 error "incompatible -R and -A options not detected"
7599         $LFS_MIGRATE -A -c 1 "$file1" &&
7600                 error "incompatible -A and -c options not detected"
7601         $LFS_MIGRATE -A -S 1M "$file1" &&
7602                 error "incompatible -A and -S options not detected"
7603         $LFS_MIGRATE -A -p pool "$file1" &&
7604                 error "incompatible -A and -p options not detected"
7605         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7606                 error "incompatible -A and -E options not detected"
7607         echo "done."
7608
7609         # Ensure unrecognized options are passed through to 'lfs migrate'
7610         echo -n "Verifying -S option is passed through to lfs migrate..."
7611         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7612         cur_ssize=$($LFS getstripe -S "$file1")
7613         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7614         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7615         echo "done."
7616
7617         # File currently set to -S 1M -c 1
7618
7619         # Ensure long options are supported
7620         echo -n "Verifying long options supported..."
7621         $LFS_MIGRATE --non-block "$file1" ||
7622                 error "long option without argument not supported"
7623         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7624                 error "long option with argument not supported"
7625         cur_ssize=$($LFS getstripe -S "$file1")
7626         (( cur_ssize == 524288 )) ||
7627                 error "migrate --stripe-size $cur_ssize != 524288"
7628         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7629         echo "done."
7630
7631         # File currently set to -S 512K -c 1
7632
7633         if (( OSTCOUNT > 1 )); then
7634                 echo -n "Verifying explicit stripe count can be set..."
7635                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7636                 cur_scount=$($LFS getstripe -c "$file1")
7637                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7638                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7639                         error "file data has changed (3)"
7640                 echo "done."
7641         fi
7642
7643         # File currently set to -S 512K -c 1 or -S 512K -c 2
7644
7645         # Ensure parent striping is used if -R is set, and no stripe
7646         # count or size is specified
7647         echo -n "Setting stripe for parent directory..."
7648         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7649                 error "cannot set stripe '-S 2M -c 1'"
7650         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7651         echo "done."
7652
7653         echo -n "Verifying restripe option uses parent stripe settings..."
7654         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7655         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7656         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7657         cur_ssize=$($LFS getstripe -S "$file1")
7658         (( cur_ssize == parent_ssize )) ||
7659                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7660         cur_scount=$($LFS getstripe -c "$file1")
7661         (( cur_scount == parent_scount )) ||
7662                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7663         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7664         echo "done."
7665
7666         # File currently set to -S 1M -c 1
7667
7668         # Ensure striping is preserved if -R is not set, and no stripe
7669         # count or size is specified
7670         echo -n "Verifying striping size preserved when not specified..."
7671         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7672         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7673                 error "cannot set stripe on parent directory"
7674         $LFS_MIGRATE "$file1" || error "migrate failed"
7675         cur_ssize=$($LFS getstripe -S "$file1")
7676         (( cur_ssize == orig_ssize )) ||
7677                 error "migrate by default $cur_ssize != $orig_ssize"
7678         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7679         echo "done."
7680
7681         # Ensure file name properly detected when final option has no argument
7682         echo -n "Verifying file name properly detected..."
7683         $LFS_MIGRATE "$file1" ||
7684                 error "file name interpreted as option argument"
7685         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7686         echo "done."
7687
7688         # Ensure PFL arguments are passed through properly
7689         echo -n "Verifying PFL options passed through..."
7690         new_scount=$(((OSTCOUNT + 1) / 2))
7691         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7692                 error "migrate PFL arguments failed"
7693         cur_comp=$($LFS getstripe --comp-count $file1)
7694         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7695         cur_scount=$($LFS getstripe --stripe-count $file1)
7696         (( cur_scount == new_scount)) ||
7697                 error "PFL stripe count $cur_scount != $new_scount"
7698         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7699         echo "done."
7700 }
7701 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7702
7703 test_56wd() {
7704         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7705
7706         local file1=$DIR/$tdir/$tfile
7707
7708         echo -n "Creating test dir..."
7709         test_mkdir $DIR/$tdir || error "cannot create dir"
7710         echo "done."
7711
7712         echo -n "Creating test file..."
7713         echo "$tfile" > $file1
7714         echo "done."
7715
7716         # Ensure 'lfs migrate' will fail by using a non-existent option,
7717         # and make sure rsync is not called to recover
7718         echo -n "Make sure --no-rsync option works..."
7719         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7720                 grep -q 'refusing to fall back to rsync' ||
7721                 error "rsync was called with --no-rsync set"
7722         echo "done."
7723
7724         # Ensure rsync is called without trying 'lfs migrate' first
7725         echo -n "Make sure --rsync option works..."
7726         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7727                 grep -q 'falling back to rsync' &&
7728                 error "lfs migrate was called with --rsync set"
7729         echo "done."
7730 }
7731 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7732
7733 test_56we() {
7734         local td=$DIR/$tdir
7735         local tf=$td/$tfile
7736
7737         test_mkdir $td || error "cannot create $td"
7738         touch $tf || error "cannot touch $tf"
7739
7740         echo -n "Make sure --non-direct|-D works..."
7741         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7742                 grep -q "lfs migrate --non-direct" ||
7743                 error "--non-direct option cannot work correctly"
7744         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7745                 grep -q "lfs migrate -D" ||
7746                 error "-D option cannot work correctly"
7747         echo "done."
7748 }
7749 run_test 56we "check lfs_migrate --non-direct|-D support"
7750
7751 test_56x() {
7752         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7753         check_swap_layouts_support
7754
7755         local dir=$DIR/$tdir
7756         local ref1=/etc/passwd
7757         local file1=$dir/file1
7758
7759         test_mkdir $dir || error "creating dir $dir"
7760         $LFS setstripe -c 2 $file1
7761         cp $ref1 $file1
7762         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7763         stripe=$($LFS getstripe -c $file1)
7764         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7765         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7766
7767         # clean up
7768         rm -f $file1
7769 }
7770 run_test 56x "lfs migration support"
7771
7772 test_56xa() {
7773         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7774         check_swap_layouts_support
7775
7776         local dir=$DIR/$tdir/$testnum
7777
7778         test_mkdir -p $dir
7779
7780         local ref1=/etc/passwd
7781         local file1=$dir/file1
7782
7783         $LFS setstripe -c 2 $file1
7784         cp $ref1 $file1
7785         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7786
7787         local stripe=$($LFS getstripe -c $file1)
7788
7789         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7790         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7791
7792         # clean up
7793         rm -f $file1
7794 }
7795 run_test 56xa "lfs migration --block support"
7796
7797 check_migrate_links() {
7798         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7799         local dir="$1"
7800         local file1="$dir/file1"
7801         local begin="$2"
7802         local count="$3"
7803         local runas="$4"
7804         local total_count=$(($begin + $count - 1))
7805         local symlink_count=10
7806         local uniq_count=10
7807
7808         if [ ! -f "$file1" ]; then
7809                 echo -n "creating initial file..."
7810                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7811                         error "cannot setstripe initial file"
7812                 echo "done"
7813
7814                 echo -n "creating symlinks..."
7815                 for s in $(seq 1 $symlink_count); do
7816                         ln -s "$file1" "$dir/slink$s" ||
7817                                 error "cannot create symlinks"
7818                 done
7819                 echo "done"
7820
7821                 echo -n "creating nonlinked files..."
7822                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7823                         error "cannot create nonlinked files"
7824                 echo "done"
7825         fi
7826
7827         # create hard links
7828         if [ ! -f "$dir/file$total_count" ]; then
7829                 echo -n "creating hard links $begin:$total_count..."
7830                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7831                         /dev/null || error "cannot create hard links"
7832                 echo "done"
7833         fi
7834
7835         echo -n "checking number of hard links listed in xattrs..."
7836         local fid=$($LFS getstripe -F "$file1")
7837         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7838
7839         echo "${#paths[*]}"
7840         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7841                         skip "hard link list has unexpected size, skipping test"
7842         fi
7843         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7844                         error "link names should exceed xattrs size"
7845         fi
7846
7847         echo -n "migrating files..."
7848         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7849         local rc=$?
7850         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7851         echo "done"
7852
7853         # make sure all links have been properly migrated
7854         echo -n "verifying files..."
7855         fid=$($LFS getstripe -F "$file1") ||
7856                 error "cannot get fid for file $file1"
7857         for i in $(seq 2 $total_count); do
7858                 local fid2=$($LFS getstripe -F $dir/file$i)
7859
7860                 [ "$fid2" == "$fid" ] ||
7861                         error "migrated hard link has mismatched FID"
7862         done
7863
7864         # make sure hard links were properly detected, and migration was
7865         # performed only once for the entire link set; nonlinked files should
7866         # also be migrated
7867         local actual=$(grep -c 'done' <<< "$migrate_out")
7868         local expected=$(($uniq_count + 1))
7869
7870         [ "$actual" -eq  "$expected" ] ||
7871                 error "hard links individually migrated ($actual != $expected)"
7872
7873         # make sure the correct number of hard links are present
7874         local hardlinks=$(stat -c '%h' "$file1")
7875
7876         [ $hardlinks -eq $total_count ] ||
7877                 error "num hard links $hardlinks != $total_count"
7878         echo "done"
7879
7880         return 0
7881 }
7882
7883 test_56xb() {
7884         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7885                 skip "Need MDS version at least 2.10.55"
7886
7887         local dir="$DIR/$tdir"
7888
7889         test_mkdir "$dir" || error "cannot create dir $dir"
7890
7891         echo "testing lfs migrate mode when all links fit within xattrs"
7892         check_migrate_links "$dir" 2 99
7893
7894         echo "testing rsync mode when all links fit within xattrs"
7895         check_migrate_links --rsync "$dir" 2 99
7896
7897         echo "testing lfs migrate mode when all links do not fit within xattrs"
7898         check_migrate_links "$dir" 101 100
7899
7900         echo "testing rsync mode when all links do not fit within xattrs"
7901         check_migrate_links --rsync "$dir" 101 100
7902
7903         chown -R $RUNAS_ID $dir
7904         echo "testing non-root lfs migrate mode when not all links are in xattr"
7905         check_migrate_links "$dir" 101 100 "$RUNAS"
7906
7907         # clean up
7908         rm -rf $dir
7909 }
7910 run_test 56xb "lfs migration hard link support"
7911
7912 test_56xc() {
7913         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7914
7915         local dir="$DIR/$tdir"
7916
7917         test_mkdir "$dir" || error "cannot create dir $dir"
7918
7919         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7920         echo -n "Setting initial stripe for 20MB test file..."
7921         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7922                 error "cannot setstripe 20MB file"
7923         echo "done"
7924         echo -n "Sizing 20MB test file..."
7925         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7926         echo "done"
7927         echo -n "Verifying small file autostripe count is 1..."
7928         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7929                 error "cannot migrate 20MB file"
7930         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7931                 error "cannot get stripe for $dir/20mb"
7932         [ $stripe_count -eq 1 ] ||
7933                 error "unexpected stripe count $stripe_count for 20MB file"
7934         rm -f "$dir/20mb"
7935         echo "done"
7936
7937         # Test 2: File is small enough to fit within the available space on
7938         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7939         # have at least an additional 1KB for each desired stripe for test 3
7940         echo -n "Setting stripe for 1GB test file..."
7941         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7942         echo "done"
7943         echo -n "Sizing 1GB test file..."
7944         # File size is 1GB + 3KB
7945         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7946         echo "done"
7947
7948         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7949         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7950         if (( avail > 524288 * OSTCOUNT )); then
7951                 echo -n "Migrating 1GB file..."
7952                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7953                         error "cannot migrate 1GB file"
7954                 echo "done"
7955                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7956                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7957                         error "cannot getstripe for 1GB file"
7958                 [ $stripe_count -eq 2 ] ||
7959                         error "unexpected stripe count $stripe_count != 2"
7960                 echo "done"
7961         fi
7962
7963         # Test 3: File is too large to fit within the available space on
7964         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7965         if [ $OSTCOUNT -ge 3 ]; then
7966                 # The required available space is calculated as
7967                 # file size (1GB + 3KB) / OST count (3).
7968                 local kb_per_ost=349526
7969
7970                 echo -n "Migrating 1GB file with limit..."
7971                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7972                         error "cannot migrate 1GB file with limit"
7973                 echo "done"
7974
7975                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7976                 echo -n "Verifying 1GB autostripe count with limited space..."
7977                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7978                         error "unexpected stripe count $stripe_count (min 3)"
7979                 echo "done"
7980         fi
7981
7982         # clean up
7983         rm -rf $dir
7984 }
7985 run_test 56xc "lfs migration autostripe"
7986
7987 test_56xd() {
7988         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7989
7990         local dir=$DIR/$tdir
7991         local f_mgrt=$dir/$tfile.mgrt
7992         local f_yaml=$dir/$tfile.yaml
7993         local f_copy=$dir/$tfile.copy
7994         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7995         local layout_copy="-c 2 -S 2M -i 1"
7996         local yamlfile=$dir/yamlfile
7997         local layout_before;
7998         local layout_after;
7999
8000         test_mkdir "$dir" || error "cannot create dir $dir"
8001         $LFS setstripe $layout_yaml $f_yaml ||
8002                 error "cannot setstripe $f_yaml with layout $layout_yaml"
8003         $LFS getstripe --yaml $f_yaml > $yamlfile
8004         $LFS setstripe $layout_copy $f_copy ||
8005                 error "cannot setstripe $f_copy with layout $layout_copy"
8006         touch $f_mgrt
8007         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8008
8009         # 1. test option --yaml
8010         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8011                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8012         layout_before=$(get_layout_param $f_yaml)
8013         layout_after=$(get_layout_param $f_mgrt)
8014         [ "$layout_after" == "$layout_before" ] ||
8015                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8016
8017         # 2. test option --copy
8018         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8019                 error "cannot migrate $f_mgrt with --copy $f_copy"
8020         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8021         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8022         [ "$layout_after" == "$layout_before" ] ||
8023                 error "lfs_migrate --copy: $layout_after != $layout_before"
8024 }
8025 run_test 56xd "check lfs_migrate --yaml and --copy support"
8026
8027 test_56xe() {
8028         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8029
8030         local dir=$DIR/$tdir
8031         local f_comp=$dir/$tfile
8032         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8033         local layout_before=""
8034         local layout_after=""
8035
8036         test_mkdir "$dir" || error "cannot create dir $dir"
8037         $LFS setstripe $layout $f_comp ||
8038                 error "cannot setstripe $f_comp with layout $layout"
8039         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8040         dd if=/dev/zero of=$f_comp bs=1M count=4
8041
8042         # 1. migrate a comp layout file by lfs_migrate
8043         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8044         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8045         [ "$layout_before" == "$layout_after" ] ||
8046                 error "lfs_migrate: $layout_before != $layout_after"
8047
8048         # 2. migrate a comp layout file by lfs migrate
8049         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8050         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8051         [ "$layout_before" == "$layout_after" ] ||
8052                 error "lfs migrate: $layout_before != $layout_after"
8053 }
8054 run_test 56xe "migrate a composite layout file"
8055
8056 test_56xf() {
8057         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8058
8059         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8060                 skip "Need server version at least 2.13.53"
8061
8062         local dir=$DIR/$tdir
8063         local f_comp=$dir/$tfile
8064         local layout="-E 1M -c1 -E -1 -c2"
8065         local fid_before=""
8066         local fid_after=""
8067
8068         test_mkdir "$dir" || error "cannot create dir $dir"
8069         $LFS setstripe $layout $f_comp ||
8070                 error "cannot setstripe $f_comp with layout $layout"
8071         fid_before=$($LFS getstripe --fid $f_comp)
8072         dd if=/dev/zero of=$f_comp bs=1M count=4
8073
8074         # 1. migrate a comp layout file to a comp layout
8075         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8076         fid_after=$($LFS getstripe --fid $f_comp)
8077         [ "$fid_before" == "$fid_after" ] ||
8078                 error "comp-to-comp migrate: $fid_before != $fid_after"
8079
8080         # 2. migrate a comp layout file to a plain layout
8081         $LFS migrate -c2 $f_comp ||
8082                 error "cannot migrate $f_comp by lfs migrate"
8083         fid_after=$($LFS getstripe --fid $f_comp)
8084         [ "$fid_before" == "$fid_after" ] ||
8085                 error "comp-to-plain migrate: $fid_before != $fid_after"
8086
8087         # 3. migrate a plain layout file to a comp layout
8088         $LFS migrate $layout $f_comp ||
8089                 error "cannot migrate $f_comp by lfs migrate"
8090         fid_after=$($LFS getstripe --fid $f_comp)
8091         [ "$fid_before" == "$fid_after" ] ||
8092                 error "plain-to-comp migrate: $fid_before != $fid_after"
8093 }
8094 run_test 56xf "FID is not lost during migration of a composite layout file"
8095
8096 check_file_ost_range() {
8097         local file="$1"
8098         shift
8099         local range="$*"
8100         local -a file_range
8101         local idx
8102
8103         file_range=($($LFS getstripe -y "$file" |
8104                 awk '/l_ost_idx:/ { print $NF }'))
8105
8106         if [[ "${#file_range[@]}" = 0 ]]; then
8107                 echo "No osts found for $file"
8108                 return 1
8109         fi
8110
8111         for idx in "${file_range[@]}"; do
8112                 [[ " $range " =~ " $idx " ]] ||
8113                         return 1
8114         done
8115
8116         return 0
8117 }
8118
8119 sub_test_56xg() {
8120         local stripe_opt="$1"
8121         local pool="$2"
8122         shift 2
8123         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8124
8125         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8126                 error "Fail to migrate $tfile on $pool"
8127         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8128                 error "$tfile is not in pool $pool"
8129         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8130                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8131 }
8132
8133 test_56xg() {
8134         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8135         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8136         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8137                 skip "Need MDS version newer than 2.14.52"
8138
8139         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8140         local -a pool_ranges=("0 0" "1 1" "0 1")
8141
8142         # init pools
8143         for i in "${!pool_names[@]}"; do
8144                 pool_add ${pool_names[$i]} ||
8145                         error "pool_add failed (pool: ${pool_names[$i]})"
8146                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8147                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8148         done
8149
8150         # init the file to migrate
8151         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8152                 error "Unable to create $tfile on OST1"
8153         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8154                 error "Unable to write on $tfile"
8155
8156         echo "1. migrate $tfile on pool ${pool_names[0]}"
8157         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8158
8159         echo "2. migrate $tfile on pool ${pool_names[2]}"
8160         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8161
8162         echo "3. migrate $tfile on pool ${pool_names[1]}"
8163         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8164
8165         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8166         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8167         echo
8168
8169         # Clean pools
8170         destroy_test_pools ||
8171                 error "pool_destroy failed"
8172 }
8173 run_test 56xg "lfs migrate pool support"
8174
8175 test_56xh() {
8176         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8177
8178         local size_mb=25
8179         local file1=$DIR/$tfile
8180         local tmp1=$TMP/$tfile.tmp
8181
8182         $LFS setstripe -c 2 $file1
8183
8184         stack_trap "rm -f $file1 $tmp1"
8185         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8186                         error "error creating $tmp1"
8187         ls -lsh $tmp1
8188         cp $tmp1 $file1
8189
8190         local start=$SECONDS
8191
8192         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8193                 error "migrate failed rc = $?"
8194
8195         local elapsed=$((SECONDS - start))
8196
8197         # with 1MB/s, elapsed should equal size_mb
8198         (( elapsed >= size_mb * 95 / 100 )) ||
8199                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8200
8201         (( elapsed <= size_mb * 120 / 100 )) ||
8202                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8203
8204         (( elapsed <= size_mb * 350 / 100 )) ||
8205                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8206
8207         stripe=$($LFS getstripe -c $file1)
8208         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8209         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8210
8211         # Clean up file (since it is multiple MB)
8212         rm -f $file1 $tmp1
8213 }
8214 run_test 56xh "lfs migrate bandwidth limitation support"
8215
8216 test_56xi() {
8217         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8218         verify_yaml_available || skip_env "YAML verification not installed"
8219
8220         local size_mb=5
8221         local file1=$DIR/$tfile.1
8222         local file2=$DIR/$tfile.2
8223         local file3=$DIR/$tfile.3
8224         local output_file=$DIR/$tfile.out
8225         local tmp1=$TMP/$tfile.tmp
8226
8227         $LFS setstripe -c 2 $file1
8228         $LFS setstripe -c 2 $file2
8229         $LFS setstripe -c 2 $file3
8230
8231         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8232         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8233                         error "error creating $tmp1"
8234         ls -lsh $tmp1
8235         cp $tmp1 $file1
8236         cp $tmp1 $file2
8237         cp $tmp1 $file3
8238
8239         $LFS migrate --stats --stats-interval=1 \
8240                 -c 1 $file1 $file2 $file3 1> $output_file ||
8241                 error "migrate failed rc = $?"
8242
8243         cat $output_file
8244         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8245
8246         # Clean up file (since it is multiple MB)
8247         rm -f $file1 $file2 $file3 $tmp1 $output_file
8248 }
8249 run_test 56xi "lfs migrate stats support"
8250
8251 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8252         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8253
8254         local file=$DIR/$tfile
8255         local linkdir=$DIR/$tdir
8256
8257         test_mkdir $linkdir || error "fail to create $linkdir"
8258         $LFS setstripe -i 0 -c 1 -S1M $file
8259         dd if=/dev/urandom of=$file bs=1M count=10 ||
8260                 error "fail to create $file"
8261
8262         # Create file links
8263         local cpts
8264         local threads_max
8265         local nlinks
8266
8267         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8268         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8269         (( nlinks = thread_max * 3 / 2 / cpts))
8270
8271         echo "create $nlinks hard links of $file"
8272         createmany -l $file $linkdir/link $nlinks
8273
8274         # Parallel migrates (should not block)
8275         local i
8276         for ((i = 0; i < nlinks; i++)); do
8277                 echo $linkdir/link$i
8278         done | xargs -n1 -P $nlinks $LFS migrate -c2
8279
8280         local stripe_count
8281         stripe_count=$($LFS getstripe -c $file) ||
8282                 error "fail to get stripe count on $file"
8283
8284         ((stripe_count == 2)) ||
8285                 error "fail to migrate $file (stripe_count = $stripe_count)"
8286 }
8287 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8288
8289 test_56y() {
8290         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8291                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8292
8293         local res=""
8294         local dir=$DIR/$tdir
8295         local f1=$dir/file1
8296         local f2=$dir/file2
8297
8298         test_mkdir -p $dir || error "creating dir $dir"
8299         touch $f1 || error "creating std file $f1"
8300         $MULTIOP $f2 H2c || error "creating released file $f2"
8301
8302         # a directory can be raid0, so ask only for files
8303         res=$($LFS find $dir -L raid0 -type f | wc -l)
8304         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8305
8306         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8307         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8308
8309         # only files can be released, so no need to force file search
8310         res=$($LFS find $dir -L released)
8311         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8312
8313         res=$($LFS find $dir -type f \! -L released)
8314         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8315 }
8316 run_test 56y "lfs find -L raid0|released"
8317
8318 test_56z() { # LU-4824
8319         # This checks to make sure 'lfs find' continues after errors
8320         # There are two classes of errors that should be caught:
8321         # - If multiple paths are provided, all should be searched even if one
8322         #   errors out
8323         # - If errors are encountered during the search, it should not terminate
8324         #   early
8325         local dir=$DIR/$tdir
8326         local i
8327
8328         test_mkdir $dir
8329         for i in d{0..9}; do
8330                 test_mkdir $dir/$i
8331                 touch $dir/$i/$tfile
8332         done
8333         $LFS find $DIR/non_existent_dir $dir &&
8334                 error "$LFS find did not return an error"
8335         # Make a directory unsearchable. This should NOT be the last entry in
8336         # directory order.  Arbitrarily pick the 6th entry
8337         chmod 700 $($LFS find $dir -type d | sed '6!d')
8338
8339         $RUNAS $LFS find $DIR/non_existent $dir
8340         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8341
8342         # The user should be able to see 10 directories and 9 files
8343         (( count == 19 )) ||
8344                 error "$LFS find found $count != 19 entries after error"
8345 }
8346 run_test 56z "lfs find should continue after an error"
8347
8348 test_56aa() { # LU-5937
8349         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8350
8351         local dir=$DIR/$tdir
8352
8353         mkdir $dir
8354         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8355
8356         createmany -o $dir/striped_dir/${tfile}- 1024
8357         local dirs=$($LFS find --size +8k $dir/)
8358
8359         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8360 }
8361 run_test 56aa "lfs find --size under striped dir"
8362
8363 test_56ab() { # LU-10705
8364         test_mkdir $DIR/$tdir
8365         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8366         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8367         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8368         # Flush writes to ensure valid blocks.  Need to be more thorough for
8369         # ZFS, since blocks are not allocated/returned to client immediately.
8370         sync_all_data
8371         wait_zfs_commit ost1 2
8372         cancel_lru_locks osc
8373         ls -ls $DIR/$tdir
8374
8375         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8376
8377         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8378
8379         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8380         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8381
8382         rm -f $DIR/$tdir/$tfile.[123]
8383 }
8384 run_test 56ab "lfs find --blocks"
8385
8386 # LU-11188
8387 test_56aca() {
8388         local dir="$DIR/$tdir"
8389         local perms=(001 002 003 004 005 006 007
8390                      010 020 030 040 050 060 070
8391                      100 200 300 400 500 600 700
8392                      111 222 333 444 555 666 777)
8393         local perm_minus=(8 8 4 8 4 4 2
8394                           8 8 4 8 4 4 2
8395                           8 8 4 8 4 4 2
8396                           4 4 2 4 2 2 1)
8397         local perm_slash=(8  8 12  8 12 12 14
8398                           8  8 12  8 12 12 14
8399                           8  8 12  8 12 12 14
8400                          16 16 24 16 24 24 28)
8401
8402         test_mkdir "$dir"
8403         for perm in ${perms[*]}; do
8404                 touch "$dir/$tfile.$perm"
8405                 chmod $perm "$dir/$tfile.$perm"
8406         done
8407
8408         for ((i = 0; i < ${#perms[*]}; i++)); do
8409                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8410                 (( $num == 1 )) ||
8411                         error "lfs find -perm ${perms[i]}:"\
8412                               "$num != 1"
8413
8414                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8415                 (( $num == ${perm_minus[i]} )) ||
8416                         error "lfs find -perm -${perms[i]}:"\
8417                               "$num != ${perm_minus[i]}"
8418
8419                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8420                 (( $num == ${perm_slash[i]} )) ||
8421                         error "lfs find -perm /${perms[i]}:"\
8422                               "$num != ${perm_slash[i]}"
8423         done
8424 }
8425 run_test 56aca "check lfs find -perm with octal representation"
8426
8427 test_56acb() {
8428         local dir=$DIR/$tdir
8429         # p is the permission of write and execute for user, group and other
8430         # without the umask. It is used to test +wx.
8431         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8432         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8433         local symbolic=(+t  a+t u+t g+t o+t
8434                         g+s u+s o+s +s o+sr
8435                         o=r,ug+o,u+w
8436                         u+ g+ o+ a+ ugo+
8437                         u- g- o- a- ugo-
8438                         u= g= o= a= ugo=
8439                         o=r,ug+o,u+w u=r,a+u,u+w
8440                         g=r,ugo=g,u+w u+x,+X +X
8441                         u+x,u+X u+X u+x,g+X o+r,+X
8442                         u+x,go+X +wx +rwx)
8443
8444         test_mkdir $dir
8445         for perm in ${perms[*]}; do
8446                 touch "$dir/$tfile.$perm"
8447                 chmod $perm "$dir/$tfile.$perm"
8448         done
8449
8450         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8451                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8452
8453                 (( $num == 1 )) ||
8454                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8455         done
8456 }
8457 run_test 56acb "check lfs find -perm with symbolic representation"
8458
8459 test_56acc() {
8460         local dir=$DIR/$tdir
8461         local tests="17777 787 789 abcd
8462                 ug=uu ug=a ug=gu uo=ou urw
8463                 u+xg+x a=r,u+x,"
8464
8465         test_mkdir $dir
8466         for err in $tests; do
8467                 if $LFS find $dir -perm $err 2>/dev/null; then
8468                         error "lfs find -perm $err: parsing should have failed"
8469                 fi
8470         done
8471 }
8472 run_test 56acc "check parsing error for lfs find -perm"
8473
8474 test_56ba() {
8475         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8476                 skip "Need MDS version at least 2.10.50"
8477
8478         # Create composite files with one component
8479         local dir=$DIR/$tdir
8480
8481         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8482         # Create composite files with three components
8483         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8484         # Create non-composite files
8485         createmany -o $dir/${tfile}- 10
8486
8487         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8488
8489         [[ $nfiles == 10 ]] ||
8490                 error "lfs find -E 1M found $nfiles != 10 files"
8491
8492         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8493         [[ $nfiles == 25 ]] ||
8494                 error "lfs find ! -E 1M found $nfiles != 25 files"
8495
8496         # All files have a component that starts at 0
8497         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8498         [[ $nfiles == 35 ]] ||
8499                 error "lfs find --component-start 0 - $nfiles != 35 files"
8500
8501         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8502         [[ $nfiles == 15 ]] ||
8503                 error "lfs find --component-start 2M - $nfiles != 15 files"
8504
8505         # All files created here have a componenet that does not starts at 2M
8506         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8507         [[ $nfiles == 35 ]] ||
8508                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8509
8510         # Find files with a specified number of components
8511         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8512         [[ $nfiles == 15 ]] ||
8513                 error "lfs find --component-count 3 - $nfiles != 15 files"
8514
8515         # Remember non-composite files have a component count of zero
8516         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8517         [[ $nfiles == 10 ]] ||
8518                 error "lfs find --component-count 0 - $nfiles != 10 files"
8519
8520         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8521         [[ $nfiles == 20 ]] ||
8522                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8523
8524         # All files have a flag called "init"
8525         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8526         [[ $nfiles == 35 ]] ||
8527                 error "lfs find --component-flags init - $nfiles != 35 files"
8528
8529         # Multi-component files will have a component not initialized
8530         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8531         [[ $nfiles == 15 ]] ||
8532                 error "lfs find !--component-flags init - $nfiles != 15 files"
8533
8534         rm -rf $dir
8535
8536 }
8537 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8538
8539 test_56ca() {
8540         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8541                 skip "Need MDS version at least 2.10.57"
8542
8543         local td=$DIR/$tdir
8544         local tf=$td/$tfile
8545         local dir
8546         local nfiles
8547         local cmd
8548         local i
8549         local j
8550
8551         # create mirrored directories and mirrored files
8552         mkdir $td || error "mkdir $td failed"
8553         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8554         createmany -o $tf- 10 || error "create $tf- failed"
8555
8556         for i in $(seq 2); do
8557                 dir=$td/dir$i
8558                 mkdir $dir || error "mkdir $dir failed"
8559                 $LFS mirror create -N$((3 + i)) $dir ||
8560                         error "create mirrored dir $dir failed"
8561                 createmany -o $dir/$tfile- 10 ||
8562                         error "create $dir/$tfile- failed"
8563         done
8564
8565         # change the states of some mirrored files
8566         echo foo > $tf-6
8567         for i in $(seq 2); do
8568                 dir=$td/dir$i
8569                 for j in $(seq 4 9); do
8570                         echo foo > $dir/$tfile-$j
8571                 done
8572         done
8573
8574         # find mirrored files with specific mirror count
8575         cmd="$LFS find --mirror-count 3 --type f $td"
8576         nfiles=$($cmd | wc -l)
8577         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8578
8579         cmd="$LFS find ! --mirror-count 3 --type f $td"
8580         nfiles=$($cmd | wc -l)
8581         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8582
8583         cmd="$LFS find --mirror-count +2 --type f $td"
8584         nfiles=$($cmd | wc -l)
8585         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8586
8587         cmd="$LFS find --mirror-count -6 --type f $td"
8588         nfiles=$($cmd | wc -l)
8589         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8590
8591         # find mirrored files with specific file state
8592         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8593         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8594
8595         cmd="$LFS find --mirror-state=ro --type f $td"
8596         nfiles=$($cmd | wc -l)
8597         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8598
8599         cmd="$LFS find ! --mirror-state=ro --type f $td"
8600         nfiles=$($cmd | wc -l)
8601         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8602
8603         cmd="$LFS find --mirror-state=wp --type f $td"
8604         nfiles=$($cmd | wc -l)
8605         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8606
8607         cmd="$LFS find ! --mirror-state=sp --type f $td"
8608         nfiles=$($cmd | wc -l)
8609         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8610 }
8611 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8612
8613 test_56da() { # LU-14179
8614         local path=$DIR/$tdir
8615
8616         test_mkdir $path
8617         cd $path
8618
8619         local longdir=$(str_repeat 'a' 255)
8620
8621         for i in {1..15}; do
8622                 path=$path/$longdir
8623                 test_mkdir $longdir
8624                 cd $longdir
8625         done
8626
8627         local len=${#path}
8628         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8629
8630         test_mkdir $lastdir
8631         cd $lastdir
8632         # PATH_MAX-1
8633         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8634
8635         # NAME_MAX
8636         touch $(str_repeat 'f' 255)
8637
8638         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8639                 error "lfs find reported an error"
8640
8641         rm -rf $DIR/$tdir
8642 }
8643 run_test 56da "test lfs find with long paths"
8644
8645 test_56ea() { #LU-10378
8646         local path=$DIR/$tdir
8647         local pool=$TESTNAME
8648
8649         # Create ost pool
8650         pool_add $pool || error "pool_add $pool failed"
8651         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8652                 error "adding targets to $pool failed"
8653
8654         # Set default pool on directory before creating file
8655         mkdir $path || error "mkdir $path failed"
8656         $LFS setstripe -p $pool $path ||
8657                 error "set OST pool on $pool failed"
8658         touch $path/$tfile || error "touch $path/$tfile failed"
8659
8660         # Compare basic file attributes from -printf and stat
8661         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8662         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8663
8664         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8665                 error "Attrs from lfs find and stat don't match"
8666
8667         # Compare Lustre attributes from lfs find and lfs getstripe
8668         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8669         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8670         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8671         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8672         local fpool=$($LFS getstripe --pool $path/$tfile)
8673         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8674
8675         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8676                 error "Attrs from lfs find and lfs getstripe don't match"
8677
8678         # Verify behavior for unknown escape/format sequences
8679         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8680
8681         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8682                 error "Escape/format codes don't match"
8683 }
8684 run_test 56ea "test lfs find -printf option"
8685
8686 test_56eb() {
8687         local dir=$DIR/$tdir
8688         local subdir_1=$dir/subdir_1
8689
8690         test_mkdir -p $subdir_1
8691         ln -s subdir_1 $dir/link_1
8692
8693         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8694                 error "symlink is not followed"
8695
8696         $LFS getstripe --no-follow $dir |
8697                 grep "^$dir/link_1 has no stripe info$" ||
8698                 error "symlink should not have stripe info"
8699
8700         touch $dir/testfile
8701         ln -s testfile $dir/file_link_2
8702
8703         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8704                 error "symlink is not followed"
8705
8706         $LFS getstripe --no-follow $dir |
8707                 grep "^$dir/file_link_2 has no stripe info$" ||
8708                 error "symlink should not have stripe info"
8709 }
8710 run_test 56eb "check lfs getstripe on symlink"
8711
8712 test_56ec() {
8713         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8714         local dir=$DIR/$tdir
8715         local srcfile=$dir/srcfile
8716         local srcyaml=$dir/srcyaml
8717         local destfile=$dir/destfile
8718
8719         test_mkdir -p $dir
8720
8721         $LFS setstripe -i 1 $srcfile
8722         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8723         # if the setstripe yaml parsing fails for any reason, the command can
8724         # randomly assign the correct OST index, leading to an erroneous
8725         # success. but the chance of false success is low enough that a
8726         # regression should still be quickly caught.
8727         $LFS setstripe --yaml=$srcyaml $destfile
8728
8729         local srcindex=$($LFS getstripe -i $srcfile)
8730         local destindex=$($LFS getstripe -i $destfile)
8731
8732         if [[ ! $srcindex -eq $destindex ]]; then
8733                 error "setstripe did not set OST index correctly"
8734         fi
8735 }
8736 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8737
8738 test_57a() {
8739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8740         # note test will not do anything if MDS is not local
8741         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8742                 skip_env "ldiskfs only test"
8743         fi
8744         remote_mds_nodsh && skip "remote MDS with nodsh"
8745
8746         local MNTDEV="osd*.*MDT*.mntdev"
8747         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8748         [ -z "$DEV" ] && error "can't access $MNTDEV"
8749         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8750                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8751                         error "can't access $DEV"
8752                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8753                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8754                 rm $TMP/t57a.dump
8755         done
8756 }
8757 run_test 57a "verify MDS filesystem created with large inodes =="
8758
8759 test_57b() {
8760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8761         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8762                 skip_env "ldiskfs only test"
8763         fi
8764         remote_mds_nodsh && skip "remote MDS with nodsh"
8765
8766         local dir=$DIR/$tdir
8767         local filecount=100
8768         local file1=$dir/f1
8769         local fileN=$dir/f$filecount
8770
8771         rm -rf $dir || error "removing $dir"
8772         test_mkdir -c1 $dir
8773         local mdtidx=$($LFS getstripe -m $dir)
8774         local mdtname=MDT$(printf %04x $mdtidx)
8775         local facet=mds$((mdtidx + 1))
8776
8777         echo "mcreating $filecount files"
8778         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8779
8780         # verify that files do not have EAs yet
8781         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8782                 error "$file1 has an EA"
8783         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8784                 error "$fileN has an EA"
8785
8786         sync
8787         sleep 1
8788         df $dir  #make sure we get new statfs data
8789         local mdsfree=$(do_facet $facet \
8790                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8791         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8792         local file
8793
8794         echo "opening files to create objects/EAs"
8795         for file in $(seq -f $dir/f%g 1 $filecount); do
8796                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8797                         error "opening $file"
8798         done
8799
8800         # verify that files have EAs now
8801         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8802         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8803
8804         sleep 1  #make sure we get new statfs data
8805         df $dir
8806         local mdsfree2=$(do_facet $facet \
8807                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8808         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8809
8810         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8811                 if [ "$mdsfree" != "$mdsfree2" ]; then
8812                         error "MDC before $mdcfree != after $mdcfree2"
8813                 else
8814                         echo "MDC before $mdcfree != after $mdcfree2"
8815                         echo "unable to confirm if MDS has large inodes"
8816                 fi
8817         fi
8818         rm -rf $dir
8819 }
8820 run_test 57b "default LOV EAs are stored inside large inodes ==="
8821
8822 test_58() {
8823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8824         [ -z "$(which wiretest 2>/dev/null)" ] &&
8825                         skip_env "could not find wiretest"
8826
8827         wiretest
8828 }
8829 run_test 58 "verify cross-platform wire constants =============="
8830
8831 test_59() {
8832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8833
8834         echo "touch 130 files"
8835         createmany -o $DIR/f59- 130
8836         echo "rm 130 files"
8837         unlinkmany $DIR/f59- 130
8838         sync
8839         # wait for commitment of removal
8840         wait_delete_completed
8841 }
8842 run_test 59 "verify cancellation of llog records async ========="
8843
8844 TEST60_HEAD="test_60 run $RANDOM"
8845 test_60a() {
8846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8847         remote_mgs_nodsh && skip "remote MGS with nodsh"
8848         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8849                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8850                         skip_env "missing subtest run-llog.sh"
8851
8852         log "$TEST60_HEAD - from kernel mode"
8853         do_facet mgs "$LCTL dk > /dev/null"
8854         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8855         do_facet mgs $LCTL dk > $TMP/$tfile
8856
8857         # LU-6388: test llog_reader
8858         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8859         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8860         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8861                         skip_env "missing llog_reader"
8862         local fstype=$(facet_fstype mgs)
8863         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8864                 skip_env "Only for ldiskfs or zfs type mgs"
8865
8866         local mntpt=$(facet_mntpt mgs)
8867         local mgsdev=$(mgsdevname 1)
8868         local fid_list
8869         local fid
8870         local rec_list
8871         local rec
8872         local rec_type
8873         local obj_file
8874         local path
8875         local seq
8876         local oid
8877         local pass=true
8878
8879         #get fid and record list
8880         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8881                 tail -n 4))
8882         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8883                 tail -n 4))
8884         #remount mgs as ldiskfs or zfs type
8885         stop mgs || error "stop mgs failed"
8886         mount_fstype mgs || error "remount mgs failed"
8887         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8888                 fid=${fid_list[i]}
8889                 rec=${rec_list[i]}
8890                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8891                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8892                 oid=$((16#$oid))
8893
8894                 case $fstype in
8895                         ldiskfs )
8896                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8897                         zfs )
8898                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8899                 esac
8900                 echo "obj_file is $obj_file"
8901                 do_facet mgs $llog_reader $obj_file
8902
8903                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8904                         awk '{ print $3 }' | sed -e "s/^type=//g")
8905                 if [ $rec_type != $rec ]; then
8906                         echo "FAILED test_60a wrong record type $rec_type," \
8907                               "should be $rec"
8908                         pass=false
8909                         break
8910                 fi
8911
8912                 #check obj path if record type is LLOG_LOGID_MAGIC
8913                 if [ "$rec" == "1064553b" ]; then
8914                         path=$(do_facet mgs $llog_reader $obj_file |
8915                                 grep "path=" | awk '{ print $NF }' |
8916                                 sed -e "s/^path=//g")
8917                         if [ $obj_file != $mntpt/$path ]; then
8918                                 echo "FAILED test_60a wrong obj path" \
8919                                       "$montpt/$path, should be $obj_file"
8920                                 pass=false
8921                                 break
8922                         fi
8923                 fi
8924         done
8925         rm -f $TMP/$tfile
8926         #restart mgs before "error", otherwise it will block the next test
8927         stop mgs || error "stop mgs failed"
8928         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8929         $pass || error "test failed, see FAILED test_60a messages for specifics"
8930 }
8931 run_test 60a "llog_test run from kernel module and test llog_reader"
8932
8933 test_60b() { # bug 6411
8934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8935
8936         dmesg > $DIR/$tfile
8937         LLOG_COUNT=$(do_facet mgs dmesg |
8938                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8939                           /llog_[a-z]*.c:[0-9]/ {
8940                                 if (marker)
8941                                         from_marker++
8942                                 from_begin++
8943                           }
8944                           END {
8945                                 if (marker)
8946                                         print from_marker
8947                                 else
8948                                         print from_begin
8949                           }")
8950
8951         [[ $LLOG_COUNT -gt 120 ]] &&
8952                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8953 }
8954 run_test 60b "limit repeated messages from CERROR/CWARN"
8955
8956 test_60c() {
8957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8958
8959         echo "create 5000 files"
8960         createmany -o $DIR/f60c- 5000
8961 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8962         lctl set_param fail_loc=0x80000137
8963         unlinkmany $DIR/f60c- 5000
8964         lctl set_param fail_loc=0
8965 }
8966 run_test 60c "unlink file when mds full"
8967
8968 test_60d() {
8969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8970
8971         SAVEPRINTK=$(lctl get_param -n printk)
8972         # verify "lctl mark" is even working"
8973         MESSAGE="test message ID $RANDOM $$"
8974         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8975         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8976
8977         lctl set_param printk=0 || error "set lnet.printk failed"
8978         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8979         MESSAGE="new test message ID $RANDOM $$"
8980         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8981         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8982         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8983
8984         lctl set_param -n printk="$SAVEPRINTK"
8985 }
8986 run_test 60d "test printk console message masking"
8987
8988 test_60e() {
8989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8990         remote_mds_nodsh && skip "remote MDS with nodsh"
8991
8992         touch $DIR/$tfile
8993 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8994         do_facet mds1 lctl set_param fail_loc=0x15b
8995         rm $DIR/$tfile
8996 }
8997 run_test 60e "no space while new llog is being created"
8998
8999 test_60f() {
9000         local old_path=$($LCTL get_param -n debug_path)
9001
9002         stack_trap "$LCTL set_param debug_path=$old_path"
9003         stack_trap "rm -f $TMP/$tfile*"
9004         rm -f $TMP/$tfile* 2> /dev/null
9005         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9006         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9007         test_mkdir $DIR/$tdir
9008         # retry in case the open is cached and not released
9009         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9010                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9011                 sleep 0.1
9012         done
9013         ls $TMP/$tfile*
9014         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9015 }
9016 run_test 60f "change debug_path works"
9017
9018 test_60g() {
9019         local pid
9020         local i
9021
9022         test_mkdir -c $MDSCOUNT $DIR/$tdir
9023
9024         (
9025                 local index=0
9026                 while true; do
9027                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9028                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9029                                 2>/dev/null
9030                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9031                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9032                         index=$((index + 1))
9033                 done
9034         ) &
9035
9036         pid=$!
9037
9038         for i in {0..100}; do
9039                 # define OBD_FAIL_OSD_TXN_START    0x19a
9040                 local index=$((i % MDSCOUNT + 1))
9041
9042                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9043                         > /dev/null
9044                 sleep 0.01
9045         done
9046
9047         kill -9 $pid
9048
9049         for i in $(seq $MDSCOUNT); do
9050                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9051         done
9052
9053         mkdir $DIR/$tdir/new || error "mkdir failed"
9054         rmdir $DIR/$tdir/new || error "rmdir failed"
9055
9056         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9057                 -t namespace
9058         for i in $(seq $MDSCOUNT); do
9059                 wait_update_facet mds$i "$LCTL get_param -n \
9060                         mdd.$(facet_svc mds$i).lfsck_namespace |
9061                         awk '/^status/ { print \\\$2 }'" "completed"
9062         done
9063
9064         ls -R $DIR/$tdir
9065         rm -rf $DIR/$tdir || error "rmdir failed"
9066 }
9067 run_test 60g "transaction abort won't cause MDT hung"
9068
9069 test_60h() {
9070         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9071                 skip "Need MDS version at least 2.12.52"
9072         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9073
9074         local f
9075
9076         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9077         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9078         for fail_loc in 0x80000188 0x80000189; do
9079                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9080                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9081                         error "mkdir $dir-$fail_loc failed"
9082                 for i in {0..10}; do
9083                         # create may fail on missing stripe
9084                         echo $i > $DIR/$tdir-$fail_loc/$i
9085                 done
9086                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9087                         error "getdirstripe $tdir-$fail_loc failed"
9088                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9089                         error "migrate $tdir-$fail_loc failed"
9090                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9091                         error "getdirstripe $tdir-$fail_loc failed"
9092                 pushd $DIR/$tdir-$fail_loc
9093                 for f in *; do
9094                         echo $f | cmp $f - || error "$f data mismatch"
9095                 done
9096                 popd
9097                 rm -rf $DIR/$tdir-$fail_loc
9098         done
9099 }
9100 run_test 60h "striped directory with missing stripes can be accessed"
9101
9102 function t60i_load() {
9103         mkdir $DIR/$tdir
9104         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9105         $LCTL set_param fail_loc=0x131c fail_val=1
9106         for ((i=0; i<5000; i++)); do
9107                 touch $DIR/$tdir/f$i
9108         done
9109 }
9110
9111 test_60i() {
9112         changelog_register || error "changelog_register failed"
9113         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9114         changelog_users $SINGLEMDS | grep -q $cl_user ||
9115                 error "User $cl_user not found in changelog_users"
9116         changelog_chmask "ALL"
9117         t60i_load &
9118         local PID=$!
9119         for((i=0; i<100; i++)); do
9120                 changelog_dump >/dev/null ||
9121                         error "can't read changelog"
9122         done
9123         kill $PID
9124         wait $PID
9125         changelog_deregister || error "changelog_deregister failed"
9126         $LCTL set_param fail_loc=0
9127 }
9128 run_test 60i "llog: new record vs reader race"
9129
9130 test_60j() {
9131         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9132                 skip "need MDS version at least 2.15.50"
9133         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9134         remote_mds_nodsh && skip "remote MDS with nodsh"
9135         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9136
9137         changelog_users $SINGLEMDS | grep "^cl" &&
9138                 skip "active changelog user"
9139
9140         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9141
9142         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9143                 skip_env "missing llog_reader"
9144
9145         mkdir_on_mdt0 $DIR/$tdir
9146
9147         local f=$DIR/$tdir/$tfile
9148         local mdt_dev
9149         local tmpfile
9150         local plain
9151
9152         changelog_register || error "cannot register changelog user"
9153
9154         # set changelog_mask to ALL
9155         changelog_chmask "ALL"
9156         changelog_clear
9157
9158         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9159         unlinkmany ${f}- 100 || error "unlinkmany failed"
9160
9161         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9162         mdt_dev=$(facet_device $SINGLEMDS)
9163
9164         do_facet $SINGLEMDS sync
9165         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9166                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9167                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9168
9169         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9170
9171         # if $tmpfile is not on EXT3 filesystem for some reason
9172         [[ ${plain:0:1} == 'O' ]] ||
9173                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9174
9175         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9176                 $mdt_dev; stat -c %s $tmpfile")
9177         echo "Truncate llog from $size to $((size - size % 8192))"
9178         size=$((size - size % 8192))
9179         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9180         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9181                 grep -c 'in bitmap only')
9182         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9183
9184         size=$((size - 9000))
9185         echo "Corrupt llog in the middle at $size"
9186         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9187                 count=333 conv=notrunc
9188         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9189                 grep -c 'next chunk')
9190         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9191 }
9192 run_test 60j "llog_reader reports corruptions"
9193
9194 test_61a() {
9195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9196
9197         f="$DIR/f61"
9198         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9199         cancel_lru_locks osc
9200         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9201         sync
9202 }
9203 run_test 61a "mmap() writes don't make sync hang ================"
9204
9205 test_61b() {
9206         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9207 }
9208 run_test 61b "mmap() of unstriped file is successful"
9209
9210 # bug 2330 - insufficient obd_match error checking causes LBUG
9211 test_62() {
9212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9213
9214         f="$DIR/f62"
9215         echo foo > $f
9216         cancel_lru_locks osc
9217         lctl set_param fail_loc=0x405
9218         cat $f && error "cat succeeded, expect -EIO"
9219         lctl set_param fail_loc=0
9220 }
9221 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9222 # match every page all of the time.
9223 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9224
9225 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9226 # Though this test is irrelevant anymore, it helped to reveal some
9227 # other grant bugs (LU-4482), let's keep it.
9228 test_63a() {   # was test_63
9229         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9230
9231         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9232
9233         for i in `seq 10` ; do
9234                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9235                 sleep 5
9236                 kill $!
9237                 sleep 1
9238         done
9239
9240         rm -f $DIR/f63 || true
9241 }
9242 run_test 63a "Verify oig_wait interruption does not crash ======="
9243
9244 # bug 2248 - async write errors didn't return to application on sync
9245 # bug 3677 - async write errors left page locked
9246 test_63b() {
9247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9248
9249         debugsave
9250         lctl set_param debug=-1
9251
9252         # ensure we have a grant to do async writes
9253         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9254         rm $DIR/$tfile
9255
9256         sync    # sync lest earlier test intercept the fail_loc
9257
9258         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9259         lctl set_param fail_loc=0x80000406
9260         $MULTIOP $DIR/$tfile Owy && \
9261                 error "sync didn't return ENOMEM"
9262         sync; sleep 2; sync     # do a real sync this time to flush page
9263         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9264                 error "locked page left in cache after async error" || true
9265         debugrestore
9266 }
9267 run_test 63b "async write errors should be returned to fsync ==="
9268
9269 test_64a () {
9270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9271
9272         lfs df $DIR
9273         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9274 }
9275 run_test 64a "verify filter grant calculations (in kernel) ====="
9276
9277 test_64b () {
9278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9279
9280         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9281 }
9282 run_test 64b "check out-of-space detection on client"
9283
9284 test_64c() {
9285         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9286 }
9287 run_test 64c "verify grant shrink"
9288
9289 import_param() {
9290         local tgt=$1
9291         local param=$2
9292
9293         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9294 }
9295
9296 # this does exactly what osc_request.c:osc_announce_cached() does in
9297 # order to calculate max amount of grants to ask from server
9298 want_grant() {
9299         local tgt=$1
9300
9301         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9302         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9303
9304         ((rpc_in_flight++));
9305         nrpages=$((nrpages * rpc_in_flight))
9306
9307         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9308
9309         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9310
9311         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9312         local undirty=$((nrpages * PAGE_SIZE))
9313
9314         local max_extent_pages
9315         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9316         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9317         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9318         local grant_extent_tax
9319         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9320
9321         undirty=$((undirty + nrextents * grant_extent_tax))
9322
9323         echo $undirty
9324 }
9325
9326 # this is size of unit for grant allocation. It should be equal to
9327 # what tgt_grant.c:tgt_grant_chunk() calculates
9328 grant_chunk() {
9329         local tgt=$1
9330         local max_brw_size
9331         local grant_extent_tax
9332
9333         max_brw_size=$(import_param $tgt max_brw_size)
9334
9335         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9336
9337         echo $(((max_brw_size + grant_extent_tax) * 2))
9338 }
9339
9340 test_64d() {
9341         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9342                 skip "OST < 2.10.55 doesn't limit grants enough"
9343
9344         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9345
9346         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9347                 skip "no grant_param connect flag"
9348
9349         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9350
9351         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9352         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9353
9354
9355         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9356         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9357
9358         $LFS setstripe $DIR/$tfile -i 0 -c 1
9359         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9360         ddpid=$!
9361
9362         while kill -0 $ddpid; do
9363                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9364
9365                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9366                         kill $ddpid
9367                         error "cur_grant $cur_grant > $max_cur_granted"
9368                 fi
9369
9370                 sleep 1
9371         done
9372 }
9373 run_test 64d "check grant limit exceed"
9374
9375 check_grants() {
9376         local tgt=$1
9377         local expected=$2
9378         local msg=$3
9379         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9380
9381         ((cur_grants == expected)) ||
9382                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9383 }
9384
9385 round_up_p2() {
9386         echo $((($1 + $2 - 1) & ~($2 - 1)))
9387 }
9388
9389 test_64e() {
9390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9391         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9392                 skip "Need OSS version at least 2.11.56"
9393
9394         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9395         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9396         $LCTL set_param debug=+cache
9397
9398         # Remount client to reset grant
9399         remount_client $MOUNT || error "failed to remount client"
9400         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9401
9402         local init_grants=$(import_param $osc_tgt initial_grant)
9403
9404         check_grants $osc_tgt $init_grants "init grants"
9405
9406         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9407         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9408         local gbs=$(import_param $osc_tgt grant_block_size)
9409
9410         # write random number of bytes from max_brw_size / 4 to max_brw_size
9411         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9412         # align for direct io
9413         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9414         # round to grant consumption unit
9415         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9416
9417         local grants=$((wb_round_up + extent_tax))
9418
9419         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9420
9421         # define OBD_FAIL_TGT_NO_GRANT 0x725
9422         # make the server not grant more back
9423         do_facet ost1 $LCTL set_param fail_loc=0x725
9424         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9425
9426         do_facet ost1 $LCTL set_param fail_loc=0
9427
9428         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9429
9430         rm -f $DIR/$tfile || error "rm failed"
9431
9432         # Remount client to reset grant
9433         remount_client $MOUNT || error "failed to remount client"
9434         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9435
9436         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9437
9438         # define OBD_FAIL_TGT_NO_GRANT 0x725
9439         # make the server not grant more back
9440         do_facet ost1 $LCTL set_param fail_loc=0x725
9441         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9442         do_facet ost1 $LCTL set_param fail_loc=0
9443
9444         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9445 }
9446 run_test 64e "check grant consumption (no grant allocation)"
9447
9448 test_64f() {
9449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9450
9451         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9452         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9453         $LCTL set_param debug=+cache
9454
9455         # Remount client to reset grant
9456         remount_client $MOUNT || error "failed to remount client"
9457         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9458
9459         local init_grants=$(import_param $osc_tgt initial_grant)
9460         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9461         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9462         local gbs=$(import_param $osc_tgt grant_block_size)
9463         local chunk=$(grant_chunk $osc_tgt)
9464
9465         # write random number of bytes from max_brw_size / 4 to max_brw_size
9466         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9467         # align for direct io
9468         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9469         # round to grant consumption unit
9470         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9471
9472         local grants=$((wb_round_up + extent_tax))
9473
9474         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9475         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9476                 error "error writing to $DIR/$tfile"
9477
9478         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9479                 "direct io with grant allocation"
9480
9481         rm -f $DIR/$tfile || error "rm failed"
9482
9483         # Remount client to reset grant
9484         remount_client $MOUNT || error "failed to remount client"
9485         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9486
9487         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9488
9489         local cmd="oO_WRONLY:w${write_bytes}_yc"
9490
9491         $MULTIOP $DIR/$tfile $cmd &
9492         MULTIPID=$!
9493         sleep 1
9494
9495         check_grants $osc_tgt $((init_grants - grants)) \
9496                 "buffered io, not write rpc"
9497
9498         kill -USR1 $MULTIPID
9499         wait
9500
9501         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9502                 "buffered io, one RPC"
9503 }
9504 run_test 64f "check grant consumption (with grant allocation)"
9505
9506 test_64g() {
9507         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9508                 skip "Need MDS version at least 2.14.56"
9509
9510         local mdts=$(comma_list $(mdts_nodes))
9511
9512         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9513                         tr '\n' ' ')
9514         stack_trap "$LCTL set_param $old"
9515
9516         # generate dirty pages and increase dirty granted on MDT
9517         stack_trap "rm -f $DIR/$tfile-*"
9518         for (( i = 0; i < 10; i++)); do
9519                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9520                         error "can't set stripe"
9521                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9522                         error "can't dd"
9523                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9524                         $LFS getstripe $DIR/$tfile-$i
9525                         error "not DoM file"
9526                 }
9527         done
9528
9529         # flush dirty pages
9530         sync
9531
9532         # wait until grant shrink reset grant dirty on MDTs
9533         for ((i = 0; i < 120; i++)); do
9534                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9535                         awk '{sum=sum+$1} END {print sum}')
9536                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9537                 echo "$grant_dirty grants, $vm_dirty pages"
9538                 (( grant_dirty + vm_dirty == 0 )) && break
9539                 (( i == 3 )) && sync &&
9540                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9541                 sleep 1
9542         done
9543
9544         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9545                 awk '{sum=sum+$1} END {print sum}')
9546         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9547 }
9548 run_test 64g "grant shrink on MDT"
9549
9550 test_64h() {
9551         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9552                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9553
9554         local instance=$($LFS getname -i $DIR)
9555         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9556         local num_exps=$(do_facet ost1 \
9557             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9558         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9559         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9560         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9561
9562         # 10MiB is for file to be written, max_brw_size * 16 *
9563         # num_exps is space reserve so that tgt_grant_shrink() decided
9564         # to not shrink
9565         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9566         (( avail * 1024 < expect )) &&
9567                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9568
9569         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9570         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9571         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9572         $LCTL set_param osc.*OST0000*.grant_shrink=1
9573         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9574
9575         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9576         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9577
9578         # drop cache so that coming read would do rpc
9579         cancel_lru_locks osc
9580
9581         # shrink interval is set to 10, pause for 7 seconds so that
9582         # grant thread did not wake up yet but coming read entered
9583         # shrink mode for rpc (osc_should_shrink_grant())
9584         sleep 7
9585
9586         declare -a cur_grant_bytes
9587         declare -a tot_granted
9588         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9589         tot_granted[0]=$(do_facet ost1 \
9590             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9591
9592         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9593
9594         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9595         tot_granted[1]=$(do_facet ost1 \
9596             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9597
9598         # grant change should be equal on both sides
9599         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9600                 tot_granted[0] - tot_granted[1])) ||
9601                 error "grant change mismatch, "                                \
9602                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9603                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9604 }
9605 run_test 64h "grant shrink on read"
9606
9607 test_64i() {
9608         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9609                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9610
9611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9612         remote_ost_nodsh && skip "remote OSTs with nodsh"
9613
9614         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9615
9616         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9617
9618         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9619         local instance=$($LFS getname -i $DIR)
9620
9621         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9622         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9623
9624         # shrink grants and simulate rpc loss
9625         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9626         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9627         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9628
9629         fail ost1
9630
9631         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9632
9633         local testid=$(echo $TESTNAME | tr '_' ' ')
9634
9635         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9636                 grep "GRANT, real grant" &&
9637                 error "client has more grants then it owns" || true
9638 }
9639 run_test 64i "shrink on reconnect"
9640
9641 # bug 1414 - set/get directories' stripe info
9642 test_65a() {
9643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9644
9645         test_mkdir $DIR/$tdir
9646         touch $DIR/$tdir/f1
9647         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9648 }
9649 run_test 65a "directory with no stripe info"
9650
9651 test_65b() {
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         test_mkdir $DIR/$tdir
9655         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9656
9657         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9658                                                 error "setstripe"
9659         touch $DIR/$tdir/f2
9660         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9661 }
9662 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9663
9664 test_65c() {
9665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9666         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9667
9668         test_mkdir $DIR/$tdir
9669         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9670
9671         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9672                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9673         touch $DIR/$tdir/f3
9674         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9675 }
9676 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9677
9678 test_65d() {
9679         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9680
9681         test_mkdir $DIR/$tdir
9682         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9683         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9684
9685         if [[ $STRIPECOUNT -le 0 ]]; then
9686                 sc=1
9687         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9688                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9689                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9690         else
9691                 sc=$(($STRIPECOUNT - 1))
9692         fi
9693         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9694         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9695         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9696                 error "lverify failed"
9697 }
9698 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9699
9700 test_65e() {
9701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9702
9703         test_mkdir $DIR/$tdir
9704
9705         $LFS setstripe $DIR/$tdir || error "setstripe"
9706         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9707                                         error "no stripe info failed"
9708         touch $DIR/$tdir/f6
9709         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9710 }
9711 run_test 65e "directory setstripe defaults"
9712
9713 test_65f() {
9714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9715
9716         test_mkdir $DIR/${tdir}f
9717         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9718                 error "setstripe succeeded" || true
9719 }
9720 run_test 65f "dir setstripe permission (should return error) ==="
9721
9722 test_65g() {
9723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9724
9725         test_mkdir $DIR/$tdir
9726         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9727
9728         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9729                 error "setstripe -S failed"
9730         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9731         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9732                 error "delete default stripe failed"
9733 }
9734 run_test 65g "directory setstripe -d"
9735
9736 test_65h() {
9737         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9738
9739         test_mkdir $DIR/$tdir
9740         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9741
9742         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9743                 error "setstripe -S failed"
9744         test_mkdir $DIR/$tdir/dd1
9745         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9746                 error "stripe info inherit failed"
9747 }
9748 run_test 65h "directory stripe info inherit ===================="
9749
9750 test_65i() {
9751         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9752
9753         save_layout_restore_at_exit $MOUNT
9754
9755         # bug6367: set non-default striping on root directory
9756         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9757
9758         # bug12836: getstripe on -1 default directory striping
9759         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9760
9761         # bug12836: getstripe -v on -1 default directory striping
9762         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9763
9764         # bug12836: new find on -1 default directory striping
9765         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9766 }
9767 run_test 65i "various tests to set root directory striping"
9768
9769 test_65j() { # bug6367
9770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9771
9772         sync; sleep 1
9773
9774         # if we aren't already remounting for each test, do so for this test
9775         if [ "$I_MOUNTED" = "yes" ]; then
9776                 cleanup || error "failed to unmount"
9777                 setup
9778         fi
9779
9780         save_layout_restore_at_exit $MOUNT
9781
9782         $LFS setstripe -d $MOUNT || error "setstripe failed"
9783 }
9784 run_test 65j "set default striping on root directory (bug 6367)="
9785
9786 cleanup_65k() {
9787         rm -rf $DIR/$tdir
9788         wait_delete_completed
9789         do_facet $SINGLEMDS "lctl set_param -n \
9790                 osp.$ost*MDT0000.max_create_count=$max_count"
9791         do_facet $SINGLEMDS "lctl set_param -n \
9792                 osp.$ost*MDT0000.create_count=$count"
9793         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9794         echo $INACTIVE_OSC "is Activate"
9795
9796         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9797 }
9798
9799 test_65k() { # bug11679
9800         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9801         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9802         remote_mds_nodsh && skip "remote MDS with nodsh"
9803
9804         local disable_precreate=true
9805         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9806                 disable_precreate=false
9807
9808         echo "Check OST status: "
9809         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9810                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9811
9812         for OSC in $MDS_OSCS; do
9813                 echo $OSC "is active"
9814                 do_facet $SINGLEMDS lctl --device %$OSC activate
9815         done
9816
9817         for INACTIVE_OSC in $MDS_OSCS; do
9818                 local ost=$(osc_to_ost $INACTIVE_OSC)
9819                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9820                                lov.*md*.target_obd |
9821                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9822
9823                 mkdir -p $DIR/$tdir
9824                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9825                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9826
9827                 echo "Deactivate: " $INACTIVE_OSC
9828                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9829
9830                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9831                               osp.$ost*MDT0000.create_count")
9832                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9833                                   osp.$ost*MDT0000.max_create_count")
9834                 $disable_precreate &&
9835                         do_facet $SINGLEMDS "lctl set_param -n \
9836                                 osp.$ost*MDT0000.max_create_count=0"
9837
9838                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9839                         [ -f $DIR/$tdir/$idx ] && continue
9840                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9841                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9842                                 { cleanup_65k;
9843                                   error "setstripe $idx should succeed"; }
9844                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9845                 done
9846                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9847                 rmdir $DIR/$tdir
9848
9849                 do_facet $SINGLEMDS "lctl set_param -n \
9850                         osp.$ost*MDT0000.max_create_count=$max_count"
9851                 do_facet $SINGLEMDS "lctl set_param -n \
9852                         osp.$ost*MDT0000.create_count=$count"
9853                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9854                 echo $INACTIVE_OSC "is Activate"
9855
9856                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9857         done
9858 }
9859 run_test 65k "validate manual striping works properly with deactivated OSCs"
9860
9861 test_65l() { # bug 12836
9862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9863
9864         test_mkdir -p $DIR/$tdir/test_dir
9865         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9866         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9867 }
9868 run_test 65l "lfs find on -1 stripe dir ========================"
9869
9870 test_65m() {
9871         local layout=$(save_layout $MOUNT)
9872         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9873                 restore_layout $MOUNT $layout
9874                 error "setstripe should fail by non-root users"
9875         }
9876         true
9877 }
9878 run_test 65m "normal user can't set filesystem default stripe"
9879
9880 test_65n() {
9881         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9882         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9883                 skip "Need MDS version at least 2.12.50"
9884         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9885
9886         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9887         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9888         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9889
9890         save_layout_restore_at_exit $MOUNT
9891
9892         # new subdirectory under root directory should not inherit
9893         # the default layout from root
9894         local dir1=$MOUNT/$tdir-1
9895         mkdir $dir1 || error "mkdir $dir1 failed"
9896         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9897                 error "$dir1 shouldn't have LOV EA"
9898
9899         # delete the default layout on root directory
9900         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9901
9902         local dir2=$MOUNT/$tdir-2
9903         mkdir $dir2 || error "mkdir $dir2 failed"
9904         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9905                 error "$dir2 shouldn't have LOV EA"
9906
9907         # set a new striping pattern on root directory
9908         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9909         local new_def_stripe_size=$((def_stripe_size * 2))
9910         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9911                 error "set stripe size on $MOUNT failed"
9912
9913         # new file created in $dir2 should inherit the new stripe size from
9914         # the filesystem default
9915         local file2=$dir2/$tfile-2
9916         touch $file2 || error "touch $file2 failed"
9917
9918         local file2_stripe_size=$($LFS getstripe -S $file2)
9919         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9920         {
9921                 echo "file2_stripe_size: '$file2_stripe_size'"
9922                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9923                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9924         }
9925
9926         local dir3=$MOUNT/$tdir-3
9927         mkdir $dir3 || error "mkdir $dir3 failed"
9928         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9929         # the root layout, which is the actual default layout that will be used
9930         # when new files are created in $dir3.
9931         local dir3_layout=$(get_layout_param $dir3)
9932         local root_dir_layout=$(get_layout_param $MOUNT)
9933         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9934         {
9935                 echo "dir3_layout: '$dir3_layout'"
9936                 echo "root_dir_layout: '$root_dir_layout'"
9937                 error "$dir3 should show the default layout from $MOUNT"
9938         }
9939
9940         # set OST pool on root directory
9941         local pool=$TESTNAME
9942         pool_add $pool || error "add $pool failed"
9943         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9944                 error "add targets to $pool failed"
9945
9946         $LFS setstripe -p $pool $MOUNT ||
9947                 error "set OST pool on $MOUNT failed"
9948
9949         # new file created in $dir3 should inherit the pool from
9950         # the filesystem default
9951         local file3=$dir3/$tfile-3
9952         touch $file3 || error "touch $file3 failed"
9953
9954         local file3_pool=$($LFS getstripe -p $file3)
9955         [[ "$file3_pool" = "$pool" ]] ||
9956                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9957
9958         local dir4=$MOUNT/$tdir-4
9959         mkdir $dir4 || error "mkdir $dir4 failed"
9960         local dir4_layout=$(get_layout_param $dir4)
9961         root_dir_layout=$(get_layout_param $MOUNT)
9962         echo "$LFS getstripe -d $dir4"
9963         $LFS getstripe -d $dir4
9964         echo "$LFS getstripe -d $MOUNT"
9965         $LFS getstripe -d $MOUNT
9966         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9967         {
9968                 echo "dir4_layout: '$dir4_layout'"
9969                 echo "root_dir_layout: '$root_dir_layout'"
9970                 error "$dir4 should show the default layout from $MOUNT"
9971         }
9972
9973         # new file created in $dir4 should inherit the pool from
9974         # the filesystem default
9975         local file4=$dir4/$tfile-4
9976         touch $file4 || error "touch $file4 failed"
9977
9978         local file4_pool=$($LFS getstripe -p $file4)
9979         [[ "$file4_pool" = "$pool" ]] ||
9980                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9981
9982         # new subdirectory under non-root directory should inherit
9983         # the default layout from its parent directory
9984         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9985                 error "set directory layout on $dir4 failed"
9986
9987         local dir5=$dir4/$tdir-5
9988         mkdir $dir5 || error "mkdir $dir5 failed"
9989
9990         dir4_layout=$(get_layout_param $dir4)
9991         local dir5_layout=$(get_layout_param $dir5)
9992         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9993         {
9994                 echo "dir4_layout: '$dir4_layout'"
9995                 echo "dir5_layout: '$dir5_layout'"
9996                 error "$dir5 should inherit the default layout from $dir4"
9997         }
9998
9999         # though subdir under ROOT doesn't inherit default layout, but
10000         # its sub dir/file should be created with default layout.
10001         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
10002         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
10003                 skip "Need MDS version at least 2.12.59"
10004
10005         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10006         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10007         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10008
10009         if [ $default_lmv_hash == "none" ]; then
10010                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10011         else
10012                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10013                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10014         fi
10015
10016         $LFS setdirstripe -D -c 2 $MOUNT ||
10017                 error "setdirstripe -D -c 2 failed"
10018         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10019         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10020         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10021
10022         # $dir4 layout includes pool
10023         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10024         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10025                 error "pool lost on setstripe"
10026         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10027         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10028                 error "pool lost on compound layout setstripe"
10029 }
10030 run_test 65n "don't inherit default layout from root for new subdirectories"
10031
10032 test_65o() {
10033         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10034                 skip "need MDS version at least 2.14.57"
10035
10036         # set OST pool on root directory
10037         local pool=$TESTNAME
10038
10039         pool_add $pool || error "add $pool failed"
10040         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10041                 error "add targets to $pool failed"
10042
10043         local dir1=$MOUNT/$tdir
10044
10045         mkdir $dir1 || error "mkdir $dir1 failed"
10046
10047         # set a new striping pattern on root directory
10048         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10049
10050         $LFS setstripe -p $pool $dir1 ||
10051                 error "set directory layout on $dir1 failed"
10052
10053         # $dir1 layout includes pool
10054         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10055         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10056                 error "pool lost on setstripe"
10057         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10058         $LFS getstripe $dir1
10059         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10060                 error "pool lost on compound layout setstripe"
10061
10062         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10063                 error "setdirstripe failed on sub-dir with inherited pool"
10064         $LFS getstripe $dir1/dir2
10065         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10066                 error "pool lost on compound layout setdirstripe"
10067
10068         $LFS setstripe -E -1 -c 1 $dir1
10069         $LFS getstripe -d $dir1
10070         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10071                 error "pool lost on setstripe"
10072 }
10073 run_test 65o "pool inheritance for mdt component"
10074
10075 test_65p () { # LU-16152
10076         local src_dir=$DIR/$tdir/src_dir
10077         local dst_dir=$DIR/$tdir/dst_dir
10078         local yaml_file=$DIR/$tdir/layout.yaml
10079         local border
10080
10081         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10082                 skip "Need at least version 2.15.51"
10083
10084         test_mkdir -p $src_dir
10085         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10086                 error "failed to setstripe"
10087         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10088                 error "failed to getstripe"
10089
10090         test_mkdir -p $dst_dir
10091         $LFS setstripe --yaml $yaml_file $dst_dir ||
10092                 error "failed to setstripe with yaml file"
10093         border=$($LFS getstripe -d $dst_dir |
10094                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10095                 error "failed to getstripe"
10096
10097         # 2048M is 0x80000000, or 2147483648
10098         (( $border == 2147483648 )) ||
10099                 error "failed to handle huge number in yaml layout"
10100 }
10101 run_test 65p "setstripe with yaml file and huge number"
10102
10103 # bug 2543 - update blocks count on client
10104 test_66() {
10105         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10106
10107         local COUNT=${COUNT:-8}
10108         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10109         sync; sync_all_data; sync; sync_all_data
10110         cancel_lru_locks osc
10111         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10112         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10113 }
10114 run_test 66 "update inode blocks count on client ==============="
10115
10116 meminfo() {
10117         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10118 }
10119
10120 swap_used() {
10121         swapon -s | awk '($1 == "'$1'") { print $4 }'
10122 }
10123
10124 # bug5265, obdfilter oa2dentry return -ENOENT
10125 # #define OBD_FAIL_SRV_ENOENT 0x217
10126 test_69() {
10127         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10128         remote_ost_nodsh && skip "remote OST with nodsh"
10129
10130         f="$DIR/$tfile"
10131         $LFS setstripe -c 1 -i 0 $f
10132
10133         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10134
10135         do_facet ost1 lctl set_param fail_loc=0x217
10136         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10137         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10138
10139         do_facet ost1 lctl set_param fail_loc=0
10140         $DIRECTIO write $f 0 2 || error "write error"
10141
10142         cancel_lru_locks osc
10143         $DIRECTIO read $f 0 1 || error "read error"
10144
10145         do_facet ost1 lctl set_param fail_loc=0x217
10146         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10147
10148         do_facet ost1 lctl set_param fail_loc=0
10149         rm -f $f
10150 }
10151 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10152
10153 test_71() {
10154         test_mkdir $DIR/$tdir
10155         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10156         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10157 }
10158 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10159
10160 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10162         [ "$RUNAS_ID" = "$UID" ] &&
10163                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10164         # Check that testing environment is properly set up. Skip if not
10165         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10166                 skip_env "User $RUNAS_ID does not exist - skipping"
10167
10168         touch $DIR/$tfile
10169         chmod 777 $DIR/$tfile
10170         chmod ug+s $DIR/$tfile
10171         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10172                 error "$RUNAS dd $DIR/$tfile failed"
10173         # See if we are still setuid/sgid
10174         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10175                 error "S/gid is not dropped on write"
10176         # Now test that MDS is updated too
10177         cancel_lru_locks mdc
10178         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10179                 error "S/gid is not dropped on MDS"
10180         rm -f $DIR/$tfile
10181 }
10182 run_test 72a "Test that remove suid works properly (bug5695) ===="
10183
10184 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10185         local perm
10186
10187         [ "$RUNAS_ID" = "$UID" ] &&
10188                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10189         [ "$RUNAS_ID" -eq 0 ] &&
10190                 skip_env "RUNAS_ID = 0 -- skipping"
10191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10192         # Check that testing environment is properly set up. Skip if not
10193         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10194                 skip_env "User $RUNAS_ID does not exist - skipping"
10195
10196         touch $DIR/${tfile}-f{g,u}
10197         test_mkdir $DIR/${tfile}-dg
10198         test_mkdir $DIR/${tfile}-du
10199         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10200         chmod g+s $DIR/${tfile}-{f,d}g
10201         chmod u+s $DIR/${tfile}-{f,d}u
10202         for perm in 777 2777 4777; do
10203                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10204                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10205                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10206                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10207         done
10208         true
10209 }
10210 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10211
10212 # bug 3462 - multiple simultaneous MDC requests
10213 test_73() {
10214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10215
10216         test_mkdir $DIR/d73-1
10217         test_mkdir $DIR/d73-2
10218         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10219         pid1=$!
10220
10221         lctl set_param fail_loc=0x80000129
10222         $MULTIOP $DIR/d73-1/f73-2 Oc &
10223         sleep 1
10224         lctl set_param fail_loc=0
10225
10226         $MULTIOP $DIR/d73-2/f73-3 Oc &
10227         pid3=$!
10228
10229         kill -USR1 $pid1
10230         wait $pid1 || return 1
10231
10232         sleep 25
10233
10234         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10235         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10236         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10237
10238         rm -rf $DIR/d73-*
10239 }
10240 run_test 73 "multiple MDC requests (should not deadlock)"
10241
10242 test_74a() { # bug 6149, 6184
10243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10244
10245         touch $DIR/f74a
10246         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10247         #
10248         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10249         # will spin in a tight reconnection loop
10250         $LCTL set_param fail_loc=0x8000030e
10251         # get any lock that won't be difficult - lookup works.
10252         ls $DIR/f74a
10253         $LCTL set_param fail_loc=0
10254         rm -f $DIR/f74a
10255         true
10256 }
10257 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10258
10259 test_74b() { # bug 13310
10260         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10261
10262         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10263         #
10264         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10265         # will spin in a tight reconnection loop
10266         $LCTL set_param fail_loc=0x8000030e
10267         # get a "difficult" lock
10268         touch $DIR/f74b
10269         $LCTL set_param fail_loc=0
10270         rm -f $DIR/f74b
10271         true
10272 }
10273 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10274
10275 test_74c() {
10276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10277
10278         #define OBD_FAIL_LDLM_NEW_LOCK
10279         $LCTL set_param fail_loc=0x319
10280         touch $DIR/$tfile && error "touch successful"
10281         $LCTL set_param fail_loc=0
10282         true
10283 }
10284 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10285
10286 slab_lic=/sys/kernel/slab/lustre_inode_cache
10287 num_objects() {
10288         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10289         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10290                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10291 }
10292
10293 test_76a() { # Now for b=20433, added originally in b=1443
10294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10295
10296         cancel_lru_locks osc
10297         # there may be some slab objects cached per core
10298         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10299         local before=$(num_objects)
10300         local count=$((512 * cpus))
10301         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10302         local margin=$((count / 10))
10303         if [[ -f $slab_lic/aliases ]]; then
10304                 local aliases=$(cat $slab_lic/aliases)
10305                 (( aliases > 0 )) && margin=$((margin * aliases))
10306         fi
10307
10308         echo "before slab objects: $before"
10309         for i in $(seq $count); do
10310                 touch $DIR/$tfile
10311                 rm -f $DIR/$tfile
10312         done
10313         cancel_lru_locks osc
10314         local after=$(num_objects)
10315         echo "created: $count, after slab objects: $after"
10316         # shared slab counts are not very accurate, allow significant margin
10317         # the main goal is that the cache growth is not permanently > $count
10318         while (( after > before + margin )); do
10319                 sleep 1
10320                 after=$(num_objects)
10321                 wait=$((wait + 1))
10322                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10323                 if (( wait > 60 )); then
10324                         error "inode slab grew from $before+$margin to $after"
10325                 fi
10326         done
10327 }
10328 run_test 76a "confirm clients recycle inodes properly ===="
10329
10330 test_76b() {
10331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10332         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10333
10334         local count=512
10335         local before=$(num_objects)
10336
10337         for i in $(seq $count); do
10338                 mkdir $DIR/$tdir
10339                 rmdir $DIR/$tdir
10340         done
10341
10342         local after=$(num_objects)
10343         local wait=0
10344
10345         while (( after > before )); do
10346                 sleep 1
10347                 after=$(num_objects)
10348                 wait=$((wait + 1))
10349                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10350                 if (( wait > 60 )); then
10351                         error "inode slab grew from $before to $after"
10352                 fi
10353         done
10354
10355         echo "slab objects before: $before, after: $after"
10356 }
10357 run_test 76b "confirm clients recycle directory inodes properly ===="
10358
10359 export ORIG_CSUM=""
10360 set_checksums()
10361 {
10362         # Note: in sptlrpc modes which enable its own bulk checksum, the
10363         # original crc32_le bulk checksum will be automatically disabled,
10364         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10365         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10366         # In this case set_checksums() will not be no-op, because sptlrpc
10367         # bulk checksum will be enabled all through the test.
10368
10369         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10370         lctl set_param -n osc.*.checksums $1
10371         return 0
10372 }
10373
10374 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10375                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10376 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10377                              tr -d [] | head -n1)}
10378 set_checksum_type()
10379 {
10380         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10381         rc=$?
10382         log "set checksum type to $1, rc = $rc"
10383         return $rc
10384 }
10385
10386 get_osc_checksum_type()
10387 {
10388         # arugment 1: OST name, like OST0000
10389         ost=$1
10390         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10391                         sed 's/.*\[\(.*\)\].*/\1/g')
10392         rc=$?
10393         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10394         echo $checksum_type
10395 }
10396
10397 F77_TMP=$TMP/f77-temp
10398 F77SZ=8
10399 setup_f77() {
10400         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10401                 error "error writing to $F77_TMP"
10402 }
10403
10404 test_77a() { # bug 10889
10405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10406         $GSS && skip_env "could not run with gss"
10407
10408         [ ! -f $F77_TMP ] && setup_f77
10409         set_checksums 1
10410         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10411         set_checksums 0
10412         rm -f $DIR/$tfile
10413 }
10414 run_test 77a "normal checksum read/write operation"
10415
10416 test_77b() { # bug 10889
10417         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10418         $GSS && skip_env "could not run with gss"
10419
10420         [ ! -f $F77_TMP ] && setup_f77
10421         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10422         $LCTL set_param fail_loc=0x80000409
10423         set_checksums 1
10424
10425         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10426                 error "dd error: $?"
10427         $LCTL set_param fail_loc=0
10428
10429         for algo in $CKSUM_TYPES; do
10430                 cancel_lru_locks osc
10431                 set_checksum_type $algo
10432                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10433                 $LCTL set_param fail_loc=0x80000408
10434                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10435                 $LCTL set_param fail_loc=0
10436         done
10437         set_checksums 0
10438         set_checksum_type $ORIG_CSUM_TYPE
10439         rm -f $DIR/$tfile
10440 }
10441 run_test 77b "checksum error on client write, read"
10442
10443 cleanup_77c() {
10444         trap 0
10445         set_checksums 0
10446         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10447         $check_ost &&
10448                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10449         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10450         $check_ost && [ -n "$ost_file_prefix" ] &&
10451                 do_facet ost1 rm -f ${ost_file_prefix}\*
10452 }
10453
10454 test_77c() {
10455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10456         $GSS && skip_env "could not run with gss"
10457         remote_ost_nodsh && skip "remote OST with nodsh"
10458
10459         local bad1
10460         local osc_file_prefix
10461         local osc_file
10462         local check_ost=false
10463         local ost_file_prefix
10464         local ost_file
10465         local orig_cksum
10466         local dump_cksum
10467         local fid
10468
10469         # ensure corruption will occur on first OSS/OST
10470         $LFS setstripe -i 0 $DIR/$tfile
10471
10472         [ ! -f $F77_TMP ] && setup_f77
10473         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10474                 error "dd write error: $?"
10475         fid=$($LFS path2fid $DIR/$tfile)
10476
10477         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10478         then
10479                 check_ost=true
10480                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10481                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10482         else
10483                 echo "OSS do not support bulk pages dump upon error"
10484         fi
10485
10486         osc_file_prefix=$($LCTL get_param -n debug_path)
10487         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10488
10489         trap cleanup_77c EXIT
10490
10491         set_checksums 1
10492         # enable bulk pages dump upon error on Client
10493         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10494         # enable bulk pages dump upon error on OSS
10495         $check_ost &&
10496                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10497
10498         # flush Client cache to allow next read to reach OSS
10499         cancel_lru_locks osc
10500
10501         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10502         $LCTL set_param fail_loc=0x80000408
10503         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10504         $LCTL set_param fail_loc=0
10505
10506         rm -f $DIR/$tfile
10507
10508         # check cksum dump on Client
10509         osc_file=$(ls ${osc_file_prefix}*)
10510         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10511         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10512         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10513         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10514         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10515                      cksum)
10516         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10517         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10518                 error "dump content does not match on Client"
10519
10520         $check_ost || skip "No need to check cksum dump on OSS"
10521
10522         # check cksum dump on OSS
10523         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10524         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10525         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10526         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10527         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10528                 error "dump content does not match on OSS"
10529
10530         cleanup_77c
10531 }
10532 run_test 77c "checksum error on client read with debug"
10533
10534 test_77d() { # bug 10889
10535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10536         $GSS && skip_env "could not run with gss"
10537
10538         stack_trap "rm -f $DIR/$tfile"
10539         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10540         $LCTL set_param fail_loc=0x80000409
10541         set_checksums 1
10542         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10543                 error "direct write: rc=$?"
10544         $LCTL set_param fail_loc=0
10545         set_checksums 0
10546
10547         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10548         $LCTL set_param fail_loc=0x80000408
10549         set_checksums 1
10550         cancel_lru_locks osc
10551         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10552                 error "direct read: rc=$?"
10553         $LCTL set_param fail_loc=0
10554         set_checksums 0
10555 }
10556 run_test 77d "checksum error on OST direct write, read"
10557
10558 test_77f() { # bug 10889
10559         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10560         $GSS && skip_env "could not run with gss"
10561
10562         set_checksums 1
10563         stack_trap "rm -f $DIR/$tfile"
10564         for algo in $CKSUM_TYPES; do
10565                 cancel_lru_locks osc
10566                 set_checksum_type $algo
10567                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10568                 $LCTL set_param fail_loc=0x409
10569                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10570                         error "direct write succeeded"
10571                 $LCTL set_param fail_loc=0
10572         done
10573         set_checksum_type $ORIG_CSUM_TYPE
10574         set_checksums 0
10575 }
10576 run_test 77f "repeat checksum error on write (expect error)"
10577
10578 test_77g() { # bug 10889
10579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10580         $GSS && skip_env "could not run with gss"
10581         remote_ost_nodsh && skip "remote OST with nodsh"
10582
10583         [ ! -f $F77_TMP ] && setup_f77
10584
10585         local file=$DIR/$tfile
10586         stack_trap "rm -f $file" EXIT
10587
10588         $LFS setstripe -c 1 -i 0 $file
10589         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10590         do_facet ost1 lctl set_param fail_loc=0x8000021a
10591         set_checksums 1
10592         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10593                 error "write error: rc=$?"
10594         do_facet ost1 lctl set_param fail_loc=0
10595         set_checksums 0
10596
10597         cancel_lru_locks osc
10598         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10599         do_facet ost1 lctl set_param fail_loc=0x8000021b
10600         set_checksums 1
10601         cmp $F77_TMP $file || error "file compare failed"
10602         do_facet ost1 lctl set_param fail_loc=0
10603         set_checksums 0
10604 }
10605 run_test 77g "checksum error on OST write, read"
10606
10607 test_77k() { # LU-10906
10608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10609         $GSS && skip_env "could not run with gss"
10610
10611         local cksum_param="osc.$FSNAME*.checksums"
10612         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10613         local checksum
10614         local i
10615
10616         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10617         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10618         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10619
10620         for i in 0 1; do
10621                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10622                         error "failed to set checksum=$i on MGS"
10623                 wait_update $HOSTNAME "$get_checksum" $i
10624                 #remount
10625                 echo "remount client, checksum should be $i"
10626                 remount_client $MOUNT || error "failed to remount client"
10627                 checksum=$(eval $get_checksum)
10628                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10629         done
10630         # remove persistent param to avoid races with checksum mountopt below
10631         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10632                 error "failed to delete checksum on MGS"
10633
10634         for opt in "checksum" "nochecksum"; do
10635                 #remount with mount option
10636                 echo "remount client with option $opt, checksum should be $i"
10637                 umount_client $MOUNT || error "failed to umount client"
10638                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10639                         error "failed to mount client with option '$opt'"
10640                 checksum=$(eval $get_checksum)
10641                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10642                 i=$((i - 1))
10643         done
10644
10645         remount_client $MOUNT || error "failed to remount client"
10646 }
10647 run_test 77k "enable/disable checksum correctly"
10648
10649 test_77l() {
10650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10651         $GSS && skip_env "could not run with gss"
10652
10653         set_checksums 1
10654         stack_trap "set_checksums $ORIG_CSUM" EXIT
10655         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10656
10657         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10658
10659         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10660         for algo in $CKSUM_TYPES; do
10661                 set_checksum_type $algo || error "fail to set checksum type $algo"
10662                 osc_algo=$(get_osc_checksum_type OST0000)
10663                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10664
10665                 # no locks, no reqs to let the connection idle
10666                 cancel_lru_locks osc
10667                 lru_resize_disable osc
10668                 wait_osc_import_state client ost1 IDLE
10669
10670                 # ensure ost1 is connected
10671                 stat $DIR/$tfile >/dev/null || error "can't stat"
10672                 wait_osc_import_state client ost1 FULL
10673
10674                 osc_algo=$(get_osc_checksum_type OST0000)
10675                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10676         done
10677         return 0
10678 }
10679 run_test 77l "preferred checksum type is remembered after reconnected"
10680
10681 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10682 rm -f $F77_TMP
10683 unset F77_TMP
10684
10685 test_77m() {
10686         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10687                 skip "Need at least version 2.14.52"
10688         local param=checksum_speed
10689
10690         $LCTL get_param $param || error "reading $param failed"
10691
10692         csum_speeds=$($LCTL get_param -n $param)
10693
10694         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10695                 error "known checksum types are missing"
10696 }
10697 run_test 77m "Verify checksum_speed is correctly read"
10698
10699 check_filefrag_77n() {
10700         local nr_ext=0
10701         local starts=()
10702         local ends=()
10703
10704         while read extidx a b start end rest; do
10705                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10706                         nr_ext=$(( $nr_ext + 1 ))
10707                         starts+=( ${start%..} )
10708                         ends+=( ${end%:} )
10709                 fi
10710         done < <( filefrag -sv $1 )
10711
10712         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10713         return 1
10714 }
10715
10716 test_77n() {
10717         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10718
10719         touch $DIR/$tfile
10720         $TRUNCATE $DIR/$tfile 0
10721         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10722         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10723         check_filefrag_77n $DIR/$tfile ||
10724                 skip "$tfile blocks not contiguous around hole"
10725
10726         set_checksums 1
10727         stack_trap "set_checksums $ORIG_CSUM" EXIT
10728         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10729         stack_trap "rm -f $DIR/$tfile"
10730
10731         for algo in $CKSUM_TYPES; do
10732                 if [[ "$algo" =~ ^t10 ]]; then
10733                         set_checksum_type $algo ||
10734                                 error "fail to set checksum type $algo"
10735                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10736                                 error "fail to read $tfile with $algo"
10737                 fi
10738         done
10739         rm -f $DIR/$tfile
10740         return 0
10741 }
10742 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10743
10744 test_77o() {
10745         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10746                 skip "Need MDS version at least 2.14.55"
10747         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10748                 skip "Need OST version at least 2.14.55"
10749         local ofd=obdfilter
10750         local mdt=mdt
10751
10752         # print OST checksum_type
10753         echo "$ofd.$FSNAME-*.checksum_type:"
10754         do_nodes $(comma_list $(osts_nodes)) \
10755                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10756
10757         # print MDT checksum_type
10758         echo "$mdt.$FSNAME-*.checksum_type:"
10759         do_nodes $(comma_list $(mdts_nodes)) \
10760                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10761
10762         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10763                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10764
10765         (( $o_count == $OSTCOUNT )) ||
10766                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10767
10768         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10769                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10770
10771         (( $m_count == $MDSCOUNT )) ||
10772                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10773 }
10774 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10775
10776 cleanup_test_78() {
10777         trap 0
10778         rm -f $DIR/$tfile
10779 }
10780
10781 test_78() { # bug 10901
10782         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10783         remote_ost || skip_env "local OST"
10784
10785         NSEQ=5
10786         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10787         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10788         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10789         echo "MemTotal: $MEMTOTAL"
10790
10791         # reserve 256MB of memory for the kernel and other running processes,
10792         # and then take 1/2 of the remaining memory for the read/write buffers.
10793         if [ $MEMTOTAL -gt 512 ] ;then
10794                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10795         else
10796                 # for those poor memory-starved high-end clusters...
10797                 MEMTOTAL=$((MEMTOTAL / 2))
10798         fi
10799         echo "Mem to use for directio: $MEMTOTAL"
10800
10801         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10802         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10803         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10804         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10805                 head -n1)
10806         echo "Smallest OST: $SMALLESTOST"
10807         [[ $SMALLESTOST -lt 10240 ]] &&
10808                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10809
10810         trap cleanup_test_78 EXIT
10811
10812         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10813                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10814
10815         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10816         echo "File size: $F78SIZE"
10817         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10818         for i in $(seq 1 $NSEQ); do
10819                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10820                 echo directIO rdwr round $i of $NSEQ
10821                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10822         done
10823
10824         cleanup_test_78
10825 }
10826 run_test 78 "handle large O_DIRECT writes correctly ============"
10827
10828 test_79() { # bug 12743
10829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10830
10831         wait_delete_completed
10832
10833         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10834         BKFREE=$(calc_osc_kbytes kbytesfree)
10835         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10836
10837         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10838         DFTOTAL=`echo $STRING | cut -d, -f1`
10839         DFUSED=`echo $STRING  | cut -d, -f2`
10840         DFAVAIL=`echo $STRING | cut -d, -f3`
10841         DFFREE=$(($DFTOTAL - $DFUSED))
10842
10843         ALLOWANCE=$((64 * $OSTCOUNT))
10844
10845         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10846            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10847                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10848         fi
10849         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10850            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10851                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10852         fi
10853         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10854            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10855                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10856         fi
10857 }
10858 run_test 79 "df report consistency check ======================="
10859
10860 test_80() { # bug 10718
10861         remote_ost_nodsh && skip "remote OST with nodsh"
10862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10863
10864         # relax strong synchronous semantics for slow backends like ZFS
10865         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10866                 local soc="obdfilter.*.sync_lock_cancel"
10867                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10868
10869                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10870                 if [ -z "$save" ]; then
10871                         soc="obdfilter.*.sync_on_lock_cancel"
10872                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10873                 fi
10874
10875                 if [ "$save" != "never" ]; then
10876                         local hosts=$(comma_list $(osts_nodes))
10877
10878                         do_nodes $hosts $LCTL set_param $soc=never
10879                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10880                 fi
10881         fi
10882
10883         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10884         sync; sleep 1; sync
10885         local before=$(date +%s)
10886         cancel_lru_locks osc
10887         local after=$(date +%s)
10888         local diff=$((after - before))
10889         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10890
10891         rm -f $DIR/$tfile
10892 }
10893 run_test 80 "Page eviction is equally fast at high offsets too"
10894
10895 test_81a() { # LU-456
10896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10897         remote_ost_nodsh && skip "remote OST with nodsh"
10898
10899         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10900         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10901         do_facet ost1 lctl set_param fail_loc=0x80000228
10902
10903         # write should trigger a retry and success
10904         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10905         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10906         RC=$?
10907         if [ $RC -ne 0 ] ; then
10908                 error "write should success, but failed for $RC"
10909         fi
10910 }
10911 run_test 81a "OST should retry write when get -ENOSPC ==============="
10912
10913 test_81b() { # LU-456
10914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10915         remote_ost_nodsh && skip "remote OST with nodsh"
10916
10917         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10918         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10919         do_facet ost1 lctl set_param fail_loc=0x228
10920
10921         # write should retry several times and return -ENOSPC finally
10922         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10923         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10924         RC=$?
10925         ENOSPC=28
10926         if [ $RC -ne $ENOSPC ] ; then
10927                 error "dd should fail for -ENOSPC, but succeed."
10928         fi
10929 }
10930 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10931
10932 test_99() {
10933         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10934
10935         test_mkdir $DIR/$tdir.cvsroot
10936         chown $RUNAS_ID $DIR/$tdir.cvsroot
10937
10938         cd $TMP
10939         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10940
10941         cd /etc/init.d
10942         # some versions of cvs import exit(1) when asked to import links or
10943         # files they can't read.  ignore those files.
10944         local toignore=$(find . -type l -printf '-I %f\n' -o \
10945                          ! -perm /4 -printf '-I %f\n')
10946         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10947                 $tdir.reposname vtag rtag
10948
10949         cd $DIR
10950         test_mkdir $DIR/$tdir.reposname
10951         chown $RUNAS_ID $DIR/$tdir.reposname
10952         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10953
10954         cd $DIR/$tdir.reposname
10955         $RUNAS touch foo99
10956         $RUNAS cvs add -m 'addmsg' foo99
10957         $RUNAS cvs update
10958         $RUNAS cvs commit -m 'nomsg' foo99
10959         rm -fr $DIR/$tdir.cvsroot
10960 }
10961 run_test 99 "cvs strange file/directory operations"
10962
10963 test_100() {
10964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10965         [[ "$NETTYPE" =~ tcp ]] ||
10966                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10967         [[ -n "$(type -p ss)" ]] || skip_env "ss not available"
10968         remote_ost_nodsh && skip "remote OST with nodsh"
10969         remote_mds_nodsh && skip "remote MDS with nodsh"
10970         remote_servers || skip "useless for local single node setup"
10971
10972         ss -tna | ( rc=1; while read STATE SND RCV LOCAL REMOTE STAT; do
10973                 [[ "${REMOTE/*:/}" == "$ACCEPTOR_PORT" ]] || continue
10974
10975                 rc=0
10976                 if (( ${LOCAL/*:/} >= 1024 )); then
10977                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10978                         ss -tna
10979                         error "local: ${LOCAL/*:/} > 1024 remote: ${REMOTE/*:/}"
10980                 fi
10981         done
10982         (( $rc == 0 )) || error "privileged port not found" )
10983 }
10984 run_test 100 "check local port using privileged port"
10985
10986 function get_named_value()
10987 {
10988     local tag=$1
10989
10990     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10991 }
10992
10993 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10994                    awk '/^max_cached_mb/ { print $2 }')
10995
10996 cleanup_101a() {
10997         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10998         trap 0
10999 }
11000
11001 test_101a() {
11002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11003
11004         local s
11005         local discard
11006         local nreads=10000
11007         local cache_limit=32
11008
11009         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11010         trap cleanup_101a EXIT
11011         $LCTL set_param -n llite.*.read_ahead_stats=0
11012         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11013
11014         #
11015         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11016         #
11017         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11018         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11019
11020         discard=0
11021         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11022                    get_named_value 'read.but.discarded'); do
11023                         discard=$(($discard + $s))
11024         done
11025         cleanup_101a
11026
11027         $LCTL get_param osc.*-osc*.rpc_stats
11028         $LCTL get_param llite.*.read_ahead_stats
11029
11030         # Discard is generally zero, but sometimes a few random reads line up
11031         # and trigger larger readahead, which is wasted & leads to discards.
11032         if [[ $(($discard)) -gt $nreads ]]; then
11033                 error "too many ($discard) discarded pages"
11034         fi
11035         rm -f $DIR/$tfile || true
11036 }
11037 run_test 101a "check read-ahead for random reads"
11038
11039 setup_test101bc() {
11040         test_mkdir $DIR/$tdir
11041         local ssize=$1
11042         local FILE_LENGTH=$2
11043         STRIPE_OFFSET=0
11044
11045         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11046
11047         local list=$(comma_list $(osts_nodes))
11048         set_osd_param $list '' read_cache_enable 0
11049         set_osd_param $list '' writethrough_cache_enable 0
11050
11051         trap cleanup_test101bc EXIT
11052         # prepare the read-ahead file
11053         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11054
11055         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11056                                 count=$FILE_SIZE_MB 2> /dev/null
11057
11058 }
11059
11060 cleanup_test101bc() {
11061         trap 0
11062         rm -rf $DIR/$tdir
11063         rm -f $DIR/$tfile
11064
11065         local list=$(comma_list $(osts_nodes))
11066         set_osd_param $list '' read_cache_enable 1
11067         set_osd_param $list '' writethrough_cache_enable 1
11068 }
11069
11070 calc_total() {
11071         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11072 }
11073
11074 ra_check_101() {
11075         local read_size=$1
11076         local stripe_size=$2
11077         local stride_length=$((stripe_size / read_size))
11078         local stride_width=$((stride_length * OSTCOUNT))
11079         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11080                                 (stride_width - stride_length) ))
11081         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11082                   get_named_value 'read.but.discarded' | calc_total)
11083
11084         if [[ $discard -gt $discard_limit ]]; then
11085                 $LCTL get_param llite.*.read_ahead_stats
11086                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11087         else
11088                 echo "Read-ahead success for size ${read_size}"
11089         fi
11090 }
11091
11092 test_101b() {
11093         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11094         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11095
11096         local STRIPE_SIZE=1048576
11097         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11098
11099         if [ $SLOW == "yes" ]; then
11100                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11101         else
11102                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11103         fi
11104
11105         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11106
11107         # prepare the read-ahead file
11108         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11109         cancel_lru_locks osc
11110         for BIDX in 2 4 8 16 32 64 128 256
11111         do
11112                 local BSIZE=$((BIDX*4096))
11113                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11114                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11115                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11116                 $LCTL set_param -n llite.*.read_ahead_stats=0
11117                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11118                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11119                 cancel_lru_locks osc
11120                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11121         done
11122         cleanup_test101bc
11123         true
11124 }
11125 run_test 101b "check stride-io mode read-ahead ================="
11126
11127 test_101c() {
11128         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11129
11130         local STRIPE_SIZE=1048576
11131         local FILE_LENGTH=$((STRIPE_SIZE*100))
11132         local nreads=10000
11133         local rsize=65536
11134         local osc_rpc_stats
11135
11136         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11137
11138         cancel_lru_locks osc
11139         $LCTL set_param osc.*.rpc_stats=0
11140         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11141         $LCTL get_param osc.*.rpc_stats
11142         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11143                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11144                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11145                 local size
11146
11147                 if [ $lines -le 20 ]; then
11148                         echo "continue debug"
11149                         continue
11150                 fi
11151                 for size in 1 2 4 8; do
11152                         local rpc=$(echo "$stats" |
11153                                     awk '($1 == "'$size':") {print $2; exit; }')
11154                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11155                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11156                 done
11157                 echo "$osc_rpc_stats check passed!"
11158         done
11159         cleanup_test101bc
11160         true
11161 }
11162 run_test 101c "check stripe_size aligned read-ahead"
11163
11164 test_101d() {
11165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11166
11167         local file=$DIR/$tfile
11168         local sz_MB=${FILESIZE_101d:-80}
11169         local ra_MB=${READAHEAD_MB:-40}
11170
11171         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11172         [ $free_MB -lt $sz_MB ] &&
11173                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11174
11175         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11176         $LFS setstripe -c -1 $file || error "setstripe failed"
11177
11178         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11179         echo Cancel LRU locks on lustre client to flush the client cache
11180         cancel_lru_locks osc
11181
11182         echo Disable read-ahead
11183         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11184         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11185         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11186         $LCTL get_param -n llite.*.max_read_ahead_mb
11187
11188         echo "Reading the test file $file with read-ahead disabled"
11189         local sz_KB=$((sz_MB * 1024 / 4))
11190         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11191         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11192         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11193                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11194
11195         echo "Cancel LRU locks on lustre client to flush the client cache"
11196         cancel_lru_locks osc
11197         echo Enable read-ahead with ${ra_MB}MB
11198         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11199
11200         echo "Reading the test file $file with read-ahead enabled"
11201         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11202                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11203
11204         echo "read-ahead disabled time read $raOFF"
11205         echo "read-ahead enabled time read $raON"
11206
11207         rm -f $file
11208         wait_delete_completed
11209
11210         # use awk for this check instead of bash because it handles decimals
11211         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11212                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11213 }
11214 run_test 101d "file read with and without read-ahead enabled"
11215
11216 test_101e() {
11217         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11218
11219         local file=$DIR/$tfile
11220         local size_KB=500  #KB
11221         local count=100
11222         local bsize=1024
11223
11224         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11225         local need_KB=$((count * size_KB))
11226         [[ $free_KB -le $need_KB ]] &&
11227                 skip_env "Need free space $need_KB, have $free_KB"
11228
11229         echo "Creating $count ${size_KB}K test files"
11230         for ((i = 0; i < $count; i++)); do
11231                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11232         done
11233
11234         echo "Cancel LRU locks on lustre client to flush the client cache"
11235         cancel_lru_locks $OSC
11236
11237         echo "Reset readahead stats"
11238         $LCTL set_param -n llite.*.read_ahead_stats=0
11239
11240         for ((i = 0; i < $count; i++)); do
11241                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11242         done
11243
11244         $LCTL get_param llite.*.max_cached_mb
11245         $LCTL get_param llite.*.read_ahead_stats
11246         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11247                      get_named_value 'misses' | calc_total)
11248
11249         for ((i = 0; i < $count; i++)); do
11250                 rm -rf $file.$i 2>/dev/null
11251         done
11252
11253         #10000 means 20% reads are missing in readahead
11254         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11255 }
11256 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11257
11258 test_101f() {
11259         which iozone || skip_env "no iozone installed"
11260
11261         local old_debug=$($LCTL get_param debug)
11262         old_debug=${old_debug#*=}
11263         $LCTL set_param debug="reada mmap"
11264
11265         # create a test file
11266         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11267
11268         echo Cancel LRU locks on lustre client to flush the client cache
11269         cancel_lru_locks osc
11270
11271         echo Reset readahead stats
11272         $LCTL set_param -n llite.*.read_ahead_stats=0
11273
11274         echo mmap read the file with small block size
11275         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11276                 > /dev/null 2>&1
11277
11278         echo checking missing pages
11279         $LCTL get_param llite.*.read_ahead_stats
11280         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11281                         get_named_value 'misses' | calc_total)
11282
11283         $LCTL set_param debug="$old_debug"
11284         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11285         rm -f $DIR/$tfile
11286 }
11287 run_test 101f "check mmap read performance"
11288
11289 test_101g_brw_size_test() {
11290         local mb=$1
11291         local pages=$((mb * 1048576 / PAGE_SIZE))
11292         local file=$DIR/$tfile
11293
11294         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11295                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11296         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11297                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11298                         return 2
11299         done
11300
11301         stack_trap "rm -f $file" EXIT
11302         $LCTL set_param -n osc.*.rpc_stats=0
11303
11304         # 10 RPCs should be enough for the test
11305         local count=10
11306         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11307                 { error "dd write ${mb} MB blocks failed"; return 3; }
11308         cancel_lru_locks osc
11309         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11310                 { error "dd write ${mb} MB blocks failed"; return 4; }
11311
11312         # calculate number of full-sized read and write RPCs
11313         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11314                 sed -n '/pages per rpc/,/^$/p' |
11315                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11316                 END { print reads,writes }'))
11317         # allow one extra full-sized read RPC for async readahead
11318         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11319                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11320         [[ ${rpcs[1]} == $count ]] ||
11321                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11322 }
11323
11324 test_101g() {
11325         remote_ost_nodsh && skip "remote OST with nodsh"
11326
11327         local rpcs
11328         local osts=$(get_facets OST)
11329         local list=$(comma_list $(osts_nodes))
11330         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11331         local brw_size="obdfilter.*.brw_size"
11332
11333         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11334
11335         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11336
11337         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11338                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11339                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11340            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11341                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11342                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11343
11344                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11345                         suffix="M"
11346
11347                 if [[ $orig_mb -lt 16 ]]; then
11348                         save_lustre_params $osts "$brw_size" > $p
11349                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11350                                 error "set 16MB RPC size failed"
11351
11352                         echo "remount client to enable new RPC size"
11353                         remount_client $MOUNT || error "remount_client failed"
11354                 fi
11355
11356                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11357                 # should be able to set brw_size=12, but no rpc_stats for that
11358                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11359         fi
11360
11361         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11362
11363         if [[ $orig_mb -lt 16 ]]; then
11364                 restore_lustre_params < $p
11365                 remount_client $MOUNT || error "remount_client restore failed"
11366         fi
11367
11368         rm -f $p $DIR/$tfile
11369 }
11370 run_test 101g "Big bulk(4/16 MiB) readahead"
11371
11372 test_101h() {
11373         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11374
11375         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11376                 error "dd 70M file failed"
11377         echo Cancel LRU locks on lustre client to flush the client cache
11378         cancel_lru_locks osc
11379
11380         echo "Reset readahead stats"
11381         $LCTL set_param -n llite.*.read_ahead_stats 0
11382
11383         echo "Read 10M of data but cross 64M bundary"
11384         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11385         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11386                      get_named_value 'misses' | calc_total)
11387         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11388         rm -f $p $DIR/$tfile
11389 }
11390 run_test 101h "Readahead should cover current read window"
11391
11392 test_101i() {
11393         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11394                 error "dd 10M file failed"
11395
11396         local max_per_file_mb=$($LCTL get_param -n \
11397                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11398         cancel_lru_locks osc
11399         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11400         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11401                 error "set max_read_ahead_per_file_mb to 1 failed"
11402
11403         echo "Reset readahead stats"
11404         $LCTL set_param llite.*.read_ahead_stats=0
11405
11406         dd if=$DIR/$tfile of=/dev/null bs=2M
11407
11408         $LCTL get_param llite.*.read_ahead_stats
11409         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11410                      awk '/misses/ { print $2 }')
11411         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11412         rm -f $DIR/$tfile
11413 }
11414 run_test 101i "allow current readahead to exceed reservation"
11415
11416 test_101j() {
11417         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11418                 error "setstripe $DIR/$tfile failed"
11419         local file_size=$((1048576 * 16))
11420         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11421         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11422
11423         echo Disable read-ahead
11424         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11425
11426         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11427         for blk in $PAGE_SIZE 1048576 $file_size; do
11428                 cancel_lru_locks osc
11429                 echo "Reset readahead stats"
11430                 $LCTL set_param -n llite.*.read_ahead_stats=0
11431                 local count=$(($file_size / $blk))
11432                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11433                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11434                              get_named_value 'failed.to.fast.read' | calc_total)
11435                 $LCTL get_param -n llite.*.read_ahead_stats
11436                 [ $miss -eq $count ] || error "expected $count got $miss"
11437         done
11438
11439         rm -f $p $DIR/$tfile
11440 }
11441 run_test 101j "A complete read block should be submitted when no RA"
11442
11443 test_readahead_base() {
11444         local file=$DIR/$tfile
11445         local size=$1
11446         local iosz
11447         local ramax
11448         local ranum
11449
11450         $LCTL set_param -n llite.*.read_ahead_stats=0
11451         # The first page is not accounted into readahead
11452         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11453         iosz=$(((size + 1048575) / 1048576 * 1048576))
11454         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11455
11456         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11457         fallocate -l $size $file || error "failed to fallocate $file"
11458         cancel_lru_locks osc
11459         $MULTIOP $file or${iosz}c || error "failed to read $file"
11460         $LCTL get_param -n llite.*.read_ahead_stats
11461         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11462                 awk '/readahead.pages/ { print $7 }' | calc_total)
11463         (( $ranum <= $ramax )) ||
11464                 error "read-ahead pages is $ranum more than $ramax"
11465         rm -rf $file || error "failed to remove $file"
11466 }
11467
11468 test_101m()
11469 {
11470         local file=$DIR/$tfile
11471         local ramax
11472         local ranum
11473         local size
11474         local iosz
11475
11476         check_set_fallocate_or_skip
11477         stack_trap "rm -f $file" EXIT
11478
11479         test_readahead_base 4096
11480
11481         # file size: 16K = 16384
11482         test_readahead_base 16384
11483         test_readahead_base 16385
11484         test_readahead_base 16383
11485
11486         # file size: 1M + 1 = 1048576 + 1
11487         test_readahead_base 1048577
11488         # file size: 1M + 16K
11489         test_readahead_base $((1048576 + 16384))
11490
11491         # file size: stripe_size * (stripe_count - 1) + 16K
11492         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11493         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11494         # file size: stripe_size * stripe_count + 16K
11495         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11496         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11497         # file size: 2 * stripe_size * stripe_count + 16K
11498         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11499         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11500 }
11501 run_test 101m "read ahead for small file and last stripe of the file"
11502
11503 setup_test102() {
11504         test_mkdir $DIR/$tdir
11505         chown $RUNAS_ID $DIR/$tdir
11506         STRIPE_SIZE=65536
11507         STRIPE_OFFSET=1
11508         STRIPE_COUNT=$OSTCOUNT
11509         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11510
11511         trap cleanup_test102 EXIT
11512         cd $DIR
11513         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11514         cd $DIR/$tdir
11515         for num in 1 2 3 4; do
11516                 for count in $(seq 1 $STRIPE_COUNT); do
11517                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11518                                 local size=`expr $STRIPE_SIZE \* $num`
11519                                 local file=file"$num-$idx-$count"
11520                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11521                         done
11522                 done
11523         done
11524
11525         cd $DIR
11526         $1 tar cf $TMP/f102.tar $tdir --xattrs
11527 }
11528
11529 cleanup_test102() {
11530         trap 0
11531         rm -f $TMP/f102.tar
11532         rm -rf $DIR/d0.sanity/d102
11533 }
11534
11535 test_102a() {
11536         [ "$UID" != 0 ] && skip "must run as root"
11537         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11538                 skip_env "must have user_xattr"
11539
11540         [ -z "$(which setfattr 2>/dev/null)" ] &&
11541                 skip_env "could not find setfattr"
11542
11543         local testfile=$DIR/$tfile
11544
11545         touch $testfile
11546         echo "set/get xattr..."
11547         setfattr -n trusted.name1 -v value1 $testfile ||
11548                 error "setfattr -n trusted.name1=value1 $testfile failed"
11549         getfattr -n trusted.name1 $testfile 2> /dev/null |
11550           grep "trusted.name1=.value1" ||
11551                 error "$testfile missing trusted.name1=value1"
11552
11553         setfattr -n user.author1 -v author1 $testfile ||
11554                 error "setfattr -n user.author1=author1 $testfile failed"
11555         getfattr -n user.author1 $testfile 2> /dev/null |
11556           grep "user.author1=.author1" ||
11557                 error "$testfile missing trusted.author1=author1"
11558
11559         echo "listxattr..."
11560         setfattr -n trusted.name2 -v value2 $testfile ||
11561                 error "$testfile unable to set trusted.name2"
11562         setfattr -n trusted.name3 -v value3 $testfile ||
11563                 error "$testfile unable to set trusted.name3"
11564         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11565             grep "trusted.name" | wc -l) -eq 3 ] ||
11566                 error "$testfile missing 3 trusted.name xattrs"
11567
11568         setfattr -n user.author2 -v author2 $testfile ||
11569                 error "$testfile unable to set user.author2"
11570         setfattr -n user.author3 -v author3 $testfile ||
11571                 error "$testfile unable to set user.author3"
11572         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11573             grep "user.author" | wc -l) -eq 3 ] ||
11574                 error "$testfile missing 3 user.author xattrs"
11575
11576         echo "remove xattr..."
11577         setfattr -x trusted.name1 $testfile ||
11578                 error "$testfile error deleting trusted.name1"
11579         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11580                 error "$testfile did not delete trusted.name1 xattr"
11581
11582         setfattr -x user.author1 $testfile ||
11583                 error "$testfile error deleting user.author1"
11584         echo "set lustre special xattr ..."
11585         $LFS setstripe -c1 $testfile
11586         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11587                 awk -F "=" '/trusted.lov/ { print $2 }' )
11588         setfattr -n "trusted.lov" -v $lovea $testfile ||
11589                 error "$testfile doesn't ignore setting trusted.lov again"
11590         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11591                 error "$testfile allow setting invalid trusted.lov"
11592         rm -f $testfile
11593 }
11594 run_test 102a "user xattr test =================================="
11595
11596 check_102b_layout() {
11597         local layout="$*"
11598         local testfile=$DIR/$tfile
11599
11600         echo "test layout '$layout'"
11601         $LFS setstripe $layout $testfile || error "setstripe failed"
11602         $LFS getstripe -y $testfile
11603
11604         echo "get/set/list trusted.lov xattr ..." # b=10930
11605         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11606         [[ "$value" =~ "trusted.lov" ]] ||
11607                 error "can't get trusted.lov from $testfile"
11608         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11609                 error "getstripe failed"
11610
11611         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11612
11613         value=$(cut -d= -f2 <<<$value)
11614         # LU-13168: truncated xattr should fail if short lov_user_md header
11615         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11616                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11617         for len in $lens; do
11618                 echo "setfattr $len $testfile.2"
11619                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11620                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11621         done
11622         local stripe_size=$($LFS getstripe -S $testfile.2)
11623         local stripe_count=$($LFS getstripe -c $testfile.2)
11624         [[ $stripe_size -eq 65536 ]] ||
11625                 error "stripe size $stripe_size != 65536"
11626         [[ $stripe_count -eq $stripe_count_orig ]] ||
11627                 error "stripe count $stripe_count != $stripe_count_orig"
11628         rm $testfile $testfile.2
11629 }
11630
11631 test_102b() {
11632         [ -z "$(which setfattr 2>/dev/null)" ] &&
11633                 skip_env "could not find setfattr"
11634         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11635
11636         # check plain layout
11637         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11638
11639         # and also check composite layout
11640         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11641
11642 }
11643 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11644
11645 test_102c() {
11646         [ -z "$(which setfattr 2>/dev/null)" ] &&
11647                 skip_env "could not find setfattr"
11648         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11649
11650         # b10930: get/set/list lustre.lov xattr
11651         echo "get/set/list lustre.lov xattr ..."
11652         test_mkdir $DIR/$tdir
11653         chown $RUNAS_ID $DIR/$tdir
11654         local testfile=$DIR/$tdir/$tfile
11655         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11656                 error "setstripe failed"
11657         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11658                 error "getstripe failed"
11659         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11660         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11661
11662         local testfile2=${testfile}2
11663         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11664                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11665
11666         $RUNAS $MCREATE $testfile2
11667         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11668         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11669         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11670         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11671         [ $stripe_count -eq $STRIPECOUNT ] ||
11672                 error "stripe count $stripe_count != $STRIPECOUNT"
11673 }
11674 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11675
11676 compare_stripe_info1() {
11677         local stripe_index_all_zero=true
11678
11679         for num in 1 2 3 4; do
11680                 for count in $(seq 1 $STRIPE_COUNT); do
11681                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11682                                 local size=$((STRIPE_SIZE * num))
11683                                 local file=file"$num-$offset-$count"
11684                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11685                                 [[ $stripe_size -ne $size ]] &&
11686                                     error "$file: size $stripe_size != $size"
11687                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11688                                 # allow fewer stripes to be created, ORI-601
11689                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11690                                     error "$file: count $stripe_count != $count"
11691                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11692                                 [[ $stripe_index -ne 0 ]] &&
11693                                         stripe_index_all_zero=false
11694                         done
11695                 done
11696         done
11697         $stripe_index_all_zero &&
11698                 error "all files are being extracted starting from OST index 0"
11699         return 0
11700 }
11701
11702 have_xattrs_include() {
11703         tar --help | grep -q xattrs-include &&
11704                 echo --xattrs-include="lustre.*"
11705 }
11706
11707 test_102d() {
11708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11709         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11710
11711         XINC=$(have_xattrs_include)
11712         setup_test102
11713         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11714         cd $DIR/$tdir/$tdir
11715         compare_stripe_info1
11716 }
11717 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11718
11719 test_102f() {
11720         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11721         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11722
11723         XINC=$(have_xattrs_include)
11724         setup_test102
11725         test_mkdir $DIR/$tdir.restore
11726         cd $DIR
11727         tar cf - --xattrs $tdir | tar xf - \
11728                 -C $DIR/$tdir.restore --xattrs $XINC
11729         cd $DIR/$tdir.restore/$tdir
11730         compare_stripe_info1
11731 }
11732 run_test 102f "tar copy files, not keep osts"
11733
11734 grow_xattr() {
11735         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11736                 skip "must have user_xattr"
11737         [ -z "$(which setfattr 2>/dev/null)" ] &&
11738                 skip_env "could not find setfattr"
11739         [ -z "$(which getfattr 2>/dev/null)" ] &&
11740                 skip_env "could not find getfattr"
11741
11742         local xsize=${1:-1024}  # in bytes
11743         local file=$DIR/$tfile
11744         local value="$(generate_string $xsize)"
11745         local xbig=trusted.big
11746         local toobig=$2
11747
11748         touch $file
11749         log "save $xbig on $file"
11750         if [ -z "$toobig" ]
11751         then
11752                 setfattr -n $xbig -v $value $file ||
11753                         error "saving $xbig on $file failed"
11754         else
11755                 setfattr -n $xbig -v $value $file &&
11756                         error "saving $xbig on $file succeeded"
11757                 return 0
11758         fi
11759
11760         local orig=$(get_xattr_value $xbig $file)
11761         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11762
11763         local xsml=trusted.sml
11764         log "save $xsml on $file"
11765         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11766
11767         local new=$(get_xattr_value $xbig $file)
11768         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11769
11770         log "grow $xsml on $file"
11771         setfattr -n $xsml -v "$value" $file ||
11772                 error "growing $xsml on $file failed"
11773
11774         new=$(get_xattr_value $xbig $file)
11775         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11776         log "$xbig still valid after growing $xsml"
11777
11778         rm -f $file
11779 }
11780
11781 test_102h() { # bug 15777
11782         grow_xattr 1024
11783 }
11784 run_test 102h "grow xattr from inside inode to external block"
11785
11786 test_102ha() {
11787         large_xattr_enabled || skip_env "ea_inode feature disabled"
11788
11789         echo "setting xattr of max xattr size: $(max_xattr_size)"
11790         grow_xattr $(max_xattr_size)
11791
11792         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11793         echo "This should fail:"
11794         grow_xattr $(($(max_xattr_size) + 10)) 1
11795 }
11796 run_test 102ha "grow xattr from inside inode to external inode"
11797
11798 test_102i() { # bug 17038
11799         [ -z "$(which getfattr 2>/dev/null)" ] &&
11800                 skip "could not find getfattr"
11801
11802         touch $DIR/$tfile
11803         ln -s $DIR/$tfile $DIR/${tfile}link
11804         getfattr -n trusted.lov $DIR/$tfile ||
11805                 error "lgetxattr on $DIR/$tfile failed"
11806         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11807                 grep -i "no such attr" ||
11808                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11809         rm -f $DIR/$tfile $DIR/${tfile}link
11810 }
11811 run_test 102i "lgetxattr test on symbolic link ============"
11812
11813 test_102j() {
11814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11815         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11816
11817         XINC=$(have_xattrs_include)
11818         setup_test102 "$RUNAS"
11819         chown $RUNAS_ID $DIR/$tdir
11820         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11821         cd $DIR/$tdir/$tdir
11822         compare_stripe_info1 "$RUNAS"
11823 }
11824 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11825
11826 test_102k() {
11827         [ -z "$(which setfattr 2>/dev/null)" ] &&
11828                 skip "could not find setfattr"
11829
11830         touch $DIR/$tfile
11831         # b22187 just check that does not crash for regular file.
11832         setfattr -n trusted.lov $DIR/$tfile
11833         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11834         local test_kdir=$DIR/$tdir
11835         test_mkdir $test_kdir
11836         local default_size=$($LFS getstripe -S $test_kdir)
11837         local default_count=$($LFS getstripe -c $test_kdir)
11838         local default_offset=$($LFS getstripe -i $test_kdir)
11839         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11840                 error 'dir setstripe failed'
11841         setfattr -n trusted.lov $test_kdir
11842         local stripe_size=$($LFS getstripe -S $test_kdir)
11843         local stripe_count=$($LFS getstripe -c $test_kdir)
11844         local stripe_offset=$($LFS getstripe -i $test_kdir)
11845         [ $stripe_size -eq $default_size ] ||
11846                 error "stripe size $stripe_size != $default_size"
11847         [ $stripe_count -eq $default_count ] ||
11848                 error "stripe count $stripe_count != $default_count"
11849         [ $stripe_offset -eq $default_offset ] ||
11850                 error "stripe offset $stripe_offset != $default_offset"
11851         rm -rf $DIR/$tfile $test_kdir
11852 }
11853 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11854
11855 test_102l() {
11856         [ -z "$(which getfattr 2>/dev/null)" ] &&
11857                 skip "could not find getfattr"
11858
11859         # LU-532 trusted. xattr is invisible to non-root
11860         local testfile=$DIR/$tfile
11861
11862         touch $testfile
11863
11864         echo "listxattr as user..."
11865         chown $RUNAS_ID $testfile
11866         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11867             grep -q "trusted" &&
11868                 error "$testfile trusted xattrs are user visible"
11869
11870         return 0;
11871 }
11872 run_test 102l "listxattr size test =================================="
11873
11874 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11875         local path=$DIR/$tfile
11876         touch $path
11877
11878         listxattr_size_check $path || error "listattr_size_check $path failed"
11879 }
11880 run_test 102m "Ensure listxattr fails on small bufffer ========"
11881
11882 cleanup_test102
11883
11884 getxattr() { # getxattr path name
11885         # Return the base64 encoding of the value of xattr name on path.
11886         local path=$1
11887         local name=$2
11888
11889         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11890         # file: $path
11891         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11892         #
11893         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11894
11895         getfattr --absolute-names --encoding=base64 --name=$name $path |
11896                 awk -F= -v name=$name '$1 == name {
11897                         print substr($0, index($0, "=") + 1);
11898         }'
11899 }
11900
11901 test_102n() { # LU-4101 mdt: protect internal xattrs
11902         [ -z "$(which setfattr 2>/dev/null)" ] &&
11903                 skip "could not find setfattr"
11904         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11905         then
11906                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11907         fi
11908
11909         local file0=$DIR/$tfile.0
11910         local file1=$DIR/$tfile.1
11911         local xattr0=$TMP/$tfile.0
11912         local xattr1=$TMP/$tfile.1
11913         local namelist="lov lma lmv link fid version som hsm"
11914         local name
11915         local value
11916
11917         rm -rf $file0 $file1 $xattr0 $xattr1
11918         touch $file0 $file1
11919
11920         # Get 'before' xattrs of $file1.
11921         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11922
11923         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11924                 namelist+=" lfsck_namespace"
11925         for name in $namelist; do
11926                 # Try to copy xattr from $file0 to $file1.
11927                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11928
11929                 setfattr --name=trusted.$name --value="$value" $file1 ||
11930                         error "setxattr 'trusted.$name' failed"
11931
11932                 # Try to set a garbage xattr.
11933                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11934
11935                 if [[ x$name == "xlov" ]]; then
11936                         setfattr --name=trusted.lov --value="$value" $file1 &&
11937                         error "setxattr invalid 'trusted.lov' success"
11938                 else
11939                         setfattr --name=trusted.$name --value="$value" $file1 ||
11940                                 error "setxattr invalid 'trusted.$name' failed"
11941                 fi
11942
11943                 # Try to remove the xattr from $file1. We don't care if this
11944                 # appears to succeed or fail, we just don't want there to be
11945                 # any changes or crashes.
11946                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11947         done
11948
11949         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11950         then
11951                 name="lfsck_ns"
11952                 # Try to copy xattr from $file0 to $file1.
11953                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11954
11955                 setfattr --name=trusted.$name --value="$value" $file1 ||
11956                         error "setxattr 'trusted.$name' failed"
11957
11958                 # Try to set a garbage xattr.
11959                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11960
11961                 setfattr --name=trusted.$name --value="$value" $file1 ||
11962                         error "setxattr 'trusted.$name' failed"
11963
11964                 # Try to remove the xattr from $file1. We don't care if this
11965                 # appears to succeed or fail, we just don't want there to be
11966                 # any changes or crashes.
11967                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11968         fi
11969
11970         # Get 'after' xattrs of file1.
11971         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11972
11973         if ! diff $xattr0 $xattr1; then
11974                 error "before and after xattrs of '$file1' differ"
11975         fi
11976
11977         rm -rf $file0 $file1 $xattr0 $xattr1
11978
11979         return 0
11980 }
11981 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11982
11983 test_102p() { # LU-4703 setxattr did not check ownership
11984         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11985                 skip "MDS needs to be at least 2.5.56"
11986
11987         local testfile=$DIR/$tfile
11988
11989         touch $testfile
11990
11991         echo "setfacl as user..."
11992         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11993         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11994
11995         echo "setfattr as user..."
11996         setfacl -m "u:$RUNAS_ID:---" $testfile
11997         $RUNAS setfattr -x system.posix_acl_access $testfile
11998         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11999 }
12000 run_test 102p "check setxattr(2) correctly fails without permission"
12001
12002 test_102q() {
12003         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12004                 skip "MDS needs to be at least 2.6.92"
12005
12006         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12007 }
12008 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12009
12010 test_102r() {
12011         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12012                 skip "MDS needs to be at least 2.6.93"
12013
12014         touch $DIR/$tfile || error "touch"
12015         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12016         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12017         rm $DIR/$tfile || error "rm"
12018
12019         #normal directory
12020         mkdir -p $DIR/$tdir || error "mkdir"
12021         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12022         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12023         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12024                 error "$testfile error deleting user.author1"
12025         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12026                 grep "user.$(basename $tdir)" &&
12027                 error "$tdir did not delete user.$(basename $tdir)"
12028         rmdir $DIR/$tdir || error "rmdir"
12029
12030         #striped directory
12031         test_mkdir $DIR/$tdir
12032         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12033         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12034         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12035                 error "$testfile error deleting user.author1"
12036         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12037                 grep "user.$(basename $tdir)" &&
12038                 error "$tdir did not delete user.$(basename $tdir)"
12039         rmdir $DIR/$tdir || error "rm striped dir"
12040 }
12041 run_test 102r "set EAs with empty values"
12042
12043 test_102s() {
12044         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12045                 skip "MDS needs to be at least 2.11.52"
12046
12047         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12048
12049         save_lustre_params client "llite.*.xattr_cache" > $save
12050
12051         for cache in 0 1; do
12052                 lctl set_param llite.*.xattr_cache=$cache
12053
12054                 rm -f $DIR/$tfile
12055                 touch $DIR/$tfile || error "touch"
12056                 for prefix in lustre security system trusted user; do
12057                         # Note getxattr() may fail with 'Operation not
12058                         # supported' or 'No such attribute' depending
12059                         # on prefix and cache.
12060                         getfattr -n $prefix.n102s $DIR/$tfile &&
12061                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12062                 done
12063         done
12064
12065         restore_lustre_params < $save
12066 }
12067 run_test 102s "getting nonexistent xattrs should fail"
12068
12069 test_102t() {
12070         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12071                 skip "MDS needs to be at least 2.11.52"
12072
12073         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12074
12075         save_lustre_params client "llite.*.xattr_cache" > $save
12076
12077         for cache in 0 1; do
12078                 lctl set_param llite.*.xattr_cache=$cache
12079
12080                 for buf_size in 0 256; do
12081                         rm -f $DIR/$tfile
12082                         touch $DIR/$tfile || error "touch"
12083                         setfattr -n user.multiop $DIR/$tfile
12084                         $MULTIOP $DIR/$tfile oa$buf_size ||
12085                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12086                 done
12087         done
12088
12089         restore_lustre_params < $save
12090 }
12091 run_test 102t "zero length xattr values handled correctly"
12092
12093 run_acl_subtest()
12094 {
12095         local test=$LUSTRE/tests/acl/$1.test
12096         local tmp=$(mktemp -t $1-XXXXXX).test
12097         local bin=$2
12098         local dmn=$3
12099         local grp=$4
12100         local nbd=$5
12101         export LANG=C
12102
12103
12104         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12105         local sedgroups="-e s/:users/:$grp/g"
12106         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12107
12108         sed $sedusers $sedgroups < $test > $tmp
12109         stack_trap "rm -f $tmp"
12110         [[ -s $tmp ]] || error "sed failed to create test script"
12111
12112         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12113         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12114 }
12115
12116 test_103a() {
12117         [ "$UID" != 0 ] && skip "must run as root"
12118         $GSS && skip_env "could not run under gss"
12119         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12120                 skip_env "must have acl enabled"
12121         which setfacl || skip_env "could not find setfacl"
12122         remote_mds_nodsh && skip "remote MDS with nodsh"
12123
12124         ACLBIN=${ACLBIN:-"bin"}
12125         ACLDMN=${ACLDMN:-"daemon"}
12126         ACLGRP=${ACLGRP:-"users"}
12127         ACLNBD=${ACLNBD:-"nobody"}
12128
12129         if ! id $ACLBIN ||
12130            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12131                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12132                 ACLBIN=$USER0
12133                 if ! id $ACLBIN ; then
12134                         cat /etc/passwd
12135                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12136                 fi
12137         fi
12138         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12139            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12140                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12141                 ACLDMN=$USER1
12142                 if ! id $ACLDMN ; then
12143                         cat /etc/passwd
12144                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12145                 fi
12146         fi
12147         if ! getent group $ACLGRP; then
12148                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12149                 ACLGRP="$TSTUSR"
12150                 if ! getent group $ACLGRP; then
12151                         echo "cannot find group '$ACLGRP', adding it"
12152                         cat /etc/group
12153                         add_group 60000 $ACLGRP
12154                 fi
12155         fi
12156
12157         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12158         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12159         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12160
12161         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12162                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12163                 ACLGRP="$TSTUSR"
12164                 if ! getent group $ACLGRP; then
12165                         echo "cannot find group '$ACLGRP', adding it"
12166                         cat /etc/group
12167                         add_group 60000 $ACLGRP
12168                 fi
12169                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12170                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12171                         cat /etc/group
12172                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12173                 fi
12174         fi
12175
12176         gpasswd -a $ACLDMN $ACLBIN ||
12177                 error "setting client group failed"             # LU-5641
12178         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12179                 error "setting MDS group failed"                # LU-5641
12180
12181         declare -a identity_old
12182
12183         for num in $(seq $MDSCOUNT); do
12184                 switch_identity $num true || identity_old[$num]=$?
12185         done
12186
12187         SAVE_UMASK=$(umask)
12188         umask 0022
12189         mkdir -p $DIR/$tdir
12190         cd $DIR/$tdir
12191
12192         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12193         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12194         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12195         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12196         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12197         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12198         if ! id -u $ACLNBD ||
12199            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12200                 ACLNBD="nfsnobody"
12201                 if ! id -u $ACLNBD; then
12202                         ACLNBD=""
12203                 fi
12204         fi
12205         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12206                 add_group $(id -u $ACLNBD) $ACLNBD
12207                 if ! getent group $ACLNBD; then
12208                         ACLNBD=""
12209                 fi
12210         fi
12211         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12212            [[ -n "$ACLNBD" ]] && which setfattr; then
12213                 run_acl_subtest permissions_xattr \
12214                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12215         elif [[ -z "$ACLNBD" ]]; then
12216                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12217         else
12218                 echo "skip 'permission_xattr' test - missing setfattr command"
12219         fi
12220         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12221
12222         # inheritance test got from HP
12223         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12224         chmod +x make-tree || error "chmod +x failed"
12225         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12226         rm -f make-tree
12227
12228         echo "LU-974 ignore umask when acl is enabled..."
12229         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12230         if [ $MDSCOUNT -ge 2 ]; then
12231                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12232         fi
12233
12234         echo "LU-2561 newly created file is same size as directory..."
12235         if [ "$mds1_FSTYPE" != "zfs" ]; then
12236                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12237         else
12238                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12239         fi
12240
12241         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12242
12243         cd $SAVE_PWD
12244         umask $SAVE_UMASK
12245
12246         for num in $(seq $MDSCOUNT); do
12247                 if [ "${identity_old[$num]}" = 1 ]; then
12248                         switch_identity $num false || identity_old[$num]=$?
12249                 fi
12250         done
12251 }
12252 run_test 103a "acl test"
12253
12254 test_103b() {
12255         declare -a pids
12256         local U
12257
12258         for U in {0..511}; do
12259                 {
12260                 local O=$(printf "%04o" $U)
12261
12262                 umask $(printf "%04o" $((511 ^ $O)))
12263                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12264                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12265
12266                 (( $S == ($O & 0666) )) ||
12267                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12268
12269                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12270                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12271                 (( $S == ($O & 0666) )) ||
12272                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12273
12274                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12275                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12276                 (( $S == ($O & 0666) )) ||
12277                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12278                 rm -f $DIR/$tfile.[smp]$0
12279                 } &
12280                 local pid=$!
12281
12282                 # limit the concurrently running threads to 64. LU-11878
12283                 local idx=$((U % 64))
12284                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12285                 pids[idx]=$pid
12286         done
12287         wait
12288 }
12289 run_test 103b "umask lfs setstripe"
12290
12291 test_103c() {
12292         mkdir -p $DIR/$tdir
12293         cp -rp $DIR/$tdir $DIR/$tdir.bak
12294
12295         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12296                 error "$DIR/$tdir shouldn't contain default ACL"
12297         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12298                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12299         true
12300 }
12301 run_test 103c "'cp -rp' won't set empty acl"
12302
12303 test_103e() {
12304         local numacl
12305         local fileacl
12306         local saved_debug=$($LCTL get_param -n debug)
12307
12308         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12309                 skip "MDS needs to be at least 2.14.52"
12310
12311         large_xattr_enabled || skip_env "ea_inode feature disabled"
12312
12313         mkdir -p $DIR/$tdir
12314         # add big LOV EA to cause reply buffer overflow earlier
12315         $LFS setstripe -C 1000 $DIR/$tdir
12316         lctl set_param mdc.*-mdc*.stats=clear
12317
12318         $LCTL set_param debug=0
12319         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12320         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12321
12322         # add a large number of default ACLs (expect 8000+ for 2.13+)
12323         for U in {2..7000}; do
12324                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12325                         error "Able to add just $U default ACLs"
12326         done
12327         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12328         echo "$numacl default ACLs created"
12329
12330         stat $DIR/$tdir || error "Cannot stat directory"
12331         # check file creation
12332         touch $DIR/$tdir/$tfile ||
12333                 error "failed to create $tfile with $numacl default ACLs"
12334         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12335         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12336         echo "$fileacl ACLs were inherited"
12337         (( $fileacl == $numacl )) ||
12338                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12339         # check that new ACLs creation adds new ACLs to inherited ACLs
12340         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12341                 error "Cannot set new ACL"
12342         numacl=$((numacl + 1))
12343         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12344         (( $fileacl == $numacl )) ||
12345                 error "failed to add new ACL: $fileacl != $numacl as expected"
12346         # adds more ACLs to a file to reach their maximum at 8000+
12347         numacl=0
12348         for U in {20000..25000}; do
12349                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12350                 numacl=$((numacl + 1))
12351         done
12352         echo "Added $numacl more ACLs to the file"
12353         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12354         echo "Total $fileacl ACLs in file"
12355         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12356         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12357         rmdir $DIR/$tdir || error "Cannot remove directory"
12358 }
12359 run_test 103e "inheritance of big amount of default ACLs"
12360
12361 test_103f() {
12362         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12363                 skip "MDS needs to be at least 2.14.51"
12364
12365         large_xattr_enabled || skip_env "ea_inode feature disabled"
12366
12367         # enable changelog to consume more internal MDD buffers
12368         changelog_register
12369
12370         mkdir -p $DIR/$tdir
12371         # add big LOV EA
12372         $LFS setstripe -C 1000 $DIR/$tdir
12373         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12374         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12375         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12376         rmdir $DIR/$tdir || error "Cannot remove directory"
12377 }
12378 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12379
12380 test_104a() {
12381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12382
12383         touch $DIR/$tfile
12384         lfs df || error "lfs df failed"
12385         lfs df -ih || error "lfs df -ih failed"
12386         lfs df -h $DIR || error "lfs df -h $DIR failed"
12387         lfs df -i $DIR || error "lfs df -i $DIR failed"
12388         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12389         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12390
12391         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12392         lctl --device %$OSC deactivate
12393         lfs df || error "lfs df with deactivated OSC failed"
12394         lctl --device %$OSC activate
12395         # wait the osc back to normal
12396         wait_osc_import_ready client ost
12397
12398         lfs df || error "lfs df with reactivated OSC failed"
12399         rm -f $DIR/$tfile
12400 }
12401 run_test 104a "lfs df [-ih] [path] test ========================="
12402
12403 test_104b() {
12404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12405         [ $RUNAS_ID -eq $UID ] &&
12406                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12407
12408         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12409                         grep "Permission denied" | wc -l)))
12410         if [ $denied_cnt -ne 0 ]; then
12411                 error "lfs check servers test failed"
12412         fi
12413 }
12414 run_test 104b "$RUNAS lfs check servers test ===================="
12415
12416 #
12417 # Verify $1 is within range of $2.
12418 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12419 # $1 is <= 2% of $2. Else Fail.
12420 #
12421 value_in_range() {
12422         # Strip all units (M, G, T)
12423         actual=$(echo $1 | tr -d A-Z)
12424         expect=$(echo $2 | tr -d A-Z)
12425
12426         expect_lo=$(($expect * 98 / 100)) # 2% below
12427         expect_hi=$(($expect * 102 / 100)) # 2% above
12428
12429         # permit 2% drift above and below
12430         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12431 }
12432
12433 test_104c() {
12434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12435         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12436
12437         local ost_param="osd-zfs.$FSNAME-OST0000."
12438         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12439         local ofacets=$(get_facets OST)
12440         local mfacets=$(get_facets MDS)
12441         local saved_ost_blocks=
12442         local saved_mdt_blocks=
12443
12444         echo "Before recordsize change"
12445         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12446         df=($(df -h | grep "$MOUNT"$))
12447
12448         # For checking.
12449         echo "lfs output : ${lfs_df[*]}"
12450         echo "df  output : ${df[*]}"
12451
12452         for facet in ${ofacets//,/ }; do
12453                 if [ -z $saved_ost_blocks ]; then
12454                         saved_ost_blocks=$(do_facet $facet \
12455                                 lctl get_param -n $ost_param.blocksize)
12456                         echo "OST Blocksize: $saved_ost_blocks"
12457                 fi
12458                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12459                 do_facet $facet zfs set recordsize=32768 $ost
12460         done
12461
12462         # BS too small. Sufficient for functional testing.
12463         for facet in ${mfacets//,/ }; do
12464                 if [ -z $saved_mdt_blocks ]; then
12465                         saved_mdt_blocks=$(do_facet $facet \
12466                                 lctl get_param -n $mdt_param.blocksize)
12467                         echo "MDT Blocksize: $saved_mdt_blocks"
12468                 fi
12469                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12470                 do_facet $facet zfs set recordsize=32768 $mdt
12471         done
12472
12473         # Give new values chance to reflect change
12474         sleep 2
12475
12476         echo "After recordsize change"
12477         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12478         df_after=($(df -h | grep "$MOUNT"$))
12479
12480         # For checking.
12481         echo "lfs output : ${lfs_df_after[*]}"
12482         echo "df  output : ${df_after[*]}"
12483
12484         # Verify lfs df
12485         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12486                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12487         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12488                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12489         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12490                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12491
12492         # Verify df
12493         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12494                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12495         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12496                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12497         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12498                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12499
12500         # Restore MDT recordize back to original
12501         for facet in ${mfacets//,/ }; do
12502                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12503                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12504         done
12505
12506         # Restore OST recordize back to original
12507         for facet in ${ofacets//,/ }; do
12508                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12509                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12510         done
12511
12512         return 0
12513 }
12514 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12515
12516 test_104d() {
12517         (( $RUNAS_ID != $UID )) ||
12518                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12519
12520         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12521                 skip "lustre version doesn't support lctl dl with non-root"
12522
12523         # debugfs only allows root users to access files, so the
12524         # previous move of the "devices" file to debugfs broke
12525         # "lctl dl" for non-root users. The LU-9680 Netlink
12526         # interface again allows non-root users to list devices.
12527         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12528                 error "lctl dl doesn't work for non root"
12529
12530         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12531         [ "$ost_count" -eq $OSTCOUNT ]  ||
12532                 error "lctl dl reports wrong number of OST devices"
12533
12534         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12535         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12536                 error "lctl dl reports wrong number of MDT devices"
12537 }
12538 run_test 104d "$RUNAS lctl dl test"
12539
12540 test_105a() {
12541         # doesn't work on 2.4 kernels
12542         touch $DIR/$tfile
12543         if $(flock_is_enabled); then
12544                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12545         else
12546                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12547         fi
12548         rm -f $DIR/$tfile
12549 }
12550 run_test 105a "flock when mounted without -o flock test ========"
12551
12552 test_105b() {
12553         touch $DIR/$tfile
12554         if $(flock_is_enabled); then
12555                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12556         else
12557                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12558         fi
12559         rm -f $DIR/$tfile
12560 }
12561 run_test 105b "fcntl when mounted without -o flock test ========"
12562
12563 test_105c() {
12564         touch $DIR/$tfile
12565         if $(flock_is_enabled); then
12566                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12567         else
12568                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12569         fi
12570         rm -f $DIR/$tfile
12571 }
12572 run_test 105c "lockf when mounted without -o flock test"
12573
12574 test_105d() { # bug 15924
12575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12576
12577         test_mkdir $DIR/$tdir
12578         flock_is_enabled || skip_env "mount w/o flock enabled"
12579         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12580         $LCTL set_param fail_loc=0x80000315
12581         flocks_test 2 $DIR/$tdir
12582 }
12583 run_test 105d "flock race (should not freeze) ========"
12584
12585 test_105e() { # bug 22660 && 22040
12586         flock_is_enabled || skip_env "mount w/o flock enabled"
12587
12588         touch $DIR/$tfile
12589         flocks_test 3 $DIR/$tfile
12590 }
12591 run_test 105e "Two conflicting flocks from same process"
12592
12593 test_106() { #bug 10921
12594         test_mkdir $DIR/$tdir
12595         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12596         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12597 }
12598 run_test 106 "attempt exec of dir followed by chown of that dir"
12599
12600 test_107() {
12601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12602
12603         CDIR=`pwd`
12604         local file=core
12605
12606         cd $DIR
12607         rm -f $file
12608
12609         local save_pattern=$(sysctl -n kernel.core_pattern)
12610         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12611         sysctl -w kernel.core_pattern=$file
12612         sysctl -w kernel.core_uses_pid=0
12613
12614         ulimit -c unlimited
12615         sleep 60 &
12616         SLEEPPID=$!
12617
12618         sleep 1
12619
12620         kill -s 11 $SLEEPPID
12621         wait $SLEEPPID
12622         if [ -e $file ]; then
12623                 size=`stat -c%s $file`
12624                 [ $size -eq 0 ] && error "Fail to create core file $file"
12625         else
12626                 error "Fail to create core file $file"
12627         fi
12628         rm -f $file
12629         sysctl -w kernel.core_pattern=$save_pattern
12630         sysctl -w kernel.core_uses_pid=$save_uses_pid
12631         cd $CDIR
12632 }
12633 run_test 107 "Coredump on SIG"
12634
12635 test_110() {
12636         test_mkdir $DIR/$tdir
12637         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12638         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12639                 error "mkdir with 256 char should fail, but did not"
12640         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12641                 error "create with 255 char failed"
12642         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12643                 error "create with 256 char should fail, but did not"
12644
12645         ls -l $DIR/$tdir
12646         rm -rf $DIR/$tdir
12647 }
12648 run_test 110 "filename length checking"
12649
12650 test_116a() { # was previously test_116()
12651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12652         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12653         remote_mds_nodsh && skip "remote MDS with nodsh"
12654
12655         echo -n "Free space priority "
12656         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12657                 head -n1
12658         declare -a AVAIL
12659         free_min_max
12660
12661         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12662         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12663         stack_trap simple_cleanup_common
12664
12665         # Check if we need to generate uneven OSTs
12666         test_mkdir -p $DIR/$tdir/OST${MINI}
12667         local FILL=$((MINV / 4))
12668         local DIFF=$((MAXV - MINV))
12669         local DIFF2=$((DIFF * 100 / MINV))
12670
12671         local threshold=$(do_facet $SINGLEMDS \
12672                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12673         threshold=${threshold%%%}
12674         echo -n "Check for uneven OSTs: "
12675         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12676
12677         if [[ $DIFF2 -gt $threshold ]]; then
12678                 echo "ok"
12679                 echo "Don't need to fill OST$MINI"
12680         else
12681                 # generate uneven OSTs. Write 2% over the QOS threshold value
12682                 echo "no"
12683                 DIFF=$((threshold - DIFF2 + 2))
12684                 DIFF2=$((MINV * DIFF / 100))
12685                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12686                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12687                         error "setstripe failed"
12688                 DIFF=$((DIFF2 / 2048))
12689                 i=0
12690                 while [ $i -lt $DIFF ]; do
12691                         i=$((i + 1))
12692                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12693                                 bs=2M count=1 2>/dev/null
12694                         echo -n .
12695                 done
12696                 echo .
12697                 sync
12698                 sleep_maxage
12699                 free_min_max
12700         fi
12701
12702         DIFF=$((MAXV - MINV))
12703         DIFF2=$((DIFF * 100 / MINV))
12704         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12705         if [ $DIFF2 -gt $threshold ]; then
12706                 echo "ok"
12707         else
12708                 skip "QOS imbalance criteria not met"
12709         fi
12710
12711         MINI1=$MINI
12712         MINV1=$MINV
12713         MAXI1=$MAXI
12714         MAXV1=$MAXV
12715
12716         # now fill using QOS
12717         $LFS setstripe -c 1 $DIR/$tdir
12718         FILL=$((FILL / 200))
12719         if [ $FILL -gt 600 ]; then
12720                 FILL=600
12721         fi
12722         echo "writing $FILL files to QOS-assigned OSTs"
12723         i=0
12724         while [ $i -lt $FILL ]; do
12725                 i=$((i + 1))
12726                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12727                         count=1 2>/dev/null
12728                 echo -n .
12729         done
12730         echo "wrote $i 200k files"
12731         sync
12732         sleep_maxage
12733
12734         echo "Note: free space may not be updated, so measurements might be off"
12735         free_min_max
12736         DIFF2=$((MAXV - MINV))
12737         echo "free space delta: orig $DIFF final $DIFF2"
12738         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12739         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12740         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12741         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12742         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12743         if [[ $DIFF -gt 0 ]]; then
12744                 FILL=$((DIFF2 * 100 / DIFF - 100))
12745                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12746         fi
12747
12748         # Figure out which files were written where
12749         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12750                awk '/'$MINI1': / {print $2; exit}')
12751         echo $UUID
12752         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12753         echo "$MINC files created on smaller OST $MINI1"
12754         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12755                awk '/'$MAXI1': / {print $2; exit}')
12756         echo $UUID
12757         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12758         echo "$MAXC files created on larger OST $MAXI1"
12759         if [[ $MINC -gt 0 ]]; then
12760                 FILL=$((MAXC * 100 / MINC - 100))
12761                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12762         fi
12763         [[ $MAXC -gt $MINC ]] ||
12764                 error_ignore LU-9 "stripe QOS didn't balance free space"
12765 }
12766 run_test 116a "stripe QOS: free space balance ==================="
12767
12768 test_116b() { # LU-2093
12769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12770         remote_mds_nodsh && skip "remote MDS with nodsh"
12771
12772 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12773         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12774                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12775         [ -z "$old_rr" ] && skip "no QOS"
12776         do_facet $SINGLEMDS lctl set_param \
12777                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12778         mkdir -p $DIR/$tdir
12779         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12780         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12781         do_facet $SINGLEMDS lctl set_param fail_loc=0
12782         rm -rf $DIR/$tdir
12783         do_facet $SINGLEMDS lctl set_param \
12784                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12785 }
12786 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12787
12788 test_117() # bug 10891
12789 {
12790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12791
12792         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12793         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12794         lctl set_param fail_loc=0x21e
12795         > $DIR/$tfile || error "truncate failed"
12796         lctl set_param fail_loc=0
12797         echo "Truncate succeeded."
12798         rm -f $DIR/$tfile
12799 }
12800 run_test 117 "verify osd extend =========="
12801
12802 NO_SLOW_RESENDCOUNT=4
12803 export OLD_RESENDCOUNT=""
12804 set_resend_count () {
12805         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12806         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12807         lctl set_param -n $PROC_RESENDCOUNT $1
12808         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12809 }
12810
12811 # for reduce test_118* time (b=14842)
12812 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12813
12814 # Reset async IO behavior after error case
12815 reset_async() {
12816         FILE=$DIR/reset_async
12817
12818         # Ensure all OSCs are cleared
12819         $LFS setstripe -c -1 $FILE
12820         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12821         sync
12822         rm $FILE
12823 }
12824
12825 test_118a() #bug 11710
12826 {
12827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12828
12829         reset_async
12830
12831         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12832         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12833         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12834
12835         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12836                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12837                 return 1;
12838         fi
12839         rm -f $DIR/$tfile
12840 }
12841 run_test 118a "verify O_SYNC works =========="
12842
12843 test_118b()
12844 {
12845         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12846         remote_ost_nodsh && skip "remote OST with nodsh"
12847
12848         reset_async
12849
12850         #define OBD_FAIL_SRV_ENOENT 0x217
12851         set_nodes_failloc "$(osts_nodes)" 0x217
12852         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12853         RC=$?
12854         set_nodes_failloc "$(osts_nodes)" 0
12855         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12856         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12857                     grep -c writeback)
12858
12859         if [[ $RC -eq 0 ]]; then
12860                 error "Must return error due to dropped pages, rc=$RC"
12861                 return 1;
12862         fi
12863
12864         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12865                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12866                 return 1;
12867         fi
12868
12869         echo "Dirty pages not leaked on ENOENT"
12870
12871         # Due to the above error the OSC will issue all RPCs syncronously
12872         # until a subsequent RPC completes successfully without error.
12873         $MULTIOP $DIR/$tfile Ow4096yc
12874         rm -f $DIR/$tfile
12875
12876         return 0
12877 }
12878 run_test 118b "Reclaim dirty pages on fatal error =========="
12879
12880 test_118c()
12881 {
12882         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12883
12884         # for 118c, restore the original resend count, LU-1940
12885         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12886                                 set_resend_count $OLD_RESENDCOUNT
12887         remote_ost_nodsh && skip "remote OST with nodsh"
12888
12889         reset_async
12890
12891         #define OBD_FAIL_OST_EROFS               0x216
12892         set_nodes_failloc "$(osts_nodes)" 0x216
12893
12894         # multiop should block due to fsync until pages are written
12895         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12896         MULTIPID=$!
12897         sleep 1
12898
12899         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12900                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12901         fi
12902
12903         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12904                     grep -c writeback)
12905         if [[ $WRITEBACK -eq 0 ]]; then
12906                 error "No page in writeback, writeback=$WRITEBACK"
12907         fi
12908
12909         set_nodes_failloc "$(osts_nodes)" 0
12910         wait $MULTIPID
12911         RC=$?
12912         if [[ $RC -ne 0 ]]; then
12913                 error "Multiop fsync failed, rc=$RC"
12914         fi
12915
12916         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12917         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12918                     grep -c writeback)
12919         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12920                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12921         fi
12922
12923         rm -f $DIR/$tfile
12924         echo "Dirty pages flushed via fsync on EROFS"
12925         return 0
12926 }
12927 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12928
12929 # continue to use small resend count to reduce test_118* time (b=14842)
12930 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12931
12932 test_118d()
12933 {
12934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12935         remote_ost_nodsh && skip "remote OST with nodsh"
12936
12937         reset_async
12938
12939         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12940         set_nodes_failloc "$(osts_nodes)" 0x214
12941         # multiop should block due to fsync until pages are written
12942         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12943         MULTIPID=$!
12944         sleep 1
12945
12946         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12947                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12948         fi
12949
12950         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12951                     grep -c writeback)
12952         if [[ $WRITEBACK -eq 0 ]]; then
12953                 error "No page in writeback, writeback=$WRITEBACK"
12954         fi
12955
12956         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12957         set_nodes_failloc "$(osts_nodes)" 0
12958
12959         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12960         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12961                     grep -c writeback)
12962         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12963                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12964         fi
12965
12966         rm -f $DIR/$tfile
12967         echo "Dirty pages gaurenteed flushed via fsync"
12968         return 0
12969 }
12970 run_test 118d "Fsync validation inject a delay of the bulk =========="
12971
12972 test_118f() {
12973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12974
12975         reset_async
12976
12977         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12978         lctl set_param fail_loc=0x8000040a
12979
12980         # Should simulate EINVAL error which is fatal
12981         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12982         RC=$?
12983         if [[ $RC -eq 0 ]]; then
12984                 error "Must return error due to dropped pages, rc=$RC"
12985         fi
12986
12987         lctl set_param fail_loc=0x0
12988
12989         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12990         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12991         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12992                     grep -c writeback)
12993         if [[ $LOCKED -ne 0 ]]; then
12994                 error "Locked pages remain in cache, locked=$LOCKED"
12995         fi
12996
12997         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12998                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12999         fi
13000
13001         rm -f $DIR/$tfile
13002         echo "No pages locked after fsync"
13003
13004         reset_async
13005         return 0
13006 }
13007 run_test 118f "Simulate unrecoverable OSC side error =========="
13008
13009 test_118g() {
13010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13011
13012         reset_async
13013
13014         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13015         lctl set_param fail_loc=0x406
13016
13017         # simulate local -ENOMEM
13018         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13019         RC=$?
13020
13021         lctl set_param fail_loc=0
13022         if [[ $RC -eq 0 ]]; then
13023                 error "Must return error due to dropped pages, rc=$RC"
13024         fi
13025
13026         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13027         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13028         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13029                         grep -c writeback)
13030         if [[ $LOCKED -ne 0 ]]; then
13031                 error "Locked pages remain in cache, locked=$LOCKED"
13032         fi
13033
13034         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13035                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13036         fi
13037
13038         rm -f $DIR/$tfile
13039         echo "No pages locked after fsync"
13040
13041         reset_async
13042         return 0
13043 }
13044 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13045
13046 test_118h() {
13047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13048         remote_ost_nodsh && skip "remote OST with nodsh"
13049
13050         reset_async
13051
13052         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13053         set_nodes_failloc "$(osts_nodes)" 0x20e
13054         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13055         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13056         RC=$?
13057
13058         set_nodes_failloc "$(osts_nodes)" 0
13059         if [[ $RC -eq 0 ]]; then
13060                 error "Must return error due to dropped pages, rc=$RC"
13061         fi
13062
13063         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13064         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13065         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13066                     grep -c writeback)
13067         if [[ $LOCKED -ne 0 ]]; then
13068                 error "Locked pages remain in cache, locked=$LOCKED"
13069         fi
13070
13071         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13072                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13073         fi
13074
13075         rm -f $DIR/$tfile
13076         echo "No pages locked after fsync"
13077
13078         return 0
13079 }
13080 run_test 118h "Verify timeout in handling recoverables errors  =========="
13081
13082 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13083
13084 test_118i() {
13085         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13086         remote_ost_nodsh && skip "remote OST with nodsh"
13087
13088         reset_async
13089
13090         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13091         set_nodes_failloc "$(osts_nodes)" 0x20e
13092
13093         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13094         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13095         PID=$!
13096         sleep 5
13097         set_nodes_failloc "$(osts_nodes)" 0
13098
13099         wait $PID
13100         RC=$?
13101         if [[ $RC -ne 0 ]]; then
13102                 error "got error, but should be not, rc=$RC"
13103         fi
13104
13105         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13106         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13107         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13108         if [[ $LOCKED -ne 0 ]]; then
13109                 error "Locked pages remain in cache, locked=$LOCKED"
13110         fi
13111
13112         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13113                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13114         fi
13115
13116         rm -f $DIR/$tfile
13117         echo "No pages locked after fsync"
13118
13119         return 0
13120 }
13121 run_test 118i "Fix error before timeout in recoverable error  =========="
13122
13123 [ "$SLOW" = "no" ] && set_resend_count 4
13124
13125 test_118j() {
13126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13127         remote_ost_nodsh && skip "remote OST with nodsh"
13128
13129         reset_async
13130
13131         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13132         set_nodes_failloc "$(osts_nodes)" 0x220
13133
13134         # return -EIO from OST
13135         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13136         RC=$?
13137         set_nodes_failloc "$(osts_nodes)" 0x0
13138         if [[ $RC -eq 0 ]]; then
13139                 error "Must return error due to dropped pages, rc=$RC"
13140         fi
13141
13142         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13143         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13144         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13145         if [[ $LOCKED -ne 0 ]]; then
13146                 error "Locked pages remain in cache, locked=$LOCKED"
13147         fi
13148
13149         # in recoverable error on OST we want resend and stay until it finished
13150         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13151                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13152         fi
13153
13154         rm -f $DIR/$tfile
13155         echo "No pages locked after fsync"
13156
13157         return 0
13158 }
13159 run_test 118j "Simulate unrecoverable OST side error =========="
13160
13161 test_118k()
13162 {
13163         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13164         remote_ost_nodsh && skip "remote OSTs with nodsh"
13165
13166         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13167         set_nodes_failloc "$(osts_nodes)" 0x20e
13168         test_mkdir $DIR/$tdir
13169
13170         for ((i=0;i<10;i++)); do
13171                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13172                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13173                 SLEEPPID=$!
13174                 sleep 0.500s
13175                 kill $SLEEPPID
13176                 wait $SLEEPPID
13177         done
13178
13179         set_nodes_failloc "$(osts_nodes)" 0
13180         rm -rf $DIR/$tdir
13181 }
13182 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13183
13184 test_118l() # LU-646
13185 {
13186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13187
13188         test_mkdir $DIR/$tdir
13189         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13190         rm -rf $DIR/$tdir
13191 }
13192 run_test 118l "fsync dir"
13193
13194 test_118m() # LU-3066
13195 {
13196         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13197
13198         test_mkdir $DIR/$tdir
13199         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13200         rm -rf $DIR/$tdir
13201 }
13202 run_test 118m "fdatasync dir ========="
13203
13204 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13205
13206 test_118n()
13207 {
13208         local begin
13209         local end
13210
13211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13212         remote_ost_nodsh && skip "remote OSTs with nodsh"
13213
13214         # Sleep to avoid a cached response.
13215         #define OBD_STATFS_CACHE_SECONDS 1
13216         sleep 2
13217
13218         # Inject a 10 second delay in the OST_STATFS handler.
13219         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13220         set_nodes_failloc "$(osts_nodes)" 0x242
13221
13222         begin=$SECONDS
13223         stat --file-system $MOUNT > /dev/null
13224         end=$SECONDS
13225
13226         set_nodes_failloc "$(osts_nodes)" 0
13227
13228         if ((end - begin > 20)); then
13229             error "statfs took $((end - begin)) seconds, expected 10"
13230         fi
13231 }
13232 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13233
13234 test_119a() # bug 11737
13235 {
13236         BSIZE=$((512 * 1024))
13237         directio write $DIR/$tfile 0 1 $BSIZE
13238         # We ask to read two blocks, which is more than a file size.
13239         # directio will indicate an error when requested and actual
13240         # sizes aren't equeal (a normal situation in this case) and
13241         # print actual read amount.
13242         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13243         if [ "$NOB" != "$BSIZE" ]; then
13244                 error "read $NOB bytes instead of $BSIZE"
13245         fi
13246         rm -f $DIR/$tfile
13247 }
13248 run_test 119a "Short directIO read must return actual read amount"
13249
13250 test_119b() # bug 11737
13251 {
13252         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13253
13254         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13255         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13256         sync
13257         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13258                 error "direct read failed"
13259         rm -f $DIR/$tfile
13260 }
13261 run_test 119b "Sparse directIO read must return actual read amount"
13262
13263 test_119c() # bug 13099
13264 {
13265         BSIZE=1048576
13266         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13267         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13268         rm -f $DIR/$tfile
13269 }
13270 run_test 119c "Testing for direct read hitting hole"
13271
13272 test_120a() {
13273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13274         remote_mds_nodsh && skip "remote MDS with nodsh"
13275         test_mkdir -i0 -c1 $DIR/$tdir
13276         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13277                 skip_env "no early lock cancel on server"
13278
13279         lru_resize_disable mdc
13280         lru_resize_disable osc
13281         cancel_lru_locks mdc
13282         # asynchronous object destroy at MDT could cause bl ast to client
13283         cancel_lru_locks osc
13284
13285         stat $DIR/$tdir > /dev/null
13286         can1=$(do_facet mds1 \
13287                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13288                awk '/ldlm_cancel/ {print $2}')
13289         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13290                awk '/ldlm_bl_callback/ {print $2}')
13291         test_mkdir -i0 -c1 $DIR/$tdir/d1
13292         can2=$(do_facet mds1 \
13293                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13294                awk '/ldlm_cancel/ {print $2}')
13295         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13296                awk '/ldlm_bl_callback/ {print $2}')
13297         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13298         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13299         lru_resize_enable mdc
13300         lru_resize_enable osc
13301 }
13302 run_test 120a "Early Lock Cancel: mkdir test"
13303
13304 test_120b() {
13305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13306         remote_mds_nodsh && skip "remote MDS with nodsh"
13307         test_mkdir $DIR/$tdir
13308         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13309                 skip_env "no early lock cancel on server"
13310
13311         lru_resize_disable mdc
13312         lru_resize_disable osc
13313         cancel_lru_locks mdc
13314         stat $DIR/$tdir > /dev/null
13315         can1=$(do_facet $SINGLEMDS \
13316                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13317                awk '/ldlm_cancel/ {print $2}')
13318         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13319                awk '/ldlm_bl_callback/ {print $2}')
13320         touch $DIR/$tdir/f1
13321         can2=$(do_facet $SINGLEMDS \
13322                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13323                awk '/ldlm_cancel/ {print $2}')
13324         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13325                awk '/ldlm_bl_callback/ {print $2}')
13326         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13327         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13328         lru_resize_enable mdc
13329         lru_resize_enable osc
13330 }
13331 run_test 120b "Early Lock Cancel: create test"
13332
13333 test_120c() {
13334         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13335         remote_mds_nodsh && skip "remote MDS with nodsh"
13336         test_mkdir -i0 -c1 $DIR/$tdir
13337         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13338                 skip "no early lock cancel on server"
13339
13340         lru_resize_disable mdc
13341         lru_resize_disable osc
13342         test_mkdir -i0 -c1 $DIR/$tdir/d1
13343         test_mkdir -i0 -c1 $DIR/$tdir/d2
13344         touch $DIR/$tdir/d1/f1
13345         cancel_lru_locks mdc
13346         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13347         can1=$(do_facet mds1 \
13348                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13349                awk '/ldlm_cancel/ {print $2}')
13350         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13351                awk '/ldlm_bl_callback/ {print $2}')
13352         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13353         can2=$(do_facet mds1 \
13354                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13355                awk '/ldlm_cancel/ {print $2}')
13356         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13357                awk '/ldlm_bl_callback/ {print $2}')
13358         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13359         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13360         lru_resize_enable mdc
13361         lru_resize_enable osc
13362 }
13363 run_test 120c "Early Lock Cancel: link test"
13364
13365 test_120d() {
13366         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13367         remote_mds_nodsh && skip "remote MDS with nodsh"
13368         test_mkdir -i0 -c1 $DIR/$tdir
13369         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13370                 skip_env "no early lock cancel on server"
13371
13372         lru_resize_disable mdc
13373         lru_resize_disable osc
13374         touch $DIR/$tdir
13375         cancel_lru_locks mdc
13376         stat $DIR/$tdir > /dev/null
13377         can1=$(do_facet mds1 \
13378                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13379                awk '/ldlm_cancel/ {print $2}')
13380         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13381                awk '/ldlm_bl_callback/ {print $2}')
13382         chmod a+x $DIR/$tdir
13383         can2=$(do_facet mds1 \
13384                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13385                awk '/ldlm_cancel/ {print $2}')
13386         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13387                awk '/ldlm_bl_callback/ {print $2}')
13388         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13389         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13390         lru_resize_enable mdc
13391         lru_resize_enable osc
13392 }
13393 run_test 120d "Early Lock Cancel: setattr test"
13394
13395 test_120e() {
13396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13397         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13398                 skip_env "no early lock cancel on server"
13399         remote_mds_nodsh && skip "remote MDS with nodsh"
13400
13401         local dlmtrace_set=false
13402
13403         test_mkdir -i0 -c1 $DIR/$tdir
13404         lru_resize_disable mdc
13405         lru_resize_disable osc
13406         ! $LCTL get_param debug | grep -q dlmtrace &&
13407                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13408         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13409         cancel_lru_locks mdc
13410         cancel_lru_locks osc
13411         dd if=$DIR/$tdir/f1 of=/dev/null
13412         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13413         # XXX client can not do early lock cancel of OST lock
13414         # during unlink (LU-4206), so cancel osc lock now.
13415         sleep 2
13416         cancel_lru_locks osc
13417         can1=$(do_facet mds1 \
13418                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13419                awk '/ldlm_cancel/ {print $2}')
13420         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13421                awk '/ldlm_bl_callback/ {print $2}')
13422         unlink $DIR/$tdir/f1
13423         sleep 5
13424         can2=$(do_facet mds1 \
13425                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13426                awk '/ldlm_cancel/ {print $2}')
13427         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13428                awk '/ldlm_bl_callback/ {print $2}')
13429         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13430                 $LCTL dk $TMP/cancel.debug.txt
13431         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13432                 $LCTL dk $TMP/blocking.debug.txt
13433         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13434         lru_resize_enable mdc
13435         lru_resize_enable osc
13436 }
13437 run_test 120e "Early Lock Cancel: unlink test"
13438
13439 test_120f() {
13440         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13441         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13442                 skip_env "no early lock cancel on server"
13443         remote_mds_nodsh && skip "remote MDS with nodsh"
13444
13445         test_mkdir -i0 -c1 $DIR/$tdir
13446         lru_resize_disable mdc
13447         lru_resize_disable osc
13448         test_mkdir -i0 -c1 $DIR/$tdir/d1
13449         test_mkdir -i0 -c1 $DIR/$tdir/d2
13450         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13451         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13452         cancel_lru_locks mdc
13453         cancel_lru_locks osc
13454         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13455         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13456         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13457         # XXX client can not do early lock cancel of OST lock
13458         # during rename (LU-4206), so cancel osc lock now.
13459         sleep 2
13460         cancel_lru_locks osc
13461         can1=$(do_facet mds1 \
13462                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13463                awk '/ldlm_cancel/ {print $2}')
13464         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13465                awk '/ldlm_bl_callback/ {print $2}')
13466         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13467         sleep 5
13468         can2=$(do_facet mds1 \
13469                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13470                awk '/ldlm_cancel/ {print $2}')
13471         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13472                awk '/ldlm_bl_callback/ {print $2}')
13473         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13474         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13475         lru_resize_enable mdc
13476         lru_resize_enable osc
13477 }
13478 run_test 120f "Early Lock Cancel: rename test"
13479
13480 test_120g() {
13481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13482         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13483                 skip_env "no early lock cancel on server"
13484         remote_mds_nodsh && skip "remote MDS with nodsh"
13485
13486         lru_resize_disable mdc
13487         lru_resize_disable osc
13488         count=10000
13489         echo create $count files
13490         test_mkdir $DIR/$tdir
13491         cancel_lru_locks mdc
13492         cancel_lru_locks osc
13493         t0=$(date +%s)
13494
13495         can0=$(do_facet $SINGLEMDS \
13496                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13497                awk '/ldlm_cancel/ {print $2}')
13498         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13499                awk '/ldlm_bl_callback/ {print $2}')
13500         createmany -o $DIR/$tdir/f $count
13501         sync
13502         can1=$(do_facet $SINGLEMDS \
13503                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13504                awk '/ldlm_cancel/ {print $2}')
13505         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13506                awk '/ldlm_bl_callback/ {print $2}')
13507         t1=$(date +%s)
13508         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13509         echo rm $count files
13510         rm -r $DIR/$tdir
13511         sync
13512         can2=$(do_facet $SINGLEMDS \
13513                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13514                awk '/ldlm_cancel/ {print $2}')
13515         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13516                awk '/ldlm_bl_callback/ {print $2}')
13517         t2=$(date +%s)
13518         echo total: $count removes in $((t2-t1))
13519         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13520         sleep 2
13521         # wait for commitment of removal
13522         lru_resize_enable mdc
13523         lru_resize_enable osc
13524 }
13525 run_test 120g "Early Lock Cancel: performance test"
13526
13527 test_121() { #bug #10589
13528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13529
13530         rm -rf $DIR/$tfile
13531         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13532 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13533         lctl set_param fail_loc=0x310
13534         cancel_lru_locks osc > /dev/null
13535         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13536         lctl set_param fail_loc=0
13537         [[ $reads -eq $writes ]] ||
13538                 error "read $reads blocks, must be $writes blocks"
13539 }
13540 run_test 121 "read cancel race ========="
13541
13542 test_123a_base() { # was test 123, statahead(bug 11401)
13543         local lsx="$1"
13544
13545         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13546
13547         SLOWOK=0
13548         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13549                 log "testing UP system. Performance may be lower than expected."
13550                 SLOWOK=1
13551         fi
13552         running_in_vm && SLOWOK=1
13553
13554         $LCTL set_param mdc.*.batch_stats=0
13555
13556         rm -rf $DIR/$tdir
13557         test_mkdir $DIR/$tdir
13558         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13559         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13560         MULT=10
13561         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13562                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13563
13564                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13565                 lctl set_param -n llite.*.statahead_max 0
13566                 lctl get_param llite.*.statahead_max
13567                 cancel_lru_locks mdc
13568                 cancel_lru_locks osc
13569                 stime=$(date +%s)
13570                 time $lsx $DIR/$tdir | wc -l
13571                 etime=$(date +%s)
13572                 delta=$((etime - stime))
13573                 log "$lsx $i files without statahead: $delta sec"
13574                 lctl set_param llite.*.statahead_max=$max
13575
13576                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13577                          awk '/statahead.wrong:/ { print $NF }')
13578                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13579                 cancel_lru_locks mdc
13580                 cancel_lru_locks osc
13581                 stime=$(date +%s)
13582                 time $lsx $DIR/$tdir | wc -l
13583                 etime=$(date +%s)
13584                 delta_sa=$((etime - stime))
13585                 log "$lsx $i files with statahead: $delta_sa sec"
13586                 lctl get_param -n llite.*.statahead_stats
13587                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13588                          awk '/statahead.wrong:/ { print $NF }')
13589
13590                 [[ $swrong -lt $ewrong ]] &&
13591                         log "statahead was stopped, maybe too many locks held!"
13592                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13593
13594                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13595                         max=$(lctl get_param -n llite.*.statahead_max |
13596                                 head -n 1)
13597                         lctl set_param -n llite.*.statahead_max 0
13598                         lctl get_param llite.*.statahead_max
13599                         cancel_lru_locks mdc
13600                         cancel_lru_locks osc
13601                         stime=$(date +%s)
13602                         time $lsx $DIR/$tdir | wc -l
13603                         etime=$(date +%s)
13604                         delta=$((etime - stime))
13605                         log "$lsx $i files again without statahead: $delta sec"
13606                         lctl set_param llite.*.statahead_max=$max
13607                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13608                                 if [ $SLOWOK -eq 0 ]; then
13609                                         error "$lsx $i files is slower with statahead!"
13610                                 else
13611                                         log "$lsx $i files is slower with statahead!"
13612                                 fi
13613                                 break
13614                         fi
13615                 fi
13616
13617                 [ $delta -gt 20 ] && break
13618                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13619                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13620         done
13621         log "$lsx done"
13622
13623         stime=$(date +%s)
13624         rm -r $DIR/$tdir
13625         sync
13626         etime=$(date +%s)
13627         delta=$((etime - stime))
13628         log "rm -r $DIR/$tdir/: $delta seconds"
13629         log "rm done"
13630         lctl get_param -n llite.*.statahead_stats
13631         $LCTL get_param mdc.*.batch_stats
13632 }
13633
13634 test_123aa() {
13635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13636
13637         test_123a_base "ls -l"
13638 }
13639 run_test 123aa "verify statahead work"
13640
13641 test_123ab() {
13642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13643
13644         statx_supported || skip_env "Test must be statx() syscall supported"
13645
13646         test_123a_base "$STATX -l"
13647 }
13648 run_test 123ab "verify statahead work by using statx"
13649
13650 test_123ac() {
13651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13652
13653         statx_supported || skip_env "Test must be statx() syscall supported"
13654
13655         local rpcs_before
13656         local rpcs_after
13657         local agl_before
13658         local agl_after
13659
13660         cancel_lru_locks $OSC
13661         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13662         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13663                      awk '/agl.total:/ { print $NF }')
13664         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13665         test_123a_base "$STATX --cached=always -D"
13666         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13667                     awk '/agl.total:/ { print $NF }')
13668         [ $agl_before -eq $agl_after ] ||
13669                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13670         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13671         [ $rpcs_after -eq $rpcs_before ] ||
13672                 error "$STATX should not send glimpse RPCs to $OSC"
13673 }
13674 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13675
13676 test_batch_statahead() {
13677         local max=$1
13678         local batch_max=$2
13679         local num=10000
13680         local batch_rpcs
13681         local unbatch_rpcs
13682         local hit_total
13683
13684         echo -e "\nbatching: statahead_max=$max statahead_batch_max=$batch_max"
13685         $LCTL set_param mdc.*.batch_stats=0
13686         $LCTL set_param llite.*.statahead_max=$max
13687         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13688         # Verify that batched statahead is faster than one without statahead
13689         test_123a_base "ls -l"
13690
13691         stack_trap "rm -rf $DIR/$tdir" EXIT
13692         mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
13693         createmany -o $DIR/$tdir/$tfile $num || error "failed to create files"
13694
13695         # unbatched statahead
13696         $LCTL set_param llite.*.statahead_batch_max=0
13697         $LCTL set_param llite.*.statahead_stats=clear
13698         $LCTL set_param mdc.*.stats=clear
13699         cancel_lru_locks mdc
13700         cancel_lru_locks osc
13701         time ls -l $DIR/$tdir | wc -l
13702         unbatch_rpcs=$(calc_stats mdc.*.stats ldlm_ibits_enqueue)
13703         sleep 2
13704         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13705                     awk '/hit.total:/ { print $NF }')
13706         # hit ratio should be larger than 75% (7500).
13707         (( $hit_total > 7500 )) ||
13708                 error "unbatched statahead hit count ($hit_total) is too low"
13709
13710         # batched statahead
13711         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13712         $LCTL set_param llite.*.statahead_stats=clear
13713         $LCTL set_param mdc.*.batch_stats=clear
13714         $LCTL set_param mdc.*.stats=clear
13715         cancel_lru_locks mdc
13716         cancel_lru_locks osc
13717         time ls -l $DIR/$tdir | wc -l
13718         batch_rpcs=$(calc_stats mdc.*.stats mds_batch)
13719         # wait for statahead thread to quit and update statahead stats
13720         sleep 2
13721         hit_total=$($LCTL get_param -n llite.*.statahead_stats |
13722                     awk '/hit.total:/ { print $NF }')
13723         # hit ratio should be larger than 75% (7500).
13724         (( $hit_total > 7500 )) ||
13725                 error "batched statahead hit count ($hit_total) is too low"
13726
13727         echo "unbatched RPCs: $unbatch_rpcs, batched RPCs: $batch_rpcs"
13728         (( $unbatch_rpcs > $batch_rpcs )) ||
13729                 error "batched statahead does not reduce RPC count"
13730         $LCTL get_param mdc.*.batch_stats
13731 }
13732
13733 test_123ad() {
13734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13735
13736         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
13737                 skip "Need server version at least 2.15.53"
13738
13739         local max
13740         local batch_max
13741
13742         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13743         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13744
13745         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13746         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13747
13748         test_batch_statahead 32 32
13749         test_batch_statahead 2048 256
13750 }
13751 run_test 123ad "Verify batching statahead works correctly"
13752
13753 test_123b () { # statahead(bug 15027)
13754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13755
13756         test_mkdir $DIR/$tdir
13757         createmany -o $DIR/$tdir/$tfile-%d 1000
13758
13759         cancel_lru_locks mdc
13760         cancel_lru_locks osc
13761
13762 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13763         lctl set_param fail_loc=0x80000803
13764         ls -lR $DIR/$tdir > /dev/null
13765         log "ls done"
13766         lctl set_param fail_loc=0x0
13767         lctl get_param -n llite.*.statahead_stats
13768         rm -r $DIR/$tdir
13769         sync
13770
13771 }
13772 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13773
13774 test_123c() {
13775         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13776
13777         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13778         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13779         touch $DIR/$tdir.1/{1..3}
13780         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13781
13782         remount_client $MOUNT
13783
13784         $MULTIOP $DIR/$tdir.0 Q
13785
13786         # let statahead to complete
13787         ls -l $DIR/$tdir.0 > /dev/null
13788
13789         testid=$(echo $TESTNAME | tr '_' ' ')
13790         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13791                 error "statahead warning" || true
13792 }
13793 run_test 123c "Can not initialize inode warning on DNE statahead"
13794
13795 test_123d() {
13796         local num=100
13797         local swrong
13798         local ewrong
13799
13800         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13801         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13802                 error "setdirstripe $DIR/$tdir failed"
13803         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13804         remount_client $MOUNT
13805         $LCTL get_param llite.*.statahead_max
13806         $LCTL set_param llite.*.statahead_stats=0 ||
13807                 error "clear statahead_stats failed"
13808         swrong=$(lctl get_param -n llite.*.statahead_stats |
13809                  awk '/statahead.wrong:/ { print $NF }')
13810         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13811         # wait for statahead thread finished to update hit/miss stats.
13812         sleep 1
13813         $LCTL get_param -n llite.*.statahead_stats
13814         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13815                  awk '/statahead.wrong:/ { print $NF }')
13816         (( $swrong == $ewrong )) ||
13817                 log "statahead was stopped, maybe too many locks held!"
13818 }
13819 run_test 123d "Statahead on striped directories works correctly"
13820
13821 test_123e() {
13822         local max
13823         local batch_max
13824         local dir=$DIR/$tdir
13825
13826         mkdir $dir || error "mkdir $dir failed"
13827         $LFS setstripe -C 32 $dir || error "setstripe $dir failed"
13828
13829         touch $dir/$tfile.{0..1000} || error "touch 1000 files failed"
13830
13831         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13832         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13833         stack_trap "$LCTL set_param llite.*.statahead_max=$max" EXIT
13834         stack_trap "$LCTL set_param llite.*.statahead_batch_max=$batch_max" EXIT
13835
13836         $LCTL set_param llite.*.statahead_max=2048
13837         $LCTL set_param llite.*.statahead_batch_max=1024
13838
13839         ls -l $dir
13840         $LCTL get_param mdc.*.batch_stats
13841         $LCTL get_param llite.*.statahead_*
13842 }
13843 run_test 123e "statahead with large wide striping"
13844
13845 test_123f() {
13846         local max
13847         local batch_max
13848         local dir=$DIR/$tdir
13849
13850         mkdir $dir || error "mkdir $dir failed"
13851         $LFS setstripe -C 1000 $dir || error "setstripe $dir failed"
13852
13853         touch $dir/$tfile.{0..200} || error "touch 200 files failed"
13854
13855         max=$($LCTL get_param -n llite.*.statahead_max | head -n 1)
13856         batch_max=$($LCTL get_param -n llite.*.statahead_batch_max | head -n 1)
13857
13858         $LCTL set_param llite.*.statahead_max=64
13859         $LCTL set_param llite.*.statahead_batch_max=64
13860
13861         ls -l $dir
13862         lctl get_param mdc.*.batch_stats
13863         lctl get_param llite.*.statahead_*
13864
13865         $LCTL set_param llite.*.statahead_max=$max
13866         $LCTL set_param llite.*.statahead_batch_max=$batch_max
13867 }
13868 run_test 123f "Retry mechanism with large wide striping files"
13869
13870 test_124a() {
13871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13872         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13873                 skip_env "no lru resize on server"
13874
13875         local NR=2000
13876
13877         test_mkdir $DIR/$tdir
13878
13879         log "create $NR files at $DIR/$tdir"
13880         createmany -o $DIR/$tdir/f $NR ||
13881                 error "failed to create $NR files in $DIR/$tdir"
13882
13883         cancel_lru_locks mdc
13884         ls -l $DIR/$tdir > /dev/null
13885
13886         local NSDIR=""
13887         local LRU_SIZE=0
13888         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13889                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13890                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13891                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13892                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13893                         log "NSDIR=$NSDIR"
13894                         log "NS=$(basename $NSDIR)"
13895                         break
13896                 fi
13897         done
13898
13899         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13900                 skip "Not enough cached locks created!"
13901         fi
13902         log "LRU=$LRU_SIZE"
13903
13904         local SLEEP=30
13905
13906         # We know that lru resize allows one client to hold $LIMIT locks
13907         # for 10h. After that locks begin to be killed by client.
13908         local MAX_HRS=10
13909         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13910         log "LIMIT=$LIMIT"
13911         if [ $LIMIT -lt $LRU_SIZE ]; then
13912                 skip "Limit is too small $LIMIT"
13913         fi
13914
13915         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13916         # killing locks. Some time was spent for creating locks. This means
13917         # that up to the moment of sleep finish we must have killed some of
13918         # them (10-100 locks). This depends on how fast ther were created.
13919         # Many of them were touched in almost the same moment and thus will
13920         # be killed in groups.
13921         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13922
13923         # Use $LRU_SIZE_B here to take into account real number of locks
13924         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13925         local LRU_SIZE_B=$LRU_SIZE
13926         log "LVF=$LVF"
13927         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13928         log "OLD_LVF=$OLD_LVF"
13929         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13930
13931         # Let's make sure that we really have some margin. Client checks
13932         # cached locks every 10 sec.
13933         SLEEP=$((SLEEP+20))
13934         log "Sleep ${SLEEP} sec"
13935         local SEC=0
13936         while ((SEC<$SLEEP)); do
13937                 echo -n "..."
13938                 sleep 5
13939                 SEC=$((SEC+5))
13940                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13941                 echo -n "$LRU_SIZE"
13942         done
13943         echo ""
13944         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13945         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13946
13947         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13948                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13949                 unlinkmany $DIR/$tdir/f $NR
13950                 return
13951         }
13952
13953         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13954         log "unlink $NR files at $DIR/$tdir"
13955         unlinkmany $DIR/$tdir/f $NR
13956 }
13957 run_test 124a "lru resize ======================================="
13958
13959 get_max_pool_limit()
13960 {
13961         local limit=$($LCTL get_param \
13962                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13963         local max=0
13964         for l in $limit; do
13965                 if [[ $l -gt $max ]]; then
13966                         max=$l
13967                 fi
13968         done
13969         echo $max
13970 }
13971
13972 test_124b() {
13973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13974         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13975                 skip_env "no lru resize on server"
13976
13977         LIMIT=$(get_max_pool_limit)
13978
13979         NR=$(($(default_lru_size)*20))
13980         if [[ $NR -gt $LIMIT ]]; then
13981                 log "Limit lock number by $LIMIT locks"
13982                 NR=$LIMIT
13983         fi
13984
13985         IFree=$(mdsrate_inodes_available)
13986         if [ $IFree -lt $NR ]; then
13987                 log "Limit lock number by $IFree inodes"
13988                 NR=$IFree
13989         fi
13990
13991         lru_resize_disable mdc
13992         test_mkdir -p $DIR/$tdir/disable_lru_resize
13993
13994         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13995         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13996         cancel_lru_locks mdc
13997         stime=`date +%s`
13998         PID=""
13999         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14000         PID="$PID $!"
14001         sleep 2
14002         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14003         PID="$PID $!"
14004         sleep 2
14005         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
14006         PID="$PID $!"
14007         wait $PID
14008         etime=`date +%s`
14009         nolruresize_delta=$((etime-stime))
14010         log "ls -la time: $nolruresize_delta seconds"
14011         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14012         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
14013
14014         lru_resize_enable mdc
14015         test_mkdir -p $DIR/$tdir/enable_lru_resize
14016
14017         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
14018         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
14019         cancel_lru_locks mdc
14020         stime=`date +%s`
14021         PID=""
14022         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14023         PID="$PID $!"
14024         sleep 2
14025         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14026         PID="$PID $!"
14027         sleep 2
14028         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
14029         PID="$PID $!"
14030         wait $PID
14031         etime=`date +%s`
14032         lruresize_delta=$((etime-stime))
14033         log "ls -la time: $lruresize_delta seconds"
14034         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
14035
14036         if [ $lruresize_delta -gt $nolruresize_delta ]; then
14037                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
14038         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
14039                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
14040         else
14041                 log "lru resize performs the same with no lru resize"
14042         fi
14043         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
14044 }
14045 run_test 124b "lru resize (performance test) ======================="
14046
14047 test_124c() {
14048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14049         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14050                 skip_env "no lru resize on server"
14051
14052         # cache ununsed locks on client
14053         local nr=100
14054         cancel_lru_locks mdc
14055         test_mkdir $DIR/$tdir
14056         createmany -o $DIR/$tdir/f $nr ||
14057                 error "failed to create $nr files in $DIR/$tdir"
14058         ls -l $DIR/$tdir > /dev/null
14059
14060         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14061         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14062         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14063         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14064         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14065
14066         # set lru_max_age to 1 sec
14067         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14068         echo "sleep $((recalc_p * 2)) seconds..."
14069         sleep $((recalc_p * 2))
14070
14071         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14072         # restore lru_max_age
14073         $LCTL set_param -n $nsdir.lru_max_age $max_age
14074         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14075         unlinkmany $DIR/$tdir/f $nr
14076 }
14077 run_test 124c "LRUR cancel very aged locks"
14078
14079 test_124d() {
14080         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14081         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
14082                 skip_env "no lru resize on server"
14083
14084         # cache ununsed locks on client
14085         local nr=100
14086
14087         lru_resize_disable mdc
14088         stack_trap "lru_resize_enable mdc" EXIT
14089
14090         cancel_lru_locks mdc
14091
14092         # asynchronous object destroy at MDT could cause bl ast to client
14093         test_mkdir $DIR/$tdir
14094         createmany -o $DIR/$tdir/f $nr ||
14095                 error "failed to create $nr files in $DIR/$tdir"
14096         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
14097
14098         ls -l $DIR/$tdir > /dev/null
14099
14100         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
14101         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14102         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14103         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14104
14105         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14106
14107         # set lru_max_age to 1 sec
14108         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14109         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14110
14111         echo "sleep $((recalc_p * 2)) seconds..."
14112         sleep $((recalc_p * 2))
14113
14114         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14115
14116         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14117 }
14118 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14119
14120 test_125() { # 13358
14121         $LCTL get_param -n llite.*.client_type | grep -q local ||
14122                 skip "must run as local client"
14123         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14124                 skip_env "must have acl enabled"
14125         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14126
14127         test_mkdir $DIR/$tdir
14128         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14129         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14130                 error "setfacl $DIR/$tdir failed"
14131         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14132 }
14133 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14134
14135 test_126() { # bug 12829/13455
14136         $GSS && skip_env "must run as gss disabled"
14137         $LCTL get_param -n llite.*.client_type | grep -q local ||
14138                 skip "must run as local client"
14139         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14140
14141         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14142         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14143         rm -f $DIR/$tfile
14144         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14145 }
14146 run_test 126 "check that the fsgid provided by the client is taken into account"
14147
14148 test_127a() { # bug 15521
14149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14150         local name count samp unit min max sum sumsq
14151         local tmpfile=$TMP/$tfile.tmp
14152
14153         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14154         echo "stats before reset"
14155         stack_trap "rm -f $tmpfile"
14156         local now=$(date +%s)
14157
14158         $LCTL get_param osc.*.stats | tee $tmpfile
14159
14160         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14161         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14162         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14163         local uptime=$(awk '{ print $1 }' /proc/uptime)
14164
14165         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14166         (( ${snapshot_time%\.*} >= $now - 5 &&
14167            ${snapshot_time%\.*} <= $now + 5 )) ||
14168                 error "snapshot_time=$snapshot_time != now=$now"
14169         # elapsed _should_ be from mount, but at least less than uptime
14170         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14171                 error "elapsed=$elapsed > uptime=$uptime"
14172         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14173            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14174                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14175
14176         $LCTL set_param osc.*.stats=0
14177         local reset=$(date +%s)
14178         local fsize=$((2048 * 1024))
14179
14180         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14181         cancel_lru_locks osc
14182         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14183
14184         now=$(date +%s)
14185         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14186         while read name count samp unit min max sum sumsq; do
14187                 [[ "$samp" == "samples" ]] || continue
14188
14189                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14190                 [ ! $min ] && error "Missing min value for $name proc entry"
14191                 eval $name=$count || error "Wrong proc format"
14192
14193                 case $name in
14194                 read_bytes|write_bytes)
14195                         [[ "$unit" =~ "bytes" ]] ||
14196                                 error "unit is not 'bytes': $unit"
14197                         (( $min >= 4096 )) || error "min is too small: $min"
14198                         (( $min <= $fsize )) || error "min is too big: $min"
14199                         (( $max >= 4096 )) || error "max is too small: $max"
14200                         (( $max <= $fsize )) || error "max is too big: $max"
14201                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14202                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14203                                 error "sumsquare is too small: $sumsq"
14204                         (( $sumsq <= $fsize * $fsize )) ||
14205                                 error "sumsquare is too big: $sumsq"
14206                         ;;
14207                 ost_read|ost_write)
14208                         [[ "$unit" =~ "usec" ]] ||
14209                                 error "unit is not 'usec': $unit"
14210                         ;;
14211                 *)      ;;
14212                 esac
14213         done < $tmpfile
14214
14215         #check that we actually got some stats
14216         [ "$read_bytes" ] || error "Missing read_bytes stats"
14217         [ "$write_bytes" ] || error "Missing write_bytes stats"
14218         [ "$read_bytes" != 0 ] || error "no read done"
14219         [ "$write_bytes" != 0 ] || error "no write done"
14220
14221         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14222         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14223         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14224
14225         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14226         (( ${snapshot_time%\.*} >= $now - 5 &&
14227            ${snapshot_time%\.*} <= $now + 5 )) ||
14228                 error "reset snapshot_time=$snapshot_time != now=$now"
14229         # elapsed should be from time of stats reset
14230         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14231            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14232                 error "reset elapsed=$elapsed > $now - $reset"
14233         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14234            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14235                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14236 }
14237 run_test 127a "verify the client stats are sane"
14238
14239 test_127b() { # bug LU-333
14240         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14241         local name count samp unit min max sum sumsq
14242
14243         echo "stats before reset"
14244         $LCTL get_param llite.*.stats
14245         $LCTL set_param llite.*.stats=0
14246
14247         # perform 2 reads and writes so MAX is different from SUM.
14248         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14249         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14250         cancel_lru_locks osc
14251         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14252         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14253
14254         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14255         stack_trap "rm -f $TMP/$tfile.tmp"
14256         while read name count samp unit min max sum sumsq; do
14257                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14258                 eval $name=$count || error "Wrong proc format"
14259
14260                 case $name in
14261                 read_bytes|write_bytes)
14262                         [[ "$unit" =~ "bytes" ]] ||
14263                                 error "unit is not 'bytes': $unit"
14264                         (( $count == 2 )) || error "count is not 2: $count"
14265                         (( $min == $PAGE_SIZE )) ||
14266                                 error "min is not $PAGE_SIZE: $min"
14267                         (( $max == $PAGE_SIZE )) ||
14268                                 error "max is not $PAGE_SIZE: $max"
14269                         (( $sum == $PAGE_SIZE * 2 )) ||
14270                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14271                         ;;
14272                 read|write)
14273                         [[ "$unit" =~ "usec" ]] ||
14274                                 error "unit is not 'usec': $unit"
14275                         ;;
14276                 *)      ;;
14277                 esac
14278         done < $TMP/$tfile.tmp
14279
14280         #check that we actually got some stats
14281         [ "$read_bytes" ] || error "Missing read_bytes stats"
14282         [ "$write_bytes" ] || error "Missing write_bytes stats"
14283         [ "$read_bytes" != 0 ] || error "no read done"
14284         [ "$write_bytes" != 0 ] || error "no write done"
14285 }
14286 run_test 127b "verify the llite client stats are sane"
14287
14288 test_127c() { # LU-12394
14289         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14290         local size
14291         local bsize
14292         local reads
14293         local writes
14294         local count
14295
14296         $LCTL set_param llite.*.extents_stats=1
14297         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14298
14299         # Use two stripes so there is enough space in default config
14300         $LFS setstripe -c 2 $DIR/$tfile
14301
14302         # Extent stats start at 0-4K and go in power of two buckets
14303         # LL_HIST_START = 12 --> 2^12 = 4K
14304         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14305         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14306         # small configs
14307         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14308                 do
14309                 # Write and read, 2x each, second time at a non-zero offset
14310                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14311                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14312                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14313                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14314                 rm -f $DIR/$tfile
14315         done
14316
14317         $LCTL get_param llite.*.extents_stats
14318
14319         count=2
14320         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14321                 do
14322                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14323                                 grep -m 1 $bsize)
14324                 reads=$(echo $bucket | awk '{print $5}')
14325                 writes=$(echo $bucket | awk '{print $9}')
14326                 [ "$reads" -eq $count ] ||
14327                         error "$reads reads in < $bsize bucket, expect $count"
14328                 [ "$writes" -eq $count ] ||
14329                         error "$writes writes in < $bsize bucket, expect $count"
14330         done
14331
14332         # Test mmap write and read
14333         $LCTL set_param llite.*.extents_stats=c
14334         size=512
14335         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14336         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14337         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14338
14339         $LCTL get_param llite.*.extents_stats
14340
14341         count=$(((size*1024) / PAGE_SIZE))
14342
14343         bsize=$((2 * PAGE_SIZE / 1024))K
14344
14345         bucket=$($LCTL get_param -n llite.*.extents_stats |
14346                         grep -m 1 $bsize)
14347         reads=$(echo $bucket | awk '{print $5}')
14348         writes=$(echo $bucket | awk '{print $9}')
14349         # mmap writes fault in the page first, creating an additonal read
14350         [ "$reads" -eq $((2 * count)) ] ||
14351                 error "$reads reads in < $bsize bucket, expect $count"
14352         [ "$writes" -eq $count ] ||
14353                 error "$writes writes in < $bsize bucket, expect $count"
14354 }
14355 run_test 127c "test llite extent stats with regular & mmap i/o"
14356
14357 test_128() { # bug 15212
14358         touch $DIR/$tfile
14359         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14360                 find $DIR/$tfile
14361                 find $DIR/$tfile
14362         EOF
14363
14364         result=$(grep error $TMP/$tfile.log)
14365         rm -f $DIR/$tfile $TMP/$tfile.log
14366         [ -z "$result" ] ||
14367                 error "consecutive find's under interactive lfs failed"
14368 }
14369 run_test 128 "interactive lfs for 2 consecutive find's"
14370
14371 set_dir_limits () {
14372         local mntdev
14373         local canondev
14374         local node
14375
14376         local ldproc=/proc/fs/ldiskfs
14377         local facets=$(get_facets MDS)
14378
14379         for facet in ${facets//,/ }; do
14380                 canondev=$(ldiskfs_canon \
14381                            *.$(convert_facet2label $facet).mntdev $facet)
14382                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14383                         ldproc=/sys/fs/ldiskfs
14384                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14385                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14386         done
14387 }
14388
14389 check_mds_dmesg() {
14390         local facets=$(get_facets MDS)
14391         for facet in ${facets//,/ }; do
14392                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14393         done
14394         return 1
14395 }
14396
14397 test_129() {
14398         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14399         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14400                 skip "Need MDS version with at least 2.5.56"
14401         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14402                 skip_env "ldiskfs only test"
14403         fi
14404         remote_mds_nodsh && skip "remote MDS with nodsh"
14405
14406         local ENOSPC=28
14407         local has_warning=false
14408
14409         rm -rf $DIR/$tdir
14410         mkdir -p $DIR/$tdir
14411
14412         # block size of mds1
14413         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14414         set_dir_limits $maxsize $((maxsize * 6 / 8))
14415         stack_trap "set_dir_limits 0 0"
14416         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14417         local dirsize=$(stat -c%s "$DIR/$tdir")
14418         local nfiles=0
14419         while (( $dirsize <= $maxsize )); do
14420                 $MCREATE $DIR/$tdir/file_base_$nfiles
14421                 rc=$?
14422                 # check two errors:
14423                 # ENOSPC for ext4 max_dir_size, which has been used since
14424                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14425                 if (( rc == ENOSPC )); then
14426                         set_dir_limits 0 0
14427                         echo "rc=$rc returned as expected after $nfiles files"
14428
14429                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14430                                 error "create failed w/o dir size limit"
14431
14432                         # messages may be rate limited if test is run repeatedly
14433                         check_mds_dmesg '"is approaching max"' ||
14434                                 echo "warning message should be output"
14435                         check_mds_dmesg '"has reached max"' ||
14436                                 echo "reached message should be output"
14437
14438                         dirsize=$(stat -c%s "$DIR/$tdir")
14439
14440                         [[ $dirsize -ge $maxsize ]] && return 0
14441                         error "dirsize $dirsize < $maxsize after $nfiles files"
14442                 elif (( rc != 0 )); then
14443                         break
14444                 fi
14445                 nfiles=$((nfiles + 1))
14446                 dirsize=$(stat -c%s "$DIR/$tdir")
14447         done
14448
14449         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14450 }
14451 run_test 129 "test directory size limit ========================"
14452
14453 OLDIFS="$IFS"
14454 cleanup_130() {
14455         trap 0
14456         IFS="$OLDIFS"
14457 }
14458
14459 test_130a() {
14460         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14461         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14462
14463         trap cleanup_130 EXIT RETURN
14464
14465         local fm_file=$DIR/$tfile
14466         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14467         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14468                 error "dd failed for $fm_file"
14469
14470         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14471         filefrag -ves $fm_file
14472         local rc=$?
14473         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14474                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14475         (( $rc == 0 )) || error "filefrag $fm_file failed"
14476
14477         filefrag_op=$(filefrag -ve -k $fm_file |
14478                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14479         local lun=$($LFS getstripe -i $fm_file)
14480
14481         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14482         IFS=$'\n'
14483         local tot_len=0
14484         for line in $filefrag_op; do
14485                 local frag_lun=$(echo $line | cut -d: -f5)
14486                 local ext_len=$(echo $line | cut -d: -f4)
14487
14488                 if (( $frag_lun != $lun )); then
14489                         error "FIEMAP on 1-stripe file($fm_file) failed"
14490                         return
14491                 fi
14492                 (( tot_len += ext_len ))
14493         done
14494
14495         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14496                 error "FIEMAP on 1-stripe file($fm_file) failed"
14497                 return
14498         fi
14499
14500         echo "FIEMAP on single striped file succeeded"
14501 }
14502 run_test 130a "FIEMAP (1-stripe file)"
14503
14504 test_130b() {
14505         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14506
14507         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14508         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14509         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14510                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14511
14512         trap cleanup_130 EXIT RETURN
14513
14514         local fm_file=$DIR/$tfile
14515         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14516                 error "setstripe on $fm_file"
14517
14518         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14519                 error "dd failed on $fm_file"
14520
14521         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14522         filefrag_op=$(filefrag -ve -k $fm_file |
14523                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14524
14525         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14526                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14527
14528         IFS=$'\n'
14529         local tot_len=0
14530         local num_luns=1
14531
14532         for line in $filefrag_op; do
14533                 local frag_lun=$(echo $line | cut -d: -f5 |
14534                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14535                 local ext_len=$(echo $line | cut -d: -f4)
14536                 if (( $frag_lun != $last_lun )); then
14537                         if (( tot_len != 1024 )); then
14538                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14539                                 return
14540                         else
14541                                 (( num_luns += 1 ))
14542                                 tot_len=0
14543                         fi
14544                 fi
14545                 (( tot_len += ext_len ))
14546                 last_lun=$frag_lun
14547         done
14548         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14549                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14550                 return
14551         fi
14552
14553         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14554 }
14555 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14556
14557 test_130c() {
14558         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14559
14560         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14561         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14562         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14563                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14564
14565         trap cleanup_130 EXIT RETURN
14566
14567         local fm_file=$DIR/$tfile
14568         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14569
14570         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14571                 error "dd failed on $fm_file"
14572
14573         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14574         filefrag_op=$(filefrag -ve -k $fm_file |
14575                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14576
14577         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14578                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14579
14580         IFS=$'\n'
14581         local tot_len=0
14582         local num_luns=1
14583         for line in $filefrag_op; do
14584                 local frag_lun=$(echo $line | cut -d: -f5 |
14585                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14586                 local ext_len=$(echo $line | cut -d: -f4)
14587                 if (( $frag_lun != $last_lun )); then
14588                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14589                         if (( logical != 512 )); then
14590                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14591                                 return
14592                         fi
14593                         if (( tot_len != 512 )); then
14594                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14595                                 return
14596                         else
14597                                 (( num_luns += 1 ))
14598                                 tot_len=0
14599                         fi
14600                 fi
14601                 (( tot_len += ext_len ))
14602                 last_lun=$frag_lun
14603         done
14604         if (( num_luns != 2 || tot_len != 512 )); then
14605                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14606                 return
14607         fi
14608
14609         echo "FIEMAP on 2-stripe file with hole succeeded"
14610 }
14611 run_test 130c "FIEMAP (2-stripe file with hole)"
14612
14613 test_130d() {
14614         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14615
14616         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14617         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14618         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14619                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14620
14621         trap cleanup_130 EXIT RETURN
14622
14623         local fm_file=$DIR/$tfile
14624         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14625                         error "setstripe on $fm_file"
14626
14627         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14628         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14629                 error "dd failed on $fm_file"
14630
14631         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14632         filefrag_op=$(filefrag -ve -k $fm_file |
14633                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14634
14635         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14636                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14637
14638         IFS=$'\n'
14639         local tot_len=0
14640         local num_luns=1
14641         for line in $filefrag_op; do
14642                 local frag_lun=$(echo $line | cut -d: -f5 |
14643                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14644                 local ext_len=$(echo $line | cut -d: -f4)
14645                 if (( $frag_lun != $last_lun )); then
14646                         if (( tot_len != 1024 )); then
14647                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14648                                 return
14649                         else
14650                                 (( num_luns += 1 ))
14651                                 local tot_len=0
14652                         fi
14653                 fi
14654                 (( tot_len += ext_len ))
14655                 last_lun=$frag_lun
14656         done
14657         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14658                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14659                 return
14660         fi
14661
14662         echo "FIEMAP on N-stripe file succeeded"
14663 }
14664 run_test 130d "FIEMAP (N-stripe file)"
14665
14666 test_130e() {
14667         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14668
14669         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14670         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14671         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14672                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14673
14674         trap cleanup_130 EXIT RETURN
14675
14676         local fm_file=$DIR/$tfile
14677         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14678
14679         local num_blks=512
14680         local expected_len=$(( (num_blks / 2) * 64 ))
14681         for ((i = 0; i < $num_blks; i++)); do
14682                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14683                         conv=notrunc > /dev/null 2>&1
14684         done
14685
14686         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14687         filefrag_op=$(filefrag -ve -k $fm_file |
14688                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14689
14690         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14691
14692         IFS=$'\n'
14693         local tot_len=0
14694         local num_luns=1
14695         for line in $filefrag_op; do
14696                 local frag_lun=$(echo $line | cut -d: -f5)
14697                 local ext_len=$(echo $line | cut -d: -f4)
14698                 if (( $frag_lun != $last_lun )); then
14699                         if (( tot_len != $expected_len )); then
14700                                 error "OST$last_lun $tot_len != $expected_len"
14701                         else
14702                                 (( num_luns += 1 ))
14703                                 tot_len=0
14704                         fi
14705                 fi
14706                 (( tot_len += ext_len ))
14707                 last_lun=$frag_lun
14708         done
14709         if (( num_luns != 2 || tot_len != $expected_len )); then
14710                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14711         fi
14712
14713         echo "FIEMAP with continuation calls succeeded"
14714 }
14715 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14716
14717 test_130f() {
14718         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14719         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14720         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14721                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14722
14723         local fm_file=$DIR/$tfile
14724         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14725                 error "multiop create with lov_delay_create on $fm_file"
14726
14727         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14728         filefrag_extents=$(filefrag -vek $fm_file |
14729                            awk '/extents? found/ { print $2 }')
14730         if (( $filefrag_extents != 0 )); then
14731                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14732         fi
14733
14734         rm -f $fm_file
14735 }
14736 run_test 130f "FIEMAP (unstriped file)"
14737
14738 test_130g() {
14739         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14740                 skip "Need MDS version with at least 2.12.53 for overstriping"
14741         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14742         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14743         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14744                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14745
14746         local file=$DIR/$tfile
14747         local nr=$((OSTCOUNT * 100))
14748
14749         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14750
14751         stack_trap "rm -f $file"
14752         dd if=/dev/zero of=$file count=$nr bs=1M
14753         sync
14754         nr=$($LFS getstripe -c $file)
14755
14756         local extents=$(filefrag -v $file |
14757                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14758
14759         echo "filefrag list $extents extents in file with stripecount $nr"
14760         if (( extents < nr )); then
14761                 $LFS getstripe $file
14762                 filefrag -v $file
14763                 error "filefrag printed $extents < $nr extents"
14764         fi
14765 }
14766 run_test 130g "FIEMAP (overstripe file)"
14767
14768 # Test for writev/readv
14769 test_131a() {
14770         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14771                 error "writev test failed"
14772         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14773                 error "readv failed"
14774         rm -f $DIR/$tfile
14775 }
14776 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14777
14778 test_131b() {
14779         local fsize=$((524288 + 1048576 + 1572864))
14780         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14781                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14782                         error "append writev test failed"
14783
14784         ((fsize += 1572864 + 1048576))
14785         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14786                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14787                         error "append writev test failed"
14788         rm -f $DIR/$tfile
14789 }
14790 run_test 131b "test append writev"
14791
14792 test_131c() {
14793         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14794         error "NOT PASS"
14795 }
14796 run_test 131c "test read/write on file w/o objects"
14797
14798 test_131d() {
14799         rwv -f $DIR/$tfile -w -n 1 1572864
14800         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14801         if [ "$NOB" != 1572864 ]; then
14802                 error "Short read filed: read $NOB bytes instead of 1572864"
14803         fi
14804         rm -f $DIR/$tfile
14805 }
14806 run_test 131d "test short read"
14807
14808 test_131e() {
14809         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14810         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14811         error "read hitting hole failed"
14812         rm -f $DIR/$tfile
14813 }
14814 run_test 131e "test read hitting hole"
14815
14816 check_stats() {
14817         local facet=$1
14818         local op=$2
14819         local want=${3:-0}
14820         local res
14821
14822         # open             11 samples [usecs] 468 4793 13658 35791898
14823         case $facet in
14824         mds*) res=($(do_facet $facet \
14825                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14826                  ;;
14827         ost*) res=($(do_facet $facet \
14828                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14829                  ;;
14830         *) error "Wrong facet '$facet'" ;;
14831         esac
14832         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14833         # if $want is zero, it means any stat increment is ok.
14834         if (( $want > 0 )); then
14835                 local count=${res[1]}
14836
14837                 if (( $count != $want )); then
14838                         if [[ $facet =~ "mds" ]]; then
14839                                 do_nodes $(comma_list $(mdts_nodes)) \
14840                                         $LCTL get_param mdt.*.md_stats
14841                         else
14842                                 do_nodes $(comma_list $(osts-nodes)) \
14843                                         $LCTL get_param obdfilter.*.stats
14844                         fi
14845                         error "The $op counter on $facet is $count, not $want"
14846                 fi
14847         fi
14848 }
14849
14850 test_133a() {
14851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14852         remote_ost_nodsh && skip "remote OST with nodsh"
14853         remote_mds_nodsh && skip "remote MDS with nodsh"
14854         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14855                 skip_env "MDS doesn't support rename stats"
14856
14857         local testdir=$DIR/${tdir}/stats_testdir
14858
14859         mkdir -p $DIR/${tdir}
14860
14861         # clear stats.
14862         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14863         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14864
14865         # verify mdt stats first.
14866         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14867         check_stats $SINGLEMDS "mkdir" 1
14868
14869         # clear "open" from "lfs mkdir" above
14870         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14871         touch ${testdir}/${tfile} || error "touch failed"
14872         check_stats $SINGLEMDS "open" 1
14873         check_stats $SINGLEMDS "close" 1
14874         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14875                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14876                 check_stats $SINGLEMDS "mknod" 2
14877         }
14878         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14879         check_stats $SINGLEMDS "unlink" 1
14880         rm -f ${testdir}/${tfile} || error "file remove failed"
14881         check_stats $SINGLEMDS "unlink" 2
14882
14883         # remove working dir and check mdt stats again.
14884         rmdir ${testdir} || error "rmdir failed"
14885         check_stats $SINGLEMDS "rmdir" 1
14886
14887         local testdir1=$DIR/${tdir}/stats_testdir1
14888         mkdir_on_mdt0 -p ${testdir}
14889         mkdir_on_mdt0 -p ${testdir1}
14890         touch ${testdir1}/test1
14891         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14892         check_stats $SINGLEMDS "crossdir_rename" 1
14893
14894         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14895         check_stats $SINGLEMDS "samedir_rename" 1
14896
14897         rm -rf $DIR/${tdir}
14898 }
14899 run_test 133a "Verifying MDT stats ========================================"
14900
14901 test_133b() {
14902         local res
14903
14904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14905         remote_ost_nodsh && skip "remote OST with nodsh"
14906         remote_mds_nodsh && skip "remote MDS with nodsh"
14907
14908         local testdir=$DIR/${tdir}/stats_testdir
14909
14910         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14911         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14912         touch ${testdir}/${tfile} || error "touch failed"
14913         cancel_lru_locks mdc
14914
14915         # clear stats.
14916         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14917         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14918
14919         # extra mdt stats verification.
14920         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14921         check_stats $SINGLEMDS "setattr" 1
14922         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14923         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14924         then            # LU-1740
14925                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14926                 check_stats $SINGLEMDS "getattr" 1
14927         fi
14928         rm -rf $DIR/${tdir}
14929
14930         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14931         # so the check below is not reliable
14932         [ $MDSCOUNT -eq 1 ] || return 0
14933
14934         # Sleep to avoid a cached response.
14935         #define OBD_STATFS_CACHE_SECONDS 1
14936         sleep 2
14937         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14938         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14939         $LFS df || error "lfs failed"
14940         check_stats $SINGLEMDS "statfs" 1
14941
14942         # check aggregated statfs (LU-10018)
14943         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14944                 return 0
14945         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14946                 return 0
14947         sleep 2
14948         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14949         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14950         df $DIR
14951         check_stats $SINGLEMDS "statfs" 1
14952
14953         # We want to check that the client didn't send OST_STATFS to
14954         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14955         # extra care is needed here.
14956         if remote_mds; then
14957                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14958                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14959
14960                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14961                 [ "$res" ] && error "OST got STATFS"
14962         fi
14963
14964         return 0
14965 }
14966 run_test 133b "Verifying extra MDT stats =================================="
14967
14968 test_133c() {
14969         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14970         remote_ost_nodsh && skip "remote OST with nodsh"
14971         remote_mds_nodsh && skip "remote MDS with nodsh"
14972
14973         local testdir=$DIR/$tdir/stats_testdir
14974
14975         test_mkdir -p $testdir
14976
14977         # verify obdfilter stats.
14978         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14979         sync
14980         cancel_lru_locks osc
14981         wait_delete_completed
14982
14983         # clear stats.
14984         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14985         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14986
14987         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14988                 error "dd failed"
14989         sync
14990         cancel_lru_locks osc
14991         check_stats ost1 "write" 1
14992
14993         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14994         check_stats ost1 "read" 1
14995
14996         > $testdir/$tfile || error "truncate failed"
14997         check_stats ost1 "punch" 1
14998
14999         rm -f $testdir/$tfile || error "file remove failed"
15000         wait_delete_completed
15001         check_stats ost1 "destroy" 1
15002
15003         rm -rf $DIR/$tdir
15004 }
15005 run_test 133c "Verifying OST stats ========================================"
15006
15007 order_2() {
15008         local value=$1
15009         local orig=$value
15010         local order=1
15011
15012         while [ $value -ge 2 ]; do
15013                 order=$((order*2))
15014                 value=$((value/2))
15015         done
15016
15017         if [ $orig -gt $order ]; then
15018                 order=$((order*2))
15019         fi
15020         echo $order
15021 }
15022
15023 size_in_KMGT() {
15024     local value=$1
15025     local size=('K' 'M' 'G' 'T');
15026     local i=0
15027     local size_string=$value
15028
15029     while [ $value -ge 1024 ]; do
15030         if [ $i -gt 3 ]; then
15031             #T is the biggest unit we get here, if that is bigger,
15032             #just return XXXT
15033             size_string=${value}T
15034             break
15035         fi
15036         value=$((value >> 10))
15037         if [ $value -lt 1024 ]; then
15038             size_string=${value}${size[$i]}
15039             break
15040         fi
15041         i=$((i + 1))
15042     done
15043
15044     echo $size_string
15045 }
15046
15047 get_rename_size() {
15048         local size=$1
15049         local context=${2:-.}
15050         local sample=$(do_facet $SINGLEMDS $LCTL \
15051                 get_param mdt.$FSNAME-MDT0000.rename_stats |
15052                 grep -A1 $context |
15053                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
15054         echo $sample
15055 }
15056
15057 test_133d() {
15058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15059         remote_ost_nodsh && skip "remote OST with nodsh"
15060         remote_mds_nodsh && skip "remote MDS with nodsh"
15061         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
15062                 skip_env "MDS doesn't support rename stats"
15063
15064         local testdir1=$DIR/${tdir}/stats_testdir1
15065         local testdir2=$DIR/${tdir}/stats_testdir2
15066         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
15067
15068         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15069
15070         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
15071         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
15072
15073         createmany -o $testdir1/test 512 || error "createmany failed"
15074
15075         # check samedir rename size
15076         mv ${testdir1}/test0 ${testdir1}/test_0
15077
15078         local testdir1_size=$(ls -l $DIR/${tdir} |
15079                 awk '/stats_testdir1/ {print $5}')
15080         local testdir2_size=$(ls -l $DIR/${tdir} |
15081                 awk '/stats_testdir2/ {print $5}')
15082
15083         testdir1_size=$(order_2 $testdir1_size)
15084         testdir2_size=$(order_2 $testdir2_size)
15085
15086         testdir1_size=$(size_in_KMGT $testdir1_size)
15087         testdir2_size=$(size_in_KMGT $testdir2_size)
15088
15089         echo "source rename dir size: ${testdir1_size}"
15090         echo "target rename dir size: ${testdir2_size}"
15091
15092         local cmd="do_facet $SINGLEMDS $LCTL "
15093         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
15094
15095         eval $cmd || error "$cmd failed"
15096         local samedir=$($cmd | grep 'same_dir')
15097         local same_sample=$(get_rename_size $testdir1_size)
15098         [ -z "$samedir" ] && error "samedir_rename_size count error"
15099         [[ $same_sample -eq 1 ]] ||
15100                 error "samedir_rename_size error $same_sample"
15101         echo "Check same dir rename stats success"
15102
15103         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15104
15105         # check crossdir rename size
15106         mv ${testdir1}/test_0 ${testdir2}/test_0
15107
15108         testdir1_size=$(ls -l $DIR/${tdir} |
15109                 awk '/stats_testdir1/ {print $5}')
15110         testdir2_size=$(ls -l $DIR/${tdir} |
15111                 awk '/stats_testdir2/ {print $5}')
15112
15113         testdir1_size=$(order_2 $testdir1_size)
15114         testdir2_size=$(order_2 $testdir2_size)
15115
15116         testdir1_size=$(size_in_KMGT $testdir1_size)
15117         testdir2_size=$(size_in_KMGT $testdir2_size)
15118
15119         echo "source rename dir size: ${testdir1_size}"
15120         echo "target rename dir size: ${testdir2_size}"
15121
15122         eval $cmd || error "$cmd failed"
15123         local crossdir=$($cmd | grep 'crossdir')
15124         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15125         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15126         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15127         [[ $src_sample -eq 1 ]] ||
15128                 error "crossdir_rename_size error $src_sample"
15129         [[ $tgt_sample -eq 1 ]] ||
15130                 error "crossdir_rename_size error $tgt_sample"
15131         echo "Check cross dir rename stats success"
15132         rm -rf $DIR/${tdir}
15133 }
15134 run_test 133d "Verifying rename_stats ========================================"
15135
15136 test_133e() {
15137         remote_mds_nodsh && skip "remote MDS with nodsh"
15138         remote_ost_nodsh && skip "remote OST with nodsh"
15139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15140
15141         local testdir=$DIR/${tdir}/stats_testdir
15142         local ctr f0 f1 bs=32768 count=42 sum
15143
15144         mkdir -p ${testdir} || error "mkdir failed"
15145
15146         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15147
15148         for ctr in {write,read}_bytes; do
15149                 sync
15150                 cancel_lru_locks osc
15151
15152                 do_facet ost1 $LCTL set_param -n \
15153                         "obdfilter.*.exports.clear=clear"
15154
15155                 if [ $ctr = write_bytes ]; then
15156                         f0=/dev/zero
15157                         f1=${testdir}/${tfile}
15158                 else
15159                         f0=${testdir}/${tfile}
15160                         f1=/dev/null
15161                 fi
15162
15163                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15164                         error "dd failed"
15165                 sync
15166                 cancel_lru_locks osc
15167
15168                 sum=$(do_facet ost1 $LCTL get_param \
15169                         "obdfilter.*.exports.*.stats" |
15170                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15171                                 $1 == ctr { sum += $7 }
15172                                 END { printf("%0.0f", sum) }')
15173
15174                 if ((sum != bs * count)); then
15175                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15176                 fi
15177         done
15178
15179         rm -rf $DIR/${tdir}
15180 }
15181 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15182
15183 test_133f() {
15184         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15185                 skip "too old lustre for get_param -R ($facet_ver)"
15186
15187         # verifying readability.
15188         $LCTL get_param -R '*' &> /dev/null
15189
15190         # Verifing writability with badarea_io.
15191         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15192         local skipped_params='force_lbug|changelog_mask|daemon_file'
15193         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15194                 egrep -v "$skipped_params" |
15195                 xargs -n 1 find $proc_dirs -name |
15196                 xargs -n 1 badarea_io ||
15197                 error "client badarea_io failed"
15198
15199         # remount the FS in case writes/reads /proc break the FS
15200         cleanup || error "failed to unmount"
15201         setup || error "failed to setup"
15202 }
15203 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15204
15205 test_133g() {
15206         remote_mds_nodsh && skip "remote MDS with nodsh"
15207         remote_ost_nodsh && skip "remote OST with nodsh"
15208
15209         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15210         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15211         local facet
15212         for facet in mds1 ost1; do
15213                 local facet_ver=$(lustre_version_code $facet)
15214                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15215                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15216                 else
15217                         log "$facet: too old lustre for get_param -R"
15218                 fi
15219                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15220                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15221                                 tr -d = | egrep -v $skipped_params |
15222                                 xargs -n 1 find $proc_dirs -name |
15223                                 xargs -n 1 badarea_io" ||
15224                                         error "$facet badarea_io failed"
15225                 else
15226                         skip_noexit "$facet: too old lustre for get_param -R"
15227                 fi
15228         done
15229
15230         # remount the FS in case writes/reads /proc break the FS
15231         cleanup || error "failed to unmount"
15232         setup || error "failed to setup"
15233 }
15234 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15235
15236 test_133h() {
15237         remote_mds_nodsh && skip "remote MDS with nodsh"
15238         remote_ost_nodsh && skip "remote OST with nodsh"
15239         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15240                 skip "Need MDS version at least 2.9.54"
15241
15242         local facet
15243         for facet in client mds1 ost1; do
15244                 # Get the list of files that are missing the terminating newline
15245                 local plist=$(do_facet $facet
15246                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15247                 local ent
15248                 for ent in $plist; do
15249                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15250                                 awk -v FS='\v' -v RS='\v\v' \
15251                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15252                                         print FILENAME}'" 2>/dev/null)
15253                         [ -z $missing ] || {
15254                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15255                                 error "file does not end with newline: $facet-$ent"
15256                         }
15257                 done
15258         done
15259 }
15260 run_test 133h "Proc files should end with newlines"
15261
15262 test_134a() {
15263         remote_mds_nodsh && skip "remote MDS with nodsh"
15264         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15265                 skip "Need MDS version at least 2.7.54"
15266
15267         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15268         cancel_lru_locks mdc
15269
15270         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15271         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15272         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15273
15274         local nr=1000
15275         createmany -o $DIR/$tdir/f $nr ||
15276                 error "failed to create $nr files in $DIR/$tdir"
15277         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15278
15279         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15280         do_facet mds1 $LCTL set_param fail_loc=0x327
15281         do_facet mds1 $LCTL set_param fail_val=500
15282         touch $DIR/$tdir/m
15283
15284         echo "sleep 10 seconds ..."
15285         sleep 10
15286         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15287
15288         do_facet mds1 $LCTL set_param fail_loc=0
15289         do_facet mds1 $LCTL set_param fail_val=0
15290         [ $lck_cnt -lt $unused ] ||
15291                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15292
15293         rm $DIR/$tdir/m
15294         unlinkmany $DIR/$tdir/f $nr
15295 }
15296 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15297
15298 test_134b() {
15299         remote_mds_nodsh && skip "remote MDS with nodsh"
15300         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15301                 skip "Need MDS version at least 2.7.54"
15302
15303         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15304         cancel_lru_locks mdc
15305
15306         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15307                         ldlm.lock_reclaim_threshold_mb)
15308         # disable reclaim temporarily
15309         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15310
15311         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15312         do_facet mds1 $LCTL set_param fail_loc=0x328
15313         do_facet mds1 $LCTL set_param fail_val=500
15314
15315         $LCTL set_param debug=+trace
15316
15317         local nr=600
15318         createmany -o $DIR/$tdir/f $nr &
15319         local create_pid=$!
15320
15321         echo "Sleep $TIMEOUT seconds ..."
15322         sleep $TIMEOUT
15323         if ! ps -p $create_pid  > /dev/null 2>&1; then
15324                 do_facet mds1 $LCTL set_param fail_loc=0
15325                 do_facet mds1 $LCTL set_param fail_val=0
15326                 do_facet mds1 $LCTL set_param \
15327                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15328                 error "createmany finished incorrectly!"
15329         fi
15330         do_facet mds1 $LCTL set_param fail_loc=0
15331         do_facet mds1 $LCTL set_param fail_val=0
15332         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15333         wait $create_pid || return 1
15334
15335         unlinkmany $DIR/$tdir/f $nr
15336 }
15337 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15338
15339 test_135() {
15340         remote_mds_nodsh && skip "remote MDS with nodsh"
15341         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15342                 skip "Need MDS version at least 2.13.50"
15343         local fname
15344
15345         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15346
15347 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15348         #set only one record at plain llog
15349         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15350
15351         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15352
15353         #fill already existed plain llog each 64767
15354         #wrapping whole catalog
15355         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15356
15357         createmany -o $DIR/$tdir/$tfile_ 64700
15358         for (( i = 0; i < 64700; i = i + 2 ))
15359         do
15360                 rm $DIR/$tdir/$tfile_$i &
15361                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15362                 local pid=$!
15363                 wait $pid
15364         done
15365
15366         #waiting osp synchronization
15367         wait_delete_completed
15368 }
15369 run_test 135 "Race catalog processing"
15370
15371 test_136() {
15372         remote_mds_nodsh && skip "remote MDS with nodsh"
15373         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15374                 skip "Need MDS version at least 2.13.50"
15375         local fname
15376
15377         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15378         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15379         #set only one record at plain llog
15380 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15381         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15382
15383         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15384
15385         #fill already existed 2 plain llogs each 64767
15386         #wrapping whole catalog
15387         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15388         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15389         wait_delete_completed
15390
15391         createmany -o $DIR/$tdir/$tfile_ 10
15392         sleep 25
15393
15394         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15395         for (( i = 0; i < 10; i = i + 3 ))
15396         do
15397                 rm $DIR/$tdir/$tfile_$i &
15398                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15399                 local pid=$!
15400                 wait $pid
15401                 sleep 7
15402                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15403         done
15404
15405         #waiting osp synchronization
15406         wait_delete_completed
15407 }
15408 run_test 136 "Race catalog processing 2"
15409
15410 test_140() { #bug-17379
15411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15412
15413         test_mkdir $DIR/$tdir
15414         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15415         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15416
15417         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15418         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15419         local i=0
15420         while i=$((i + 1)); do
15421                 test_mkdir $i
15422                 cd $i || error "Changing to $i"
15423                 ln -s ../stat stat || error "Creating stat symlink"
15424                 # Read the symlink until ELOOP present,
15425                 # not LBUGing the system is considered success,
15426                 # we didn't overrun the stack.
15427                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15428                 if [ $ret -ne 0 ]; then
15429                         if [ $ret -eq 40 ]; then
15430                                 break  # -ELOOP
15431                         else
15432                                 error "Open stat symlink"
15433                                         return
15434                         fi
15435                 fi
15436         done
15437         i=$((i - 1))
15438         echo "The symlink depth = $i"
15439         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15440                 error "Invalid symlink depth"
15441
15442         # Test recursive symlink
15443         ln -s symlink_self symlink_self
15444         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15445         echo "open symlink_self returns $ret"
15446         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15447 }
15448 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15449
15450 test_150a() {
15451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15452
15453         local TF="$TMP/$tfile"
15454
15455         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15456         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15457         cp $TF $DIR/$tfile
15458         cancel_lru_locks $OSC
15459         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15460         remount_client $MOUNT
15461         df -P $MOUNT
15462         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15463
15464         $TRUNCATE $TF 6000
15465         $TRUNCATE $DIR/$tfile 6000
15466         cancel_lru_locks $OSC
15467         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15468
15469         echo "12345" >>$TF
15470         echo "12345" >>$DIR/$tfile
15471         cancel_lru_locks $OSC
15472         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15473
15474         echo "12345" >>$TF
15475         echo "12345" >>$DIR/$tfile
15476         cancel_lru_locks $OSC
15477         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15478 }
15479 run_test 150a "truncate/append tests"
15480
15481 test_150b() {
15482         check_set_fallocate_or_skip
15483         local out
15484
15485         touch $DIR/$tfile
15486         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15487         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15488                 skip_eopnotsupp "$out|check_fallocate failed"
15489 }
15490 run_test 150b "Verify fallocate (prealloc) functionality"
15491
15492 test_150bb() {
15493         check_set_fallocate_or_skip
15494
15495         touch $DIR/$tfile
15496         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15497         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15498         > $DIR/$tfile
15499         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15500         # precomputed md5sum for 20MB of zeroes
15501         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15502         local sum=($(md5sum $DIR/$tfile))
15503
15504         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15505
15506         check_set_fallocate 1
15507
15508         > $DIR/$tfile
15509         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15510         sum=($(md5sum $DIR/$tfile))
15511
15512         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15513 }
15514 run_test 150bb "Verify fallocate modes both zero space"
15515
15516 test_150c() {
15517         check_set_fallocate_or_skip
15518         local striping="-c2"
15519
15520         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15521         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15522         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15523         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15524         local want=$((OSTCOUNT * 1048576))
15525
15526         # Must allocate all requested space, not more than 5% extra
15527         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15528                 error "bytes $bytes is not $want"
15529
15530         rm -f $DIR/$tfile
15531
15532         echo "verify fallocate on PFL file"
15533
15534         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15535
15536         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15537                 error "Create $DIR/$tfile failed"
15538         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15539         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15540         want=$((512 * 1048576))
15541
15542         # Must allocate all requested space, not more than 5% extra
15543         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15544                 error "bytes $bytes is not $want"
15545 }
15546 run_test 150c "Verify fallocate Size and Blocks"
15547
15548 test_150d() {
15549         check_set_fallocate_or_skip
15550         local striping="-c2"
15551
15552         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15553
15554         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15555         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15556                 error "setstripe failed"
15557         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15558         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15559         local want=$((OSTCOUNT * 1048576))
15560
15561         # Must allocate all requested space, not more than 5% extra
15562         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15563                 error "bytes $bytes is not $want"
15564 }
15565 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15566
15567 test_150e() {
15568         check_set_fallocate_or_skip
15569
15570         echo "df before:"
15571         $LFS df
15572         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15573         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15574                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15575
15576         # Find OST with Minimum Size
15577         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15578                        sort -un | head -1)
15579
15580         # Get 100MB per OST of the available space to reduce run time
15581         # else 60% of the available space if we are running SLOW tests
15582         if [ $SLOW == "no" ]; then
15583                 local space=$((1024 * 100 * OSTCOUNT))
15584         else
15585                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15586         fi
15587
15588         fallocate -l${space}k $DIR/$tfile ||
15589                 error "fallocate ${space}k $DIR/$tfile failed"
15590         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15591
15592         # get size immediately after fallocate. This should be correctly
15593         # updated
15594         local size=$(stat -c '%s' $DIR/$tfile)
15595         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15596
15597         # Sleep for a while for statfs to get updated. And not pull from cache.
15598         sleep 2
15599
15600         echo "df after fallocate:"
15601         $LFS df
15602
15603         (( size / 1024 == space )) || error "size $size != requested $space"
15604         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15605                 error "used $used < space $space"
15606
15607         rm $DIR/$tfile || error "rm failed"
15608         sync
15609         wait_delete_completed
15610
15611         echo "df after unlink:"
15612         $LFS df
15613 }
15614 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15615
15616 test_150f() {
15617         local size
15618         local blocks
15619         local want_size_before=20480 # in bytes
15620         local want_blocks_before=40 # 512 sized blocks
15621         local want_blocks_after=24  # 512 sized blocks
15622         local length=$(((want_blocks_before - want_blocks_after) * 512))
15623
15624         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15625                 skip "need at least 2.14.0 for fallocate punch"
15626
15627         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15628                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15629         fi
15630
15631         check_set_fallocate_or_skip
15632         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15633
15634         [[ "x$DOM" == "xyes" ]] &&
15635                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15636
15637         echo "Verify fallocate punch: Range within the file range"
15638         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15639                 error "dd failed for bs 4096 and count 5"
15640
15641         # Call fallocate with punch range which is within the file range
15642         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15643                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15644         # client must see changes immediately after fallocate
15645         size=$(stat -c '%s' $DIR/$tfile)
15646         blocks=$(stat -c '%b' $DIR/$tfile)
15647
15648         # Verify punch worked.
15649         (( blocks == want_blocks_after )) ||
15650                 error "punch failed: blocks $blocks != $want_blocks_after"
15651
15652         (( size == want_size_before )) ||
15653                 error "punch failed: size $size != $want_size_before"
15654
15655         # Verify there is hole in file
15656         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15657         # precomputed md5sum
15658         local expect="4a9a834a2db02452929c0a348273b4aa"
15659
15660         cksum=($(md5sum $DIR/$tfile))
15661         [[ "${cksum[0]}" == "$expect" ]] ||
15662                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15663
15664         # Start second sub-case for fallocate punch.
15665         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15666         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15667                 error "dd failed for bs 4096 and count 5"
15668
15669         # Punch range less than block size will have no change in block count
15670         want_blocks_after=40  # 512 sized blocks
15671
15672         # Punch overlaps two blocks and less than blocksize
15673         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15674                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15675         size=$(stat -c '%s' $DIR/$tfile)
15676         blocks=$(stat -c '%b' $DIR/$tfile)
15677
15678         # Verify punch worked.
15679         (( blocks == want_blocks_after )) ||
15680                 error "punch failed: blocks $blocks != $want_blocks_after"
15681
15682         (( size == want_size_before )) ||
15683                 error "punch failed: size $size != $want_size_before"
15684
15685         # Verify if range is really zero'ed out. We expect Zeros.
15686         # precomputed md5sum
15687         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15688         cksum=($(md5sum $DIR/$tfile))
15689         [[ "${cksum[0]}" == "$expect" ]] ||
15690                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15691 }
15692 run_test 150f "Verify fallocate punch functionality"
15693
15694 test_150g() {
15695         local space
15696         local size
15697         local blocks
15698         local blocks_after
15699         local size_after
15700         local BS=4096 # Block size in bytes
15701
15702         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15703                 skip "need at least 2.14.0 for fallocate punch"
15704
15705         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15706                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15707         fi
15708
15709         check_set_fallocate_or_skip
15710         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15711
15712         if [[ "x$DOM" == "xyes" ]]; then
15713                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15714                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15715         else
15716                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15717                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15718         fi
15719
15720         # Get 100MB per OST of the available space to reduce run time
15721         # else 60% of the available space if we are running SLOW tests
15722         if [ $SLOW == "no" ]; then
15723                 space=$((1024 * 100 * OSTCOUNT))
15724         else
15725                 # Find OST with Minimum Size
15726                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15727                         sort -un | head -1)
15728                 echo "min size OST: $space"
15729                 space=$(((space * 60)/100 * OSTCOUNT))
15730         fi
15731         # space in 1k units, round to 4k blocks
15732         local blkcount=$((space * 1024 / $BS))
15733
15734         echo "Verify fallocate punch: Very large Range"
15735         fallocate -l${space}k $DIR/$tfile ||
15736                 error "fallocate ${space}k $DIR/$tfile failed"
15737         # write 1M at the end, start and in the middle
15738         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15739                 error "dd failed: bs $BS count 256"
15740         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15741                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15742         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15743                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15744
15745         # Gather stats.
15746         size=$(stat -c '%s' $DIR/$tfile)
15747
15748         # gather punch length.
15749         local punch_size=$((size - (BS * 2)))
15750
15751         echo "punch_size = $punch_size"
15752         echo "size - punch_size: $((size - punch_size))"
15753         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15754
15755         # Call fallocate to punch all except 2 blocks. We leave the
15756         # first and the last block
15757         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15758         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15759                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15760
15761         size_after=$(stat -c '%s' $DIR/$tfile)
15762         blocks_after=$(stat -c '%b' $DIR/$tfile)
15763
15764         # Verify punch worked.
15765         # Size should be kept
15766         (( size == size_after )) ||
15767                 error "punch failed: size $size != $size_after"
15768
15769         # two 4k data blocks to remain plus possible 1 extra extent block
15770         (( blocks_after <= ((BS / 512) * 3) )) ||
15771                 error "too many blocks remains: $blocks_after"
15772
15773         # Verify that file has hole between the first and the last blocks
15774         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15775         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15776
15777         echo "Hole at [$hole_start, $hole_end)"
15778         (( hole_start == BS )) ||
15779                 error "no hole at offset $BS after punch"
15780
15781         (( hole_end == BS + punch_size )) ||
15782                 error "data at offset $hole_end < $((BS + punch_size))"
15783 }
15784 run_test 150g "Verify fallocate punch on large range"
15785
15786 test_150h() {
15787         local file=$DIR/$tfile
15788         local size
15789
15790         check_set_fallocate_or_skip
15791         statx_supported || skip_env "Test must be statx() syscall supported"
15792
15793         # fallocate() does not update the size information on the MDT
15794         fallocate -l 16K $file || error "failed to fallocate $file"
15795         cancel_lru_locks $OSC
15796         # STATX with cached-always mode will not send glimpse RPCs to OST,
15797         # it uses the caching attrs on the client side as much as possible.
15798         size=$($STATX --cached=always -c %s $file)
15799         [ $size == 16384 ] ||
15800                 error "size after fallocate() is $size, expected 16384"
15801 }
15802 run_test 150h "Verify extend fallocate updates the file size"
15803
15804 #LU-2902 roc_hit was not able to read all values from lproc
15805 function roc_hit_init() {
15806         local list=$(comma_list $(osts_nodes))
15807         local dir=$DIR/$tdir-check
15808         local file=$dir/$tfile
15809         local BEFORE
15810         local AFTER
15811         local idx
15812
15813         test_mkdir $dir
15814         #use setstripe to do a write to every ost
15815         for i in $(seq 0 $((OSTCOUNT-1))); do
15816                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15817                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15818                 idx=$(printf %04x $i)
15819                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15820                         awk '$1 == "cache_access" {sum += $7}
15821                                 END { printf("%0.0f", sum) }')
15822
15823                 cancel_lru_locks osc
15824                 cat $file >/dev/null
15825
15826                 AFTER=$(get_osd_param $list *OST*$idx stats |
15827                         awk '$1 == "cache_access" {sum += $7}
15828                                 END { printf("%0.0f", sum) }')
15829
15830                 echo BEFORE:$BEFORE AFTER:$AFTER
15831                 if ! let "AFTER - BEFORE == 4"; then
15832                         rm -rf $dir
15833                         error "roc_hit is not safe to use"
15834                 fi
15835                 rm $file
15836         done
15837
15838         rm -rf $dir
15839 }
15840
15841 function roc_hit() {
15842         local list=$(comma_list $(osts_nodes))
15843         echo $(get_osd_param $list '' stats |
15844                 awk '$1 == "cache_hit" {sum += $7}
15845                         END { printf("%0.0f", sum) }')
15846 }
15847
15848 function set_cache() {
15849         local on=1
15850
15851         if [ "$2" == "off" ]; then
15852                 on=0;
15853         fi
15854         local list=$(comma_list $(osts_nodes))
15855         set_osd_param $list '' $1_cache_enable $on
15856
15857         cancel_lru_locks osc
15858 }
15859
15860 test_151() {
15861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15862         remote_ost_nodsh && skip "remote OST with nodsh"
15863
15864         local CPAGES=3
15865         local list=$(comma_list $(osts_nodes))
15866
15867         # check whether obdfilter is cache capable at all
15868         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15869                 skip "not cache-capable obdfilter"
15870         fi
15871
15872         # check cache is enabled on all obdfilters
15873         if get_osd_param $list '' read_cache_enable | grep 0; then
15874                 skip "oss cache is disabled"
15875         fi
15876
15877         set_osd_param $list '' writethrough_cache_enable 1
15878
15879         # check write cache is enabled on all obdfilters
15880         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15881                 skip "oss write cache is NOT enabled"
15882         fi
15883
15884         roc_hit_init
15885
15886         #define OBD_FAIL_OBD_NO_LRU  0x609
15887         do_nodes $list $LCTL set_param fail_loc=0x609
15888
15889         # pages should be in the case right after write
15890         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15891                 error "dd failed"
15892
15893         local BEFORE=$(roc_hit)
15894         cancel_lru_locks osc
15895         cat $DIR/$tfile >/dev/null
15896         local AFTER=$(roc_hit)
15897
15898         do_nodes $list $LCTL set_param fail_loc=0
15899
15900         if ! let "AFTER - BEFORE == CPAGES"; then
15901                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15902         fi
15903
15904         cancel_lru_locks osc
15905         # invalidates OST cache
15906         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15907         set_osd_param $list '' read_cache_enable 0
15908         cat $DIR/$tfile >/dev/null
15909
15910         # now data shouldn't be found in the cache
15911         BEFORE=$(roc_hit)
15912         cancel_lru_locks osc
15913         cat $DIR/$tfile >/dev/null
15914         AFTER=$(roc_hit)
15915         if let "AFTER - BEFORE != 0"; then
15916                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15917         fi
15918
15919         set_osd_param $list '' read_cache_enable 1
15920         rm -f $DIR/$tfile
15921 }
15922 run_test 151 "test cache on oss and controls ==============================="
15923
15924 test_152() {
15925         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15926
15927         local TF="$TMP/$tfile"
15928
15929         # simulate ENOMEM during write
15930 #define OBD_FAIL_OST_NOMEM      0x226
15931         lctl set_param fail_loc=0x80000226
15932         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15933         cp $TF $DIR/$tfile
15934         sync || error "sync failed"
15935         lctl set_param fail_loc=0
15936
15937         # discard client's cache
15938         cancel_lru_locks osc
15939
15940         # simulate ENOMEM during read
15941         lctl set_param fail_loc=0x80000226
15942         cmp $TF $DIR/$tfile || error "cmp failed"
15943         lctl set_param fail_loc=0
15944
15945         rm -f $TF
15946 }
15947 run_test 152 "test read/write with enomem ============================"
15948
15949 test_153() {
15950         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15951 }
15952 run_test 153 "test if fdatasync does not crash ======================="
15953
15954 dot_lustre_fid_permission_check() {
15955         local fid=$1
15956         local ffid=$MOUNT/.lustre/fid/$fid
15957         local test_dir=$2
15958
15959         echo "stat fid $fid"
15960         stat $ffid || error "stat $ffid failed."
15961         echo "touch fid $fid"
15962         touch $ffid || error "touch $ffid failed."
15963         echo "write to fid $fid"
15964         cat /etc/hosts > $ffid || error "write $ffid failed."
15965         echo "read fid $fid"
15966         diff /etc/hosts $ffid || error "read $ffid failed."
15967         echo "append write to fid $fid"
15968         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15969         echo "rename fid $fid"
15970         mv $ffid $test_dir/$tfile.1 &&
15971                 error "rename $ffid to $tfile.1 should fail."
15972         touch $test_dir/$tfile.1
15973         mv $test_dir/$tfile.1 $ffid &&
15974                 error "rename $tfile.1 to $ffid should fail."
15975         rm -f $test_dir/$tfile.1
15976         echo "truncate fid $fid"
15977         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15978         echo "link fid $fid"
15979         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15980         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15981                 echo "setfacl fid $fid"
15982                 setfacl -R -m u:$USER0:rwx $ffid ||
15983                         error "setfacl $ffid failed"
15984                 echo "getfacl fid $fid"
15985                 getfacl $ffid || error "getfacl $ffid failed."
15986         fi
15987         echo "unlink fid $fid"
15988         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15989         echo "mknod fid $fid"
15990         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15991
15992         fid=[0xf00000400:0x1:0x0]
15993         ffid=$MOUNT/.lustre/fid/$fid
15994
15995         echo "stat non-exist fid $fid"
15996         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15997         echo "write to non-exist fid $fid"
15998         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15999         echo "link new fid $fid"
16000         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
16001
16002         mkdir -p $test_dir/$tdir
16003         touch $test_dir/$tdir/$tfile
16004         fid=$($LFS path2fid $test_dir/$tdir)
16005         rc=$?
16006         [ $rc -ne 0 ] &&
16007                 error "error: could not get fid for $test_dir/$dir/$tfile."
16008
16009         ffid=$MOUNT/.lustre/fid/$fid
16010
16011         echo "ls $fid"
16012         ls $ffid || error "ls $ffid failed."
16013         echo "touch $fid/$tfile.1"
16014         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
16015
16016         echo "touch $MOUNT/.lustre/fid/$tfile"
16017         touch $MOUNT/.lustre/fid/$tfile && \
16018                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
16019
16020         echo "setxattr to $MOUNT/.lustre/fid"
16021         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
16022
16023         echo "listxattr for $MOUNT/.lustre/fid"
16024         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
16025
16026         echo "delxattr from $MOUNT/.lustre/fid"
16027         setfattr -x trusted.name1 $MOUNT/.lustre/fid
16028
16029         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
16030         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
16031                 error "touch invalid fid should fail."
16032
16033         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
16034         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
16035                 error "touch non-normal fid should fail."
16036
16037         echo "rename $tdir to $MOUNT/.lustre/fid"
16038         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
16039                 error "rename to $MOUNT/.lustre/fid should fail."
16040
16041         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
16042         then            # LU-3547
16043                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
16044                 local new_obf_mode=777
16045
16046                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
16047                 chmod $new_obf_mode $DIR/.lustre/fid ||
16048                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
16049
16050                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
16051                 [ $obf_mode -eq $new_obf_mode ] ||
16052                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
16053
16054                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
16055                 chmod $old_obf_mode $DIR/.lustre/fid ||
16056                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
16057         fi
16058
16059         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
16060         fid=$($LFS path2fid $test_dir/$tfile-2)
16061
16062         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
16063         then # LU-5424
16064                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
16065                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
16066                         error "create lov data thru .lustre failed"
16067         fi
16068         echo "cp /etc/passwd $test_dir/$tfile-2"
16069         cp /etc/passwd $test_dir/$tfile-2 ||
16070                 error "copy to $test_dir/$tfile-2 failed."
16071         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
16072         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
16073                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
16074
16075         rm -rf $test_dir/tfile.lnk
16076         rm -rf $test_dir/$tfile-2
16077 }
16078
16079 test_154A() {
16080         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16081                 skip "Need MDS version at least 2.4.1"
16082
16083         local tf=$DIR/$tfile
16084         touch $tf
16085
16086         local fid=$($LFS path2fid $tf)
16087         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
16088
16089         # check that we get the same pathname back
16090         local rootpath
16091         local found
16092         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
16093                 echo "$rootpath $fid"
16094                 found=$($LFS fid2path $rootpath "$fid")
16095                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
16096                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
16097         done
16098
16099         # check wrong root path format
16100         rootpath=$MOUNT"_wrong"
16101         found=$($LFS fid2path $rootpath "$fid")
16102         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16103 }
16104 run_test 154A "lfs path2fid and fid2path basic checks"
16105
16106 test_154B() {
16107         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16108                 skip "Need MDS version at least 2.4.1"
16109
16110         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16111         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16112         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16113         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16114
16115         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16116         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16117
16118         # check that we get the same pathname
16119         echo "PFID: $PFID, name: $name"
16120         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16121         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16122         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16123                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16124
16125         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16126 }
16127 run_test 154B "verify the ll_decode_linkea tool"
16128
16129 test_154a() {
16130         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16131         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16132         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16133                 skip "Need MDS version at least 2.2.51"
16134         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16135
16136         cp /etc/hosts $DIR/$tfile
16137
16138         fid=$($LFS path2fid $DIR/$tfile)
16139         rc=$?
16140         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16141
16142         dot_lustre_fid_permission_check "$fid" $DIR ||
16143                 error "dot lustre permission check $fid failed"
16144
16145         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16146
16147         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16148
16149         touch $MOUNT/.lustre/file &&
16150                 error "creation is not allowed under .lustre"
16151
16152         mkdir $MOUNT/.lustre/dir &&
16153                 error "mkdir is not allowed under .lustre"
16154
16155         rm -rf $DIR/$tfile
16156 }
16157 run_test 154a "Open-by-FID"
16158
16159 test_154b() {
16160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16161         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16162         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16163         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16164                 skip "Need MDS version at least 2.2.51"
16165
16166         local remote_dir=$DIR/$tdir/remote_dir
16167         local MDTIDX=1
16168         local rc=0
16169
16170         mkdir -p $DIR/$tdir
16171         $LFS mkdir -i $MDTIDX $remote_dir ||
16172                 error "create remote directory failed"
16173
16174         cp /etc/hosts $remote_dir/$tfile
16175
16176         fid=$($LFS path2fid $remote_dir/$tfile)
16177         rc=$?
16178         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16179
16180         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16181                 error "dot lustre permission check $fid failed"
16182         rm -rf $DIR/$tdir
16183 }
16184 run_test 154b "Open-by-FID for remote directory"
16185
16186 test_154c() {
16187         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16188                 skip "Need MDS version at least 2.4.1"
16189
16190         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16191         local FID1=$($LFS path2fid $DIR/$tfile.1)
16192         local FID2=$($LFS path2fid $DIR/$tfile.2)
16193         local FID3=$($LFS path2fid $DIR/$tfile.3)
16194
16195         local N=1
16196         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16197                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16198                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16199                 local want=FID$N
16200                 [ "$FID" = "${!want}" ] ||
16201                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16202                 N=$((N + 1))
16203         done
16204
16205         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16206         do
16207                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16208                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16209                 N=$((N + 1))
16210         done
16211 }
16212 run_test 154c "lfs path2fid and fid2path multiple arguments"
16213
16214 test_154d() {
16215         remote_mds_nodsh && skip "remote MDS with nodsh"
16216         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16217                 skip "Need MDS version at least 2.5.53"
16218
16219         if remote_mds; then
16220                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16221         else
16222                 nid="0@lo"
16223         fi
16224         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16225         local fd
16226         local cmd
16227
16228         rm -f $DIR/$tfile
16229         touch $DIR/$tfile
16230
16231         local fid=$($LFS path2fid $DIR/$tfile)
16232         # Open the file
16233         fd=$(free_fd)
16234         cmd="exec $fd<$DIR/$tfile"
16235         eval $cmd
16236         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16237         echo "$fid_list" | grep "$fid"
16238         rc=$?
16239
16240         cmd="exec $fd>/dev/null"
16241         eval $cmd
16242         if [ $rc -ne 0 ]; then
16243                 error "FID $fid not found in open files list $fid_list"
16244         fi
16245 }
16246 run_test 154d "Verify open file fid"
16247
16248 test_154e()
16249 {
16250         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16251                 skip "Need MDS version at least 2.6.50"
16252
16253         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16254                 error ".lustre returned by readdir"
16255         fi
16256 }
16257 run_test 154e ".lustre is not returned by readdir"
16258
16259 test_154f() {
16260         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16261
16262         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16263         mkdir_on_mdt0 $DIR/$tdir
16264         # test dirs inherit from its stripe
16265         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16266         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16267         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16268         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16269         touch $DIR/f
16270
16271         # get fid of parents
16272         local FID0=$($LFS path2fid $DIR/$tdir)
16273         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16274         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16275         local FID3=$($LFS path2fid $DIR)
16276
16277         # check that path2fid --parents returns expected <parent_fid>/name
16278         # 1) test for a directory (single parent)
16279         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16280         [ "$parent" == "$FID0/foo1" ] ||
16281                 error "expected parent: $FID0/foo1, got: $parent"
16282
16283         # 2) test for a file with nlink > 1 (multiple parents)
16284         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16285         echo "$parent" | grep -F "$FID1/$tfile" ||
16286                 error "$FID1/$tfile not returned in parent list"
16287         echo "$parent" | grep -F "$FID2/link" ||
16288                 error "$FID2/link not returned in parent list"
16289
16290         # 3) get parent by fid
16291         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16292         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16293         echo "$parent" | grep -F "$FID1/$tfile" ||
16294                 error "$FID1/$tfile not returned in parent list (by fid)"
16295         echo "$parent" | grep -F "$FID2/link" ||
16296                 error "$FID2/link not returned in parent list (by fid)"
16297
16298         # 4) test for entry in root directory
16299         parent=$($LFS path2fid --parents $DIR/f)
16300         echo "$parent" | grep -F "$FID3/f" ||
16301                 error "$FID3/f not returned in parent list"
16302
16303         # 5) test it on root directory
16304         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16305                 error "$MOUNT should not have parents"
16306
16307         # enable xattr caching and check that linkea is correctly updated
16308         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16309         save_lustre_params client "llite.*.xattr_cache" > $save
16310         lctl set_param llite.*.xattr_cache 1
16311
16312         # 6.1) linkea update on rename
16313         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16314
16315         # get parents by fid
16316         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16317         # foo1 should no longer be returned in parent list
16318         echo "$parent" | grep -F "$FID1" &&
16319                 error "$FID1 should no longer be in parent list"
16320         # the new path should appear
16321         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16322                 error "$FID2/$tfile.moved is not in parent list"
16323
16324         # 6.2) linkea update on unlink
16325         rm -f $DIR/$tdir/foo2/link
16326         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16327         # foo2/link should no longer be returned in parent list
16328         echo "$parent" | grep -F "$FID2/link" &&
16329                 error "$FID2/link should no longer be in parent list"
16330         true
16331
16332         rm -f $DIR/f
16333         restore_lustre_params < $save
16334         rm -f $save
16335 }
16336 run_test 154f "get parent fids by reading link ea"
16337
16338 test_154g()
16339 {
16340         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16341            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16342                 skip "Need MDS version at least 2.6.92"
16343
16344         mkdir_on_mdt0 $DIR/$tdir
16345         llapi_fid_test -d $DIR/$tdir
16346 }
16347 run_test 154g "various llapi FID tests"
16348
16349 test_154h()
16350 {
16351         (( $CLIENT_VERSION >= $(version_code 2.15.55.1) )) ||
16352                 skip "Need client at least version 2.15.55.1"
16353
16354         # Create an empty file
16355         touch $DIR/$tfile
16356
16357         # Get FID (interactive mode) and save under $TMP/$tfile.log
16358         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
16359                 path2fid $DIR/$tfile
16360         EOF
16361
16362         fid=$(cat $TMP/$tfile.log)
16363         # $fid should not be empty
16364         [[ ! -z $fid ]] || error "FID is empty"
16365         $LFS rmfid $DIR "$fid" || error "rmfid failed for $fid"
16366 }
16367 run_test 154h "Verify interactive path2fid"
16368
16369 test_155_small_load() {
16370     local temp=$TMP/$tfile
16371     local file=$DIR/$tfile
16372
16373     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16374         error "dd of=$temp bs=6096 count=1 failed"
16375     cp $temp $file
16376     cancel_lru_locks $OSC
16377     cmp $temp $file || error "$temp $file differ"
16378
16379     $TRUNCATE $temp 6000
16380     $TRUNCATE $file 6000
16381     cmp $temp $file || error "$temp $file differ (truncate1)"
16382
16383     echo "12345" >>$temp
16384     echo "12345" >>$file
16385     cmp $temp $file || error "$temp $file differ (append1)"
16386
16387     echo "12345" >>$temp
16388     echo "12345" >>$file
16389     cmp $temp $file || error "$temp $file differ (append2)"
16390
16391     rm -f $temp $file
16392     true
16393 }
16394
16395 test_155_big_load() {
16396         remote_ost_nodsh && skip "remote OST with nodsh"
16397
16398         local temp=$TMP/$tfile
16399         local file=$DIR/$tfile
16400
16401         free_min_max
16402         local cache_size=$(do_facet ost$((MAXI+1)) \
16403                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16404
16405         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16406         # pre-set value
16407         if [ -z "$cache_size" ]; then
16408                 cache_size=256
16409         fi
16410         local large_file_size=$((cache_size * 2))
16411
16412         echo "OSS cache size: $cache_size KB"
16413         echo "Large file size: $large_file_size KB"
16414
16415         [ $MAXV -le $large_file_size ] &&
16416                 skip_env "max available OST size needs > $large_file_size KB"
16417
16418         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16419
16420         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16421                 error "dd of=$temp bs=$large_file_size count=1k failed"
16422         cp $temp $file
16423         ls -lh $temp $file
16424         cancel_lru_locks osc
16425         cmp $temp $file || error "$temp $file differ"
16426
16427         rm -f $temp $file
16428         true
16429 }
16430
16431 save_writethrough() {
16432         local facets=$(get_facets OST)
16433
16434         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16435 }
16436
16437 test_155a() {
16438         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16439
16440         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16441
16442         save_writethrough $p
16443
16444         set_cache read on
16445         set_cache writethrough on
16446         test_155_small_load
16447         restore_lustre_params < $p
16448         rm -f $p
16449 }
16450 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16451
16452 test_155b() {
16453         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16454
16455         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16456
16457         save_writethrough $p
16458
16459         set_cache read on
16460         set_cache writethrough off
16461         test_155_small_load
16462         restore_lustre_params < $p
16463         rm -f $p
16464 }
16465 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16466
16467 test_155c() {
16468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16469
16470         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16471
16472         save_writethrough $p
16473
16474         set_cache read off
16475         set_cache writethrough on
16476         test_155_small_load
16477         restore_lustre_params < $p
16478         rm -f $p
16479 }
16480 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16481
16482 test_155d() {
16483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16484
16485         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16486
16487         save_writethrough $p
16488
16489         set_cache read off
16490         set_cache writethrough off
16491         test_155_small_load
16492         restore_lustre_params < $p
16493         rm -f $p
16494 }
16495 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16496
16497 test_155e() {
16498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16499
16500         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16501
16502         save_writethrough $p
16503
16504         set_cache read on
16505         set_cache writethrough on
16506         test_155_big_load
16507         restore_lustre_params < $p
16508         rm -f $p
16509 }
16510 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16511
16512 test_155f() {
16513         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16514
16515         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16516
16517         save_writethrough $p
16518
16519         set_cache read on
16520         set_cache writethrough off
16521         test_155_big_load
16522         restore_lustre_params < $p
16523         rm -f $p
16524 }
16525 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16526
16527 test_155g() {
16528         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16529
16530         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16531
16532         save_writethrough $p
16533
16534         set_cache read off
16535         set_cache writethrough on
16536         test_155_big_load
16537         restore_lustre_params < $p
16538         rm -f $p
16539 }
16540 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16541
16542 test_155h() {
16543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16544
16545         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16546
16547         save_writethrough $p
16548
16549         set_cache read off
16550         set_cache writethrough off
16551         test_155_big_load
16552         restore_lustre_params < $p
16553         rm -f $p
16554 }
16555 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16556
16557 test_156() {
16558         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16559         remote_ost_nodsh && skip "remote OST with nodsh"
16560         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16561                 skip "stats not implemented on old servers"
16562         [ "$ost1_FSTYPE" = "zfs" ] &&
16563                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16564
16565         local CPAGES=3
16566         local BEFORE
16567         local AFTER
16568         local file="$DIR/$tfile"
16569         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16570
16571         save_writethrough $p
16572         roc_hit_init
16573
16574         log "Turn on read and write cache"
16575         set_cache read on
16576         set_cache writethrough on
16577
16578         log "Write data and read it back."
16579         log "Read should be satisfied from the cache."
16580         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16581         BEFORE=$(roc_hit)
16582         cancel_lru_locks osc
16583         cat $file >/dev/null
16584         AFTER=$(roc_hit)
16585         if ! let "AFTER - BEFORE == CPAGES"; then
16586                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16587         else
16588                 log "cache hits: before: $BEFORE, after: $AFTER"
16589         fi
16590
16591         log "Read again; it should be satisfied from the cache."
16592         BEFORE=$AFTER
16593         cancel_lru_locks osc
16594         cat $file >/dev/null
16595         AFTER=$(roc_hit)
16596         if ! let "AFTER - BEFORE == CPAGES"; then
16597                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16598         else
16599                 log "cache hits:: before: $BEFORE, after: $AFTER"
16600         fi
16601
16602         log "Turn off the read cache and turn on the write cache"
16603         set_cache read off
16604         set_cache writethrough on
16605
16606         log "Read again; it should be satisfied from the cache."
16607         BEFORE=$(roc_hit)
16608         cancel_lru_locks osc
16609         cat $file >/dev/null
16610         AFTER=$(roc_hit)
16611         if ! let "AFTER - BEFORE == CPAGES"; then
16612                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16613         else
16614                 log "cache hits:: before: $BEFORE, after: $AFTER"
16615         fi
16616
16617         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16618                 # > 2.12.56 uses pagecache if cached
16619                 log "Read again; it should not be satisfied from the cache."
16620                 BEFORE=$AFTER
16621                 cancel_lru_locks osc
16622                 cat $file >/dev/null
16623                 AFTER=$(roc_hit)
16624                 if ! let "AFTER - BEFORE == 0"; then
16625                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16626                 else
16627                         log "cache hits:: before: $BEFORE, after: $AFTER"
16628                 fi
16629         fi
16630
16631         log "Write data and read it back."
16632         log "Read should be satisfied from the cache."
16633         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16634         BEFORE=$(roc_hit)
16635         cancel_lru_locks osc
16636         cat $file >/dev/null
16637         AFTER=$(roc_hit)
16638         if ! let "AFTER - BEFORE == CPAGES"; then
16639                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16640         else
16641                 log "cache hits:: before: $BEFORE, after: $AFTER"
16642         fi
16643
16644         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16645                 # > 2.12.56 uses pagecache if cached
16646                 log "Read again; it should not be satisfied from the cache."
16647                 BEFORE=$AFTER
16648                 cancel_lru_locks osc
16649                 cat $file >/dev/null
16650                 AFTER=$(roc_hit)
16651                 if ! let "AFTER - BEFORE == 0"; then
16652                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16653                 else
16654                         log "cache hits:: before: $BEFORE, after: $AFTER"
16655                 fi
16656         fi
16657
16658         log "Turn off read and write cache"
16659         set_cache read off
16660         set_cache writethrough off
16661
16662         log "Write data and read it back"
16663         log "It should not be satisfied from the cache."
16664         rm -f $file
16665         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16666         cancel_lru_locks osc
16667         BEFORE=$(roc_hit)
16668         cat $file >/dev/null
16669         AFTER=$(roc_hit)
16670         if ! let "AFTER - BEFORE == 0"; then
16671                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16672         else
16673                 log "cache hits:: before: $BEFORE, after: $AFTER"
16674         fi
16675
16676         log "Turn on the read cache and turn off the write cache"
16677         set_cache read on
16678         set_cache writethrough off
16679
16680         log "Write data and read it back"
16681         log "It should not be satisfied from the cache."
16682         rm -f $file
16683         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16684         BEFORE=$(roc_hit)
16685         cancel_lru_locks osc
16686         cat $file >/dev/null
16687         AFTER=$(roc_hit)
16688         if ! let "AFTER - BEFORE == 0"; then
16689                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16690         else
16691                 log "cache hits:: before: $BEFORE, after: $AFTER"
16692         fi
16693
16694         log "Read again; it should be satisfied from the cache."
16695         BEFORE=$(roc_hit)
16696         cancel_lru_locks osc
16697         cat $file >/dev/null
16698         AFTER=$(roc_hit)
16699         if ! let "AFTER - BEFORE == CPAGES"; then
16700                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16701         else
16702                 log "cache hits:: before: $BEFORE, after: $AFTER"
16703         fi
16704
16705         restore_lustre_params < $p
16706         rm -f $p $file
16707 }
16708 run_test 156 "Verification of tunables"
16709
16710 test_160a() {
16711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16712         remote_mds_nodsh && skip "remote MDS with nodsh"
16713         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16714                 skip "Need MDS version at least 2.2.0"
16715
16716         changelog_register || error "changelog_register failed"
16717         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16718         changelog_users $SINGLEMDS | grep -q $cl_user ||
16719                 error "User $cl_user not found in changelog_users"
16720
16721         mkdir_on_mdt0 $DIR/$tdir
16722
16723         # change something
16724         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16725         changelog_clear 0 || error "changelog_clear failed"
16726         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16727         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16728         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16729         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16730         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16731         rm $DIR/$tdir/pics/desktop.jpg
16732
16733         echo "verifying changelog mask"
16734         changelog_chmask "-MKDIR"
16735         changelog_chmask "-CLOSE"
16736
16737         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16738         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16739
16740         changelog_chmask "+MKDIR"
16741         changelog_chmask "+CLOSE"
16742
16743         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16744         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16745
16746         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16747         CLOSES=$(changelog_dump | grep -c "CLOSE")
16748         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16749         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16750
16751         # verify contents
16752         echo "verifying target fid"
16753         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16754         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16755         [ "$fidc" == "$fidf" ] ||
16756                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16757         echo "verifying parent fid"
16758         # The FID returned from the Changelog may be the directory shard on
16759         # a different MDT, and not the FID returned by path2fid on the parent.
16760         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16761         # since this is what will matter when recreating this file in the tree.
16762         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16763         local pathp=$($LFS fid2path $MOUNT "$fidp")
16764         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16765                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16766
16767         echo "getting records for $cl_user"
16768         changelog_users $SINGLEMDS
16769         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16770         local nclr=3
16771         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16772                 error "changelog_clear failed"
16773         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16774         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16775         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16776                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16777
16778         local min0_rec=$(changelog_users $SINGLEMDS |
16779                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16780         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16781                           awk '{ print $1; exit; }')
16782
16783         changelog_dump | tail -n 5
16784         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16785         [ $first_rec == $((min0_rec + 1)) ] ||
16786                 error "first index should be $min0_rec + 1 not $first_rec"
16787
16788         # LU-3446 changelog index reset on MDT restart
16789         local cur_rec1=$(changelog_users $SINGLEMDS |
16790                          awk '/^current.index:/ { print $NF }')
16791         changelog_clear 0 ||
16792                 error "clear all changelog records for $cl_user failed"
16793         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16794         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16795                 error "Fail to start $SINGLEMDS"
16796         local cur_rec2=$(changelog_users $SINGLEMDS |
16797                          awk '/^current.index:/ { print $NF }')
16798         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16799         [ $cur_rec1 == $cur_rec2 ] ||
16800                 error "current index should be $cur_rec1 not $cur_rec2"
16801
16802         echo "verifying users from this test are deregistered"
16803         changelog_deregister || error "changelog_deregister failed"
16804         changelog_users $SINGLEMDS | grep -q $cl_user &&
16805                 error "User '$cl_user' still in changelog_users"
16806
16807         # lctl get_param -n mdd.*.changelog_users
16808         # current_index: 144
16809         # ID    index (idle seconds)
16810         # cl3   144   (2) mask=<list>
16811         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16812                 # this is the normal case where all users were deregistered
16813                 # make sure no new records are added when no users are present
16814                 local last_rec1=$(changelog_users $SINGLEMDS |
16815                                   awk '/^current.index:/ { print $NF }')
16816                 touch $DIR/$tdir/chloe
16817                 local last_rec2=$(changelog_users $SINGLEMDS |
16818                                   awk '/^current.index:/ { print $NF }')
16819                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16820                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16821         else
16822                 # any changelog users must be leftovers from a previous test
16823                 changelog_users $SINGLEMDS
16824                 echo "other changelog users; can't verify off"
16825         fi
16826 }
16827 run_test 160a "changelog sanity"
16828
16829 test_160b() { # LU-3587
16830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16831         remote_mds_nodsh && skip "remote MDS with nodsh"
16832         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16833                 skip "Need MDS version at least 2.2.0"
16834
16835         changelog_register || error "changelog_register failed"
16836         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16837         changelog_users $SINGLEMDS | grep -q $cl_user ||
16838                 error "User '$cl_user' not found in changelog_users"
16839
16840         local longname1=$(str_repeat a 255)
16841         local longname2=$(str_repeat b 255)
16842
16843         cd $DIR
16844         echo "creating very long named file"
16845         touch $longname1 || error "create of '$longname1' failed"
16846         echo "renaming very long named file"
16847         mv $longname1 $longname2
16848
16849         changelog_dump | grep RENME | tail -n 5
16850         rm -f $longname2
16851 }
16852 run_test 160b "Verify that very long rename doesn't crash in changelog"
16853
16854 test_160c() {
16855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16856         remote_mds_nodsh && skip "remote MDS with nodsh"
16857
16858         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16859                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16860                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16861                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16862
16863         local rc=0
16864
16865         # Registration step
16866         changelog_register || error "changelog_register failed"
16867
16868         rm -rf $DIR/$tdir
16869         mkdir -p $DIR/$tdir
16870         $MCREATE $DIR/$tdir/foo_160c
16871         changelog_chmask "-TRUNC"
16872         $TRUNCATE $DIR/$tdir/foo_160c 200
16873         changelog_chmask "+TRUNC"
16874         $TRUNCATE $DIR/$tdir/foo_160c 199
16875         changelog_dump | tail -n 5
16876         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16877         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16878 }
16879 run_test 160c "verify that changelog log catch the truncate event"
16880
16881 test_160d() {
16882         remote_mds_nodsh && skip "remote MDS with nodsh"
16883         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16885         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16886                 skip "Need MDS version at least 2.7.60"
16887
16888         # Registration step
16889         changelog_register || error "changelog_register failed"
16890
16891         mkdir -p $DIR/$tdir/migrate_dir
16892         changelog_clear 0 || error "changelog_clear failed"
16893
16894         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16895         changelog_dump | tail -n 5
16896         local migrates=$(changelog_dump | grep -c "MIGRT")
16897         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16898 }
16899 run_test 160d "verify that changelog log catch the migrate event"
16900
16901 test_160e() {
16902         remote_mds_nodsh && skip "remote MDS with nodsh"
16903
16904         # Create a user
16905         changelog_register || error "changelog_register failed"
16906
16907         local MDT0=$(facet_svc $SINGLEMDS)
16908         local rc
16909
16910         # No user (expect fail)
16911         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16912         rc=$?
16913         if [ $rc -eq 0 ]; then
16914                 error "Should fail without user"
16915         elif [ $rc -ne 4 ]; then
16916                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16917         fi
16918
16919         # Delete a future user (expect fail)
16920         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16921         rc=$?
16922         if [ $rc -eq 0 ]; then
16923                 error "Deleted non-existant user cl77"
16924         elif [ $rc -ne 2 ]; then
16925                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16926         fi
16927
16928         # Clear to a bad index (1 billion should be safe)
16929         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16930         rc=$?
16931
16932         if [ $rc -eq 0 ]; then
16933                 error "Successfully cleared to invalid CL index"
16934         elif [ $rc -ne 22 ]; then
16935                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16936         fi
16937 }
16938 run_test 160e "changelog negative testing (should return errors)"
16939
16940 test_160f() {
16941         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16942         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16943                 skip "Need MDS version at least 2.10.56"
16944
16945         local mdts=$(comma_list $(mdts_nodes))
16946
16947         # Create a user
16948         changelog_register || error "first changelog_register failed"
16949         changelog_register || error "second changelog_register failed"
16950         local cl_users
16951         declare -A cl_user1
16952         declare -A cl_user2
16953         local user_rec1
16954         local user_rec2
16955         local i
16956
16957         # generate some changelog records to accumulate on each MDT
16958         # use all_char because created files should be evenly distributed
16959         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16960                 error "test_mkdir $tdir failed"
16961         log "$(date +%s): creating first files"
16962         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16963                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16964                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16965         done
16966
16967         # check changelogs have been generated
16968         local start=$SECONDS
16969         local idle_time=$((MDSCOUNT * 5 + 5))
16970         local nbcl=$(changelog_dump | wc -l)
16971         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16972
16973         for param in "changelog_max_idle_time=$idle_time" \
16974                      "changelog_gc=1" \
16975                      "changelog_min_gc_interval=2" \
16976                      "changelog_min_free_cat_entries=3"; do
16977                 local MDT0=$(facet_svc $SINGLEMDS)
16978                 local var="${param%=*}"
16979                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16980
16981                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16982                 do_nodes $mdts $LCTL set_param mdd.*.$param
16983         done
16984
16985         # force cl_user2 to be idle (1st part), but also cancel the
16986         # cl_user1 records so that it is not evicted later in the test.
16987         local sleep1=$((idle_time / 2))
16988         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16989         sleep $sleep1
16990
16991         # simulate changelog catalog almost full
16992         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16993         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16994
16995         for i in $(seq $MDSCOUNT); do
16996                 cl_users=(${CL_USERS[mds$i]})
16997                 cl_user1[mds$i]="${cl_users[0]}"
16998                 cl_user2[mds$i]="${cl_users[1]}"
16999
17000                 [ -n "${cl_user1[mds$i]}" ] ||
17001                         error "mds$i: no user registered"
17002                 [ -n "${cl_user2[mds$i]}" ] ||
17003                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17004
17005                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17006                 [ -n "$user_rec1" ] ||
17007                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17008                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17009                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17010                 [ -n "$user_rec2" ] ||
17011                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17012                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17013                      "$user_rec1 + 2 == $user_rec2"
17014                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17015                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17016                               "$user_rec1 + 2, but is $user_rec2"
17017                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17018                 [ -n "$user_rec2" ] ||
17019                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17020                 [ $user_rec1 == $user_rec2 ] ||
17021                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17022                               "$user_rec1, but is $user_rec2"
17023         done
17024
17025         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
17026         local sleep2=$((idle_time - (SECONDS - start) + 1))
17027         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
17028         sleep $sleep2
17029
17030         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17031         # cl_user1 should be OK because it recently processed records.
17032         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
17033         for ((i = 0; i < MDSCOUNT * 2; i++)); do
17034                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
17035                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
17036         done
17037
17038         # ensure gc thread is done
17039         for i in $(mdts_nodes); do
17040                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17041                         error "$i: GC-thread not done"
17042         done
17043
17044         local first_rec
17045         for (( i = 1; i <= MDSCOUNT; i++ )); do
17046                 # check cl_user1 still registered
17047                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17048                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17049                 # check cl_user2 unregistered
17050                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17051                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17052
17053                 # check changelogs are present and starting at $user_rec1 + 1
17054                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17055                 [ -n "$user_rec1" ] ||
17056                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17057                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17058                             awk '{ print $1; exit; }')
17059
17060                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17061                 [ $((user_rec1 + 1)) == $first_rec ] ||
17062                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17063         done
17064 }
17065 run_test 160f "changelog garbage collect (timestamped users)"
17066
17067 test_160g() {
17068         remote_mds_nodsh && skip "remote MDS with nodsh"
17069         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
17070                 skip "Need MDS version at least 2.14.55"
17071
17072         local mdts=$(comma_list $(mdts_nodes))
17073
17074         # Create a user
17075         changelog_register || error "first changelog_register failed"
17076         changelog_register || error "second changelog_register failed"
17077         local cl_users
17078         declare -A cl_user1
17079         declare -A cl_user2
17080         local user_rec1
17081         local user_rec2
17082         local i
17083
17084         # generate some changelog records to accumulate on each MDT
17085         # use all_char because created files should be evenly distributed
17086         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17087                 error "test_mkdir $tdir failed"
17088         for ((i = 0; i < MDSCOUNT; i++)); do
17089                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17090                         error "create $DIR/$tdir/d$i.1 failed"
17091         done
17092
17093         # check changelogs have been generated
17094         local nbcl=$(changelog_dump | wc -l)
17095         (( $nbcl > 0 )) || error "no changelogs found"
17096
17097         # reduce the max_idle_indexes value to make sure we exceed it
17098         for param in "changelog_max_idle_indexes=2" \
17099                      "changelog_gc=1" \
17100                      "changelog_min_gc_interval=2"; do
17101                 local MDT0=$(facet_svc $SINGLEMDS)
17102                 local var="${param%=*}"
17103                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17104
17105                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17106                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17107                         error "unable to set mdd.*.$param"
17108         done
17109
17110         local start=$SECONDS
17111         for i in $(seq $MDSCOUNT); do
17112                 cl_users=(${CL_USERS[mds$i]})
17113                 cl_user1[mds$i]="${cl_users[0]}"
17114                 cl_user2[mds$i]="${cl_users[1]}"
17115
17116                 [ -n "${cl_user1[mds$i]}" ] ||
17117                         error "mds$i: user1 is not registered"
17118                 [ -n "${cl_user2[mds$i]}" ] ||
17119                         error "mds$i: only ${cl_user1[mds$i]} is registered"
17120
17121                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17122                 [ -n "$user_rec1" ] ||
17123                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17124                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17125                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17126                 [ -n "$user_rec2" ] ||
17127                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17128                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17129                      "$user_rec1 + 2 == $user_rec2"
17130                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17131                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17132                               "expected $user_rec1 + 2, but is $user_rec2"
17133                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17134                 [ -n "$user_rec2" ] ||
17135                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17136                 [ $user_rec1 == $user_rec2 ] ||
17137                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17138                               "expected $user_rec1, but is $user_rec2"
17139         done
17140
17141         # ensure we are past the previous changelog_min_gc_interval set above
17142         local sleep2=$((start + 2 - SECONDS))
17143         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17144         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17145         # cl_user1 should be OK because it recently processed records.
17146         for ((i = 0; i < MDSCOUNT; i++)); do
17147                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17148                         error "create $DIR/$tdir/d$i.3 failed"
17149         done
17150
17151         # ensure gc thread is done
17152         for i in $(mdts_nodes); do
17153                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17154                         error "$i: GC-thread not done"
17155         done
17156
17157         local first_rec
17158         for (( i = 1; i <= MDSCOUNT; i++ )); do
17159                 # check cl_user1 still registered
17160                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17161                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17162                 # check cl_user2 unregistered
17163                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17164                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17165
17166                 # check changelogs are present and starting at $user_rec1 + 1
17167                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17168                 [ -n "$user_rec1" ] ||
17169                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17170                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17171                             awk '{ print $1; exit; }')
17172
17173                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17174                 [ $((user_rec1 + 1)) == $first_rec ] ||
17175                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17176         done
17177 }
17178 run_test 160g "changelog garbage collect on idle records"
17179
17180 test_160h() {
17181         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17182         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17183                 skip "Need MDS version at least 2.10.56"
17184
17185         local mdts=$(comma_list $(mdts_nodes))
17186
17187         # Create a user
17188         changelog_register || error "first changelog_register failed"
17189         changelog_register || error "second changelog_register failed"
17190         local cl_users
17191         declare -A cl_user1
17192         declare -A cl_user2
17193         local user_rec1
17194         local user_rec2
17195         local i
17196
17197         # generate some changelog records to accumulate on each MDT
17198         # use all_char because created files should be evenly distributed
17199         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17200                 error "test_mkdir $tdir failed"
17201         for ((i = 0; i < MDSCOUNT; i++)); do
17202                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17203                         error "create $DIR/$tdir/d$i.1 failed"
17204         done
17205
17206         # check changelogs have been generated
17207         local nbcl=$(changelog_dump | wc -l)
17208         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17209
17210         for param in "changelog_max_idle_time=10" \
17211                      "changelog_gc=1" \
17212                      "changelog_min_gc_interval=2"; do
17213                 local MDT0=$(facet_svc $SINGLEMDS)
17214                 local var="${param%=*}"
17215                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17216
17217                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17218                 do_nodes $mdts $LCTL set_param mdd.*.$param
17219         done
17220
17221         # force cl_user2 to be idle (1st part)
17222         sleep 9
17223
17224         for i in $(seq $MDSCOUNT); do
17225                 cl_users=(${CL_USERS[mds$i]})
17226                 cl_user1[mds$i]="${cl_users[0]}"
17227                 cl_user2[mds$i]="${cl_users[1]}"
17228
17229                 [ -n "${cl_user1[mds$i]}" ] ||
17230                         error "mds$i: no user registered"
17231                 [ -n "${cl_user2[mds$i]}" ] ||
17232                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17233
17234                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17235                 [ -n "$user_rec1" ] ||
17236                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17237                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17238                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17239                 [ -n "$user_rec2" ] ||
17240                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17241                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17242                      "$user_rec1 + 2 == $user_rec2"
17243                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17244                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17245                               "$user_rec1 + 2, but is $user_rec2"
17246                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17247                 [ -n "$user_rec2" ] ||
17248                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17249                 [ $user_rec1 == $user_rec2 ] ||
17250                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17251                               "$user_rec1, but is $user_rec2"
17252         done
17253
17254         # force cl_user2 to be idle (2nd part) and to reach
17255         # changelog_max_idle_time
17256         sleep 2
17257
17258         # force each GC-thread start and block then
17259         # one per MDT/MDD, set fail_val accordingly
17260         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17261         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17262
17263         # generate more changelogs to trigger fail_loc
17264         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17265                 error "create $DIR/$tdir/${tfile}bis failed"
17266
17267         # stop MDT to stop GC-thread, should be done in back-ground as it will
17268         # block waiting for the thread to be released and exit
17269         declare -A stop_pids
17270         for i in $(seq $MDSCOUNT); do
17271                 stop mds$i &
17272                 stop_pids[mds$i]=$!
17273         done
17274
17275         for i in $(mdts_nodes); do
17276                 local facet
17277                 local nb=0
17278                 local facets=$(facets_up_on_host $i)
17279
17280                 for facet in ${facets//,/ }; do
17281                         if [[ $facet == mds* ]]; then
17282                                 nb=$((nb + 1))
17283                         fi
17284                 done
17285                 # ensure each MDS's gc threads are still present and all in "R"
17286                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17287                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17288                         error "$i: expected $nb GC-thread"
17289                 wait_update $i \
17290                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17291                         "R" 20 ||
17292                         error "$i: GC-thread not found in R-state"
17293                 # check umounts of each MDT on MDS have reached kthread_stop()
17294                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17295                         error "$i: expected $nb umount"
17296                 wait_update $i \
17297                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17298                         error "$i: umount not found in D-state"
17299         done
17300
17301         # release all GC-threads
17302         do_nodes $mdts $LCTL set_param fail_loc=0
17303
17304         # wait for MDT stop to complete
17305         for i in $(seq $MDSCOUNT); do
17306                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17307         done
17308
17309         # XXX
17310         # may try to check if any orphan changelog records are present
17311         # via ldiskfs/zfs and llog_reader...
17312
17313         # re-start/mount MDTs
17314         for i in $(seq $MDSCOUNT); do
17315                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17316                         error "Fail to start mds$i"
17317         done
17318
17319         local first_rec
17320         for i in $(seq $MDSCOUNT); do
17321                 # check cl_user1 still registered
17322                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17323                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17324                 # check cl_user2 unregistered
17325                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17326                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17327
17328                 # check changelogs are present and starting at $user_rec1 + 1
17329                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17330                 [ -n "$user_rec1" ] ||
17331                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17332                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17333                             awk '{ print $1; exit; }')
17334
17335                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17336                 [ $((user_rec1 + 1)) == $first_rec ] ||
17337                         error "mds$i: first index should be $user_rec1 + 1, " \
17338                               "but is $first_rec"
17339         done
17340 }
17341 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17342               "during mount"
17343
17344 test_160i() {
17345
17346         local mdts=$(comma_list $(mdts_nodes))
17347
17348         changelog_register || error "first changelog_register failed"
17349
17350         # generate some changelog records to accumulate on each MDT
17351         # use all_char because created files should be evenly distributed
17352         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17353                 error "test_mkdir $tdir failed"
17354         for ((i = 0; i < MDSCOUNT; i++)); do
17355                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17356                         error "create $DIR/$tdir/d$i.1 failed"
17357         done
17358
17359         # check changelogs have been generated
17360         local nbcl=$(changelog_dump | wc -l)
17361         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17362
17363         # simulate race between register and unregister
17364         # XXX as fail_loc is set per-MDS, with DNE configs the race
17365         # simulation will only occur for one MDT per MDS and for the
17366         # others the normal race scenario will take place
17367         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17368         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17369         do_nodes $mdts $LCTL set_param fail_val=1
17370
17371         # unregister 1st user
17372         changelog_deregister &
17373         local pid1=$!
17374         # wait some time for deregister work to reach race rdv
17375         sleep 2
17376         # register 2nd user
17377         changelog_register || error "2nd user register failed"
17378
17379         wait $pid1 || error "1st user deregister failed"
17380
17381         local i
17382         local last_rec
17383         declare -A LAST_REC
17384         for i in $(seq $MDSCOUNT); do
17385                 if changelog_users mds$i | grep "^cl"; then
17386                         # make sure new records are added with one user present
17387                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17388                                           awk '/^current.index:/ { print $NF }')
17389                 else
17390                         error "mds$i has no user registered"
17391                 fi
17392         done
17393
17394         # generate more changelog records to accumulate on each MDT
17395         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17396                 error "create $DIR/$tdir/${tfile}bis failed"
17397
17398         for i in $(seq $MDSCOUNT); do
17399                 last_rec=$(changelog_users $SINGLEMDS |
17400                            awk '/^current.index:/ { print $NF }')
17401                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17402                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17403                         error "changelogs are off on mds$i"
17404         done
17405 }
17406 run_test 160i "changelog user register/unregister race"
17407
17408 test_160j() {
17409         remote_mds_nodsh && skip "remote MDS with nodsh"
17410         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17411                 skip "Need MDS version at least 2.12.56"
17412
17413         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17414         stack_trap "umount $MOUNT2" EXIT
17415
17416         changelog_register || error "first changelog_register failed"
17417         stack_trap "changelog_deregister" EXIT
17418
17419         # generate some changelog
17420         # use all_char because created files should be evenly distributed
17421         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17422                 error "mkdir $tdir failed"
17423         for ((i = 0; i < MDSCOUNT; i++)); do
17424                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17425                         error "create $DIR/$tdir/d$i.1 failed"
17426         done
17427
17428         # open the changelog device
17429         exec 3>/dev/changelog-$FSNAME-MDT0000
17430         stack_trap "exec 3>&-" EXIT
17431         exec 4</dev/changelog-$FSNAME-MDT0000
17432         stack_trap "exec 4<&-" EXIT
17433
17434         # umount the first lustre mount
17435         umount $MOUNT
17436         stack_trap "mount_client $MOUNT" EXIT
17437
17438         # read changelog, which may or may not fail, but should not crash
17439         cat <&4 >/dev/null
17440
17441         # clear changelog
17442         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17443         changelog_users $SINGLEMDS | grep -q $cl_user ||
17444                 error "User $cl_user not found in changelog_users"
17445
17446         printf 'clear:'$cl_user':0' >&3
17447 }
17448 run_test 160j "client can be umounted while its chanangelog is being used"
17449
17450 test_160k() {
17451         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17452         remote_mds_nodsh && skip "remote MDS with nodsh"
17453
17454         mkdir -p $DIR/$tdir/1/1
17455
17456         changelog_register || error "changelog_register failed"
17457         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17458
17459         changelog_users $SINGLEMDS | grep -q $cl_user ||
17460                 error "User '$cl_user' not found in changelog_users"
17461 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17462         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17463         rmdir $DIR/$tdir/1/1 & sleep 1
17464         mkdir $DIR/$tdir/2
17465         touch $DIR/$tdir/2/2
17466         rm -rf $DIR/$tdir/2
17467
17468         wait
17469         sleep 4
17470
17471         changelog_dump | grep rmdir || error "rmdir not recorded"
17472 }
17473 run_test 160k "Verify that changelog records are not lost"
17474
17475 # Verifies that a file passed as a parameter has recently had an operation
17476 # performed on it that has generated an MTIME changelog which contains the
17477 # correct parent FID. As files might reside on a different MDT from the
17478 # parent directory in DNE configurations, the FIDs are translated to paths
17479 # before being compared, which should be identical
17480 compare_mtime_changelog() {
17481         local file="${1}"
17482         local mdtidx
17483         local mtime
17484         local cl_fid
17485         local pdir
17486         local dir
17487
17488         mdtidx=$($LFS getstripe --mdt-index $file)
17489         mdtidx=$(printf "%04x" $mdtidx)
17490
17491         # Obtain the parent FID from the MTIME changelog
17492         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17493         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17494
17495         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17496         [ -z "$cl_fid" ] && error "parent FID not present"
17497
17498         # Verify that the path for the parent FID is the same as the path for
17499         # the test directory
17500         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17501
17502         dir=$(dirname $1)
17503
17504         [[ "${pdir%/}" == "$dir" ]] ||
17505                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17506 }
17507
17508 test_160l() {
17509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17510
17511         remote_mds_nodsh && skip "remote MDS with nodsh"
17512         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17513                 skip "Need MDS version at least 2.13.55"
17514
17515         local cl_user
17516
17517         changelog_register || error "changelog_register failed"
17518         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17519
17520         changelog_users $SINGLEMDS | grep -q $cl_user ||
17521                 error "User '$cl_user' not found in changelog_users"
17522
17523         # Clear some types so that MTIME changelogs are generated
17524         changelog_chmask "-CREAT"
17525         changelog_chmask "-CLOSE"
17526
17527         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17528
17529         # Test CL_MTIME during setattr
17530         touch $DIR/$tdir/$tfile
17531         compare_mtime_changelog $DIR/$tdir/$tfile
17532
17533         # Test CL_MTIME during close
17534         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17535         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17536 }
17537 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17538
17539 test_160m() {
17540         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17541         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17542                 skip "Need MDS version at least 2.14.51"
17543         local cl_users
17544         local cl_user1
17545         local cl_user2
17546         local pid1
17547
17548         # Create a user
17549         changelog_register || error "first changelog_register failed"
17550         changelog_register || error "second changelog_register failed"
17551
17552         cl_users=(${CL_USERS[mds1]})
17553         cl_user1="${cl_users[0]}"
17554         cl_user2="${cl_users[1]}"
17555         # generate some changelog records to accumulate on MDT0
17556         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17557         createmany -m $DIR/$tdir/$tfile 50 ||
17558                 error "create $DIR/$tdir/$tfile failed"
17559         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17560         rm -f $DIR/$tdir
17561
17562         # check changelogs have been generated
17563         local nbcl=$(changelog_dump | wc -l)
17564         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17565
17566 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17567         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17568
17569         __changelog_clear mds1 $cl_user1 +10
17570         __changelog_clear mds1 $cl_user2 0 &
17571         pid1=$!
17572         sleep 2
17573         __changelog_clear mds1 $cl_user1 0 ||
17574                 error "fail to cancel record for $cl_user1"
17575         wait $pid1
17576         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17577 }
17578 run_test 160m "Changelog clear race"
17579
17580 test_160n() {
17581         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17582         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17583                 skip "Need MDS version at least 2.14.51"
17584         local cl_users
17585         local cl_user1
17586         local cl_user2
17587         local pid1
17588         local first_rec
17589         local last_rec=0
17590
17591         # Create a user
17592         changelog_register || error "first changelog_register failed"
17593
17594         cl_users=(${CL_USERS[mds1]})
17595         cl_user1="${cl_users[0]}"
17596
17597         # generate some changelog records to accumulate on MDT0
17598         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17599         first_rec=$(changelog_users $SINGLEMDS |
17600                         awk '/^current.index:/ { print $NF }')
17601         while (( last_rec < (( first_rec + 65000)) )); do
17602                 createmany -m $DIR/$tdir/$tfile 10000 ||
17603                         error "create $DIR/$tdir/$tfile failed"
17604
17605                 for i in $(seq 0 10000); do
17606                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17607                                 > /dev/null
17608                 done
17609
17610                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17611                         error "unlinkmany failed unlink"
17612                 last_rec=$(changelog_users $SINGLEMDS |
17613                         awk '/^current.index:/ { print $NF }')
17614                 echo last record $last_rec
17615                 (( last_rec == 0 )) && error "no changelog found"
17616         done
17617
17618 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17619         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17620
17621         __changelog_clear mds1 $cl_user1 0 &
17622         pid1=$!
17623         sleep 2
17624         __changelog_clear mds1 $cl_user1 0 ||
17625                 error "fail to cancel record for $cl_user1"
17626         wait $pid1
17627         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17628 }
17629 run_test 160n "Changelog destroy race"
17630
17631 test_160o() {
17632         local mdt="$(facet_svc $SINGLEMDS)"
17633
17634         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17635         remote_mds_nodsh && skip "remote MDS with nodsh"
17636         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17637                 skip "Need MDS version at least 2.14.52"
17638
17639         changelog_register --user test_160o -m unlnk+close+open ||
17640                 error "changelog_register failed"
17641
17642         do_facet $SINGLEMDS $LCTL --device $mdt \
17643                                 changelog_register -u "Tt3_-#" &&
17644                 error "bad symbols in name should fail"
17645
17646         do_facet $SINGLEMDS $LCTL --device $mdt \
17647                                 changelog_register -u test_160o &&
17648                 error "the same name registration should fail"
17649
17650         do_facet $SINGLEMDS $LCTL --device $mdt \
17651                         changelog_register -u test_160toolongname &&
17652                 error "too long name registration should fail"
17653
17654         changelog_chmask "MARK+HSM"
17655         lctl get_param mdd.*.changelog*mask
17656         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17657         changelog_users $SINGLEMDS | grep -q $cl_user ||
17658                 error "User $cl_user not found in changelog_users"
17659         #verify username
17660         echo $cl_user | grep -q test_160o ||
17661                 error "User $cl_user has no specific name 'test160o'"
17662
17663         # change something
17664         changelog_clear 0 || error "changelog_clear failed"
17665         # generate some changelog records to accumulate on MDT0
17666         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17667         touch $DIR/$tdir/$tfile                 # open 1
17668
17669         OPENS=$(changelog_dump | grep -c "OPEN")
17670         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17671
17672         # must be no MKDIR it wasn't set as user mask
17673         MKDIR=$(changelog_dump | grep -c "MKDIR")
17674         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17675
17676         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17677                                 mdd.$mdt.changelog_current_mask -n)
17678         # register maskless user
17679         changelog_register || error "changelog_register failed"
17680         # effective mask should be not changed because it is not minimal
17681         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17682                                 mdd.$mdt.changelog_current_mask -n)
17683         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17684         # set server mask to minimal value
17685         changelog_chmask "MARK"
17686         # check effective mask again, should be treated as DEFMASK now
17687         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17688                                 mdd.$mdt.changelog_current_mask -n)
17689         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17690
17691         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17692                 # set server mask back to some value
17693                 changelog_chmask "CLOSE,UNLNK"
17694                 # check effective mask again, should not remain as DEFMASK
17695                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17696                                 mdd.$mdt.changelog_current_mask -n)
17697                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17698         fi
17699
17700         do_facet $SINGLEMDS $LCTL --device $mdt \
17701                                 changelog_deregister -u test_160o ||
17702                 error "cannot deregister by name"
17703 }
17704 run_test 160o "changelog user name and mask"
17705
17706 test_160p() {
17707         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17708         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17709                 skip "Need MDS version at least 2.14.51"
17710         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17711         local cl_users
17712         local cl_user1
17713         local entry_count
17714
17715         # Create a user
17716         changelog_register || error "first changelog_register failed"
17717
17718         cl_users=(${CL_USERS[mds1]})
17719         cl_user1="${cl_users[0]}"
17720
17721         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17722         createmany -m $DIR/$tdir/$tfile 50 ||
17723                 error "create $DIR/$tdir/$tfile failed"
17724         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17725         rm -rf $DIR/$tdir
17726
17727         # check changelogs have been generated
17728         entry_count=$(changelog_dump | wc -l)
17729         ((entry_count != 0)) || error "no changelog entries found"
17730
17731         # remove changelog_users and check that orphan entries are removed
17732         stop mds1
17733         local dev=$(mdsdevname 1)
17734         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17735         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17736         entry_count=$(changelog_dump | wc -l)
17737         ((entry_count == 0)) ||
17738                 error "found $entry_count changelog entries, expected none"
17739 }
17740 run_test 160p "Changelog orphan cleanup with no users"
17741
17742 test_160q() {
17743         local mdt="$(facet_svc $SINGLEMDS)"
17744         local clu
17745
17746         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17747         remote_mds_nodsh && skip "remote MDS with nodsh"
17748         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17749                 skip "Need MDS version at least 2.14.54"
17750
17751         # set server mask to minimal value like server init does
17752         changelog_chmask "MARK"
17753         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17754                 error "changelog_register failed"
17755         # check effective mask again, should be treated as DEFMASK now
17756         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17757                                 mdd.$mdt.changelog_current_mask -n)
17758         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17759                 error "changelog_deregister failed"
17760         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17761 }
17762 run_test 160q "changelog effective mask is DEFMASK if not set"
17763
17764 test_160s() {
17765         remote_mds_nodsh && skip "remote MDS with nodsh"
17766         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17767                 skip "Need MDS version at least 2.14.55"
17768
17769         local mdts=$(comma_list $(mdts_nodes))
17770
17771         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17772         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17773                                        fail_val=$((24 * 3600 * 10))
17774
17775         # Create a user which is 10 days old
17776         changelog_register || error "first changelog_register failed"
17777         local cl_users
17778         declare -A cl_user1
17779         local i
17780
17781         # generate some changelog records to accumulate on each MDT
17782         # use all_char because created files should be evenly distributed
17783         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17784                 error "test_mkdir $tdir failed"
17785         for ((i = 0; i < MDSCOUNT; i++)); do
17786                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17787                         error "create $DIR/$tdir/d$i.1 failed"
17788         done
17789
17790         # check changelogs have been generated
17791         local nbcl=$(changelog_dump | wc -l)
17792         (( nbcl > 0 )) || error "no changelogs found"
17793
17794         # reduce the max_idle_indexes value to make sure we exceed it
17795         for param in "changelog_max_idle_indexes=2097446912" \
17796                      "changelog_max_idle_time=2592000" \
17797                      "changelog_gc=1" \
17798                      "changelog_min_gc_interval=2"; do
17799                 local MDT0=$(facet_svc $SINGLEMDS)
17800                 local var="${param%=*}"
17801                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17802
17803                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17804                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17805                         error "unable to set mdd.*.$param"
17806         done
17807
17808         local start=$SECONDS
17809         for i in $(seq $MDSCOUNT); do
17810                 cl_users=(${CL_USERS[mds$i]})
17811                 cl_user1[mds$i]="${cl_users[0]}"
17812
17813                 [[ -n "${cl_user1[mds$i]}" ]] ||
17814                         error "mds$i: no user registered"
17815         done
17816
17817         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17818         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17819
17820         # ensure we are past the previous changelog_min_gc_interval set above
17821         local sleep2=$((start + 2 - SECONDS))
17822         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17823
17824         # Generate one more changelog to trigger GC
17825         for ((i = 0; i < MDSCOUNT; i++)); do
17826                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17827                         error "create $DIR/$tdir/d$i.3 failed"
17828         done
17829
17830         # ensure gc thread is done
17831         for node in $(mdts_nodes); do
17832                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17833                         error "$node: GC-thread not done"
17834         done
17835
17836         do_nodes $mdts $LCTL set_param fail_loc=0
17837
17838         for (( i = 1; i <= MDSCOUNT; i++ )); do
17839                 # check cl_user1 is purged
17840                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17841                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17842         done
17843         return 0
17844 }
17845 run_test 160s "changelog garbage collect on idle records * time"
17846
17847 test_160t() {
17848         remote_mds_nodsh && skip "remote MDS with nodsh"
17849         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17850                 skip "Need MDS version at least 2.15.50"
17851
17852         local MDT0=$(facet_svc $SINGLEMDS)
17853         local cl_users
17854         local cl_user1
17855         local cl_user2
17856         local start
17857
17858         changelog_register --user user1 -m all ||
17859                 error "user1 failed to register"
17860
17861         mkdir_on_mdt0 $DIR/$tdir
17862         # create default overstripe to maximize changelog size
17863         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17864         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17865         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17866
17867         # user2 consumes less records so less space
17868         changelog_register --user user2 || error "user2 failed to register"
17869         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17870         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17871
17872         # check changelogs have been generated
17873         local nbcl=$(changelog_dump | wc -l)
17874         (( nbcl > 0 )) || error "no changelogs found"
17875
17876         # reduce the changelog_min_gc_interval to force check
17877         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17878                 local var="${param%=*}"
17879                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17880
17881                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17882                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17883                         error "unable to set mdd.*.$param"
17884         done
17885
17886         start=$SECONDS
17887         cl_users=(${CL_USERS[mds1]})
17888         cl_user1="${cl_users[0]}"
17889         cl_user2="${cl_users[1]}"
17890
17891         [[ -n $cl_user1 ]] ||
17892                 error "mds1: user #1 isn't registered"
17893         [[ -n $cl_user2 ]] ||
17894                 error "mds1: user #2 isn't registered"
17895
17896         # ensure we are past the previous changelog_min_gc_interval set above
17897         local sleep2=$((start + 2 - SECONDS))
17898         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17899
17900         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17901         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17902                         fail_val=$(((llog_size1 + llog_size2) / 2))
17903
17904         # Generate more changelog to trigger GC
17905         createmany -o $DIR/$tdir/u3_ 4 ||
17906                 error "create failed for more files"
17907
17908         # ensure gc thread is done
17909         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17910                 error "mds1: GC-thread not done"
17911
17912         do_facet mds1 $LCTL set_param fail_loc=0
17913
17914         # check cl_user1 is purged
17915         changelog_users mds1 | grep -q "$cl_user1" &&
17916                 error "User $cl_user1 is registered"
17917         # check cl_user2 is not purged
17918         changelog_users mds1 | grep -q "$cl_user2" ||
17919                 error "User $cl_user2 is not registered"
17920 }
17921 run_test 160t "changelog garbage collect on lack of space"
17922
17923 test_161a() {
17924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17925
17926         test_mkdir -c1 $DIR/$tdir
17927         cp /etc/hosts $DIR/$tdir/$tfile
17928         test_mkdir -c1 $DIR/$tdir/foo1
17929         test_mkdir -c1 $DIR/$tdir/foo2
17930         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17931         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17932         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17933         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17934         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17935         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17936                 $LFS fid2path $DIR $FID
17937                 error "bad link ea"
17938         fi
17939         # middle
17940         rm $DIR/$tdir/foo2/zachary
17941         # last
17942         rm $DIR/$tdir/foo2/thor
17943         # first
17944         rm $DIR/$tdir/$tfile
17945         # rename
17946         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17947         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17948                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17949         rm $DIR/$tdir/foo2/maggie
17950
17951         # overflow the EA
17952         local longname=$tfile.avg_len_is_thirty_two_
17953         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17954                 error_noexit 'failed to unlink many hardlinks'" EXIT
17955         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17956                 error "failed to hardlink many files"
17957         links=$($LFS fid2path $DIR $FID | wc -l)
17958         echo -n "${links}/1000 links in link EA"
17959         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17960 }
17961 run_test 161a "link ea sanity"
17962
17963 test_161b() {
17964         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17965         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17966
17967         local MDTIDX=1
17968         local remote_dir=$DIR/$tdir/remote_dir
17969
17970         mkdir -p $DIR/$tdir
17971         $LFS mkdir -i $MDTIDX $remote_dir ||
17972                 error "create remote directory failed"
17973
17974         cp /etc/hosts $remote_dir/$tfile
17975         mkdir -p $remote_dir/foo1
17976         mkdir -p $remote_dir/foo2
17977         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17978         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17979         ln $remote_dir/$tfile $remote_dir/foo1/luna
17980         ln $remote_dir/$tfile $remote_dir/foo2/thor
17981
17982         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17983                      tr -d ']')
17984         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17985                 $LFS fid2path $DIR $FID
17986                 error "bad link ea"
17987         fi
17988         # middle
17989         rm $remote_dir/foo2/zachary
17990         # last
17991         rm $remote_dir/foo2/thor
17992         # first
17993         rm $remote_dir/$tfile
17994         # rename
17995         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17996         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17997         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17998                 $LFS fid2path $DIR $FID
17999                 error "bad link rename"
18000         fi
18001         rm $remote_dir/foo2/maggie
18002
18003         # overflow the EA
18004         local longname=filename_avg_len_is_thirty_two_
18005         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
18006                 error "failed to hardlink many files"
18007         links=$($LFS fid2path $DIR $FID | wc -l)
18008         echo -n "${links}/1000 links in link EA"
18009         [[ ${links} -gt 60 ]] ||
18010                 error "expected at least 60 links in link EA"
18011         unlinkmany $remote_dir/foo2/$longname 1000 ||
18012         error "failed to unlink many hardlinks"
18013 }
18014 run_test 161b "link ea sanity under remote directory"
18015
18016 test_161c() {
18017         remote_mds_nodsh && skip "remote MDS with nodsh"
18018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18019         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
18020                 skip "Need MDS version at least 2.1.5"
18021
18022         # define CLF_RENAME_LAST 0x0001
18023         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
18024         changelog_register || error "changelog_register failed"
18025
18026         rm -rf $DIR/$tdir
18027         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
18028         touch $DIR/$tdir/foo_161c
18029         touch $DIR/$tdir/bar_161c
18030         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18031         changelog_dump | grep RENME | tail -n 5
18032         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18033         changelog_clear 0 || error "changelog_clear failed"
18034         if [ x$flags != "x0x1" ]; then
18035                 error "flag $flags is not 0x1"
18036         fi
18037
18038         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
18039         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
18040         touch $DIR/$tdir/foo_161c
18041         touch $DIR/$tdir/bar_161c
18042         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18043         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
18044         changelog_dump | grep RENME | tail -n 5
18045         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
18046         changelog_clear 0 || error "changelog_clear failed"
18047         if [ x$flags != "x0x0" ]; then
18048                 error "flag $flags is not 0x0"
18049         fi
18050         echo "rename overwrite a target having nlink > 1," \
18051                 "changelog record has flags of $flags"
18052
18053         # rename doesn't overwrite a target (changelog flag 0x0)
18054         touch $DIR/$tdir/foo_161c
18055         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
18056         changelog_dump | grep RENME | tail -n 5
18057         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
18058         changelog_clear 0 || error "changelog_clear failed"
18059         if [ x$flags != "x0x0" ]; then
18060                 error "flag $flags is not 0x0"
18061         fi
18062         echo "rename doesn't overwrite a target," \
18063                 "changelog record has flags of $flags"
18064
18065         # define CLF_UNLINK_LAST 0x0001
18066         # unlink a file having nlink = 1 (changelog flag 0x1)
18067         rm -f $DIR/$tdir/foo2_161c
18068         changelog_dump | grep UNLNK | tail -n 5
18069         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18070         changelog_clear 0 || error "changelog_clear failed"
18071         if [ x$flags != "x0x1" ]; then
18072                 error "flag $flags is not 0x1"
18073         fi
18074         echo "unlink a file having nlink = 1," \
18075                 "changelog record has flags of $flags"
18076
18077         # unlink a file having nlink > 1 (changelog flag 0x0)
18078         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
18079         rm -f $DIR/$tdir/foobar_161c
18080         changelog_dump | grep UNLNK | tail -n 5
18081         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
18082         changelog_clear 0 || error "changelog_clear failed"
18083         if [ x$flags != "x0x0" ]; then
18084                 error "flag $flags is not 0x0"
18085         fi
18086         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
18087 }
18088 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
18089
18090 test_161d() {
18091         remote_mds_nodsh && skip "remote MDS with nodsh"
18092         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
18093
18094         local pid
18095         local fid
18096
18097         changelog_register || error "changelog_register failed"
18098
18099         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
18100         # interfer with $MOUNT/.lustre/fid/ access
18101         mkdir $DIR/$tdir
18102         [[ $? -eq 0 ]] || error "mkdir failed"
18103
18104         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
18105         $LCTL set_param fail_loc=0x8000140c
18106         # 5s pause
18107         $LCTL set_param fail_val=5
18108
18109         # create file
18110         echo foofoo > $DIR/$tdir/$tfile &
18111         pid=$!
18112
18113         # wait for create to be delayed
18114         sleep 2
18115
18116         ps -p $pid
18117         [[ $? -eq 0 ]] || error "create should be blocked"
18118
18119         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
18120         stack_trap "rm -f $tempfile"
18121         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18122         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18123         # some delay may occur during ChangeLog publishing and file read just
18124         # above, that could allow file write to happen finally
18125         [[ -s $tempfile ]] && echo "file should be empty"
18126
18127         $LCTL set_param fail_loc=0
18128
18129         wait $pid
18130         [[ $? -eq 0 ]] || error "create failed"
18131 }
18132 run_test 161d "create with concurrent .lustre/fid access"
18133
18134 check_path() {
18135         local expected="$1"
18136         shift
18137         local fid="$2"
18138
18139         local path
18140         path=$($LFS fid2path "$@")
18141         local rc=$?
18142
18143         if [ $rc -ne 0 ]; then
18144                 error "path looked up of '$expected' failed: rc=$rc"
18145         elif [ "$path" != "$expected" ]; then
18146                 error "path looked up '$path' instead of '$expected'"
18147         else
18148                 echo "FID '$fid' resolves to path '$path' as expected"
18149         fi
18150 }
18151
18152 test_162a() { # was test_162
18153         test_mkdir -p -c1 $DIR/$tdir/d2
18154         touch $DIR/$tdir/d2/$tfile
18155         touch $DIR/$tdir/d2/x1
18156         touch $DIR/$tdir/d2/x2
18157         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18158         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18159         # regular file
18160         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18161         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18162
18163         # softlink
18164         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18165         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18166         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18167
18168         # softlink to wrong file
18169         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18170         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18171         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18172
18173         # hardlink
18174         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18175         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18176         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18177         # fid2path dir/fsname should both work
18178         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18179         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18180
18181         # hardlink count: check that there are 2 links
18182         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18183         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18184
18185         # hardlink indexing: remove the first link
18186         rm $DIR/$tdir/d2/p/q/r/hlink
18187         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18188 }
18189 run_test 162a "path lookup sanity"
18190
18191 test_162b() {
18192         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18193         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18194
18195         mkdir $DIR/$tdir
18196         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18197                                 error "create striped dir failed"
18198
18199         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18200                                         tail -n 1 | awk '{print $2}')
18201         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18202
18203         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18204         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18205
18206         # regular file
18207         for ((i=0;i<5;i++)); do
18208                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18209                         error "get fid for f$i failed"
18210                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18211
18212                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18213                         error "get fid for d$i failed"
18214                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18215         done
18216
18217         return 0
18218 }
18219 run_test 162b "striped directory path lookup sanity"
18220
18221 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18222 test_162c() {
18223         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18224                 skip "Need MDS version at least 2.7.51"
18225
18226         local lpath=$tdir.local
18227         local rpath=$tdir.remote
18228
18229         test_mkdir $DIR/$lpath
18230         test_mkdir $DIR/$rpath
18231
18232         for ((i = 0; i <= 101; i++)); do
18233                 lpath="$lpath/$i"
18234                 mkdir $DIR/$lpath
18235                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18236                         error "get fid for local directory $DIR/$lpath failed"
18237                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18238
18239                 rpath="$rpath/$i"
18240                 test_mkdir $DIR/$rpath
18241                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18242                         error "get fid for remote directory $DIR/$rpath failed"
18243                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18244         done
18245
18246         return 0
18247 }
18248 run_test 162c "fid2path works with paths 100 or more directories deep"
18249
18250 oalr_event_count() {
18251         local event="${1}"
18252         local trace="${2}"
18253
18254         awk -v name="${FSNAME}-OST0000" \
18255             -v event="${event}" \
18256             '$1 == "TRACE" && $2 == event && $3 == name' \
18257             "${trace}" |
18258         wc -l
18259 }
18260
18261 oalr_expect_event_count() {
18262         local event="${1}"
18263         local trace="${2}"
18264         local expect="${3}"
18265         local count
18266
18267         count=$(oalr_event_count "${event}" "${trace}")
18268         if ((count == expect)); then
18269                 return 0
18270         fi
18271
18272         error_noexit "${event} event count was '${count}', expected ${expect}"
18273         cat "${trace}" >&2
18274         exit 1
18275 }
18276
18277 cleanup_165() {
18278         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18279         stop ost1
18280         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18281 }
18282
18283 setup_165() {
18284         sync # Flush previous IOs so we can count log entries.
18285         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18286         stack_trap cleanup_165 EXIT
18287 }
18288
18289 test_165a() {
18290         local trace="/tmp/${tfile}.trace"
18291         local rc
18292         local count
18293
18294         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18295                 skip "OFD access log unsupported"
18296
18297         setup_165
18298         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18299         sleep 5
18300
18301         do_facet ost1 ofd_access_log_reader --list
18302         stop ost1
18303
18304         do_facet ost1 killall -TERM ofd_access_log_reader
18305         wait
18306         rc=$?
18307
18308         if ((rc != 0)); then
18309                 error "ofd_access_log_reader exited with rc = '${rc}'"
18310         fi
18311
18312         # Parse trace file for discovery events:
18313         oalr_expect_event_count alr_log_add "${trace}" 1
18314         oalr_expect_event_count alr_log_eof "${trace}" 1
18315         oalr_expect_event_count alr_log_free "${trace}" 1
18316 }
18317 run_test 165a "ofd access log discovery"
18318
18319 test_165b() {
18320         local trace="/tmp/${tfile}.trace"
18321         local file="${DIR}/${tfile}"
18322         local pfid1
18323         local pfid2
18324         local -a entry
18325         local rc
18326         local count
18327         local size
18328         local flags
18329
18330         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18331                 skip "OFD access log unsupported"
18332
18333         setup_165
18334         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18335         sleep 5
18336
18337         do_facet ost1 ofd_access_log_reader --list
18338
18339         lfs setstripe -c 1 -i 0 "${file}"
18340         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18341                 error "cannot create '${file}'"
18342
18343         sleep 5
18344         do_facet ost1 killall -TERM ofd_access_log_reader
18345         wait
18346         rc=$?
18347
18348         if ((rc != 0)); then
18349                 error "ofd_access_log_reader exited with rc = '${rc}'"
18350         fi
18351
18352         oalr_expect_event_count alr_log_entry "${trace}" 1
18353
18354         pfid1=$($LFS path2fid "${file}")
18355
18356         # 1     2             3   4    5     6   7    8    9     10
18357         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18358         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18359
18360         echo "entry = '${entry[*]}'" >&2
18361
18362         pfid2=${entry[4]}
18363         if [[ "${pfid1}" != "${pfid2}" ]]; then
18364                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18365         fi
18366
18367         size=${entry[8]}
18368         if ((size != 1048576)); then
18369                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18370         fi
18371
18372         flags=${entry[10]}
18373         if [[ "${flags}" != "w" ]]; then
18374                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18375         fi
18376
18377         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18378         sleep 5
18379
18380         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18381                 error "cannot read '${file}'"
18382         sleep 5
18383
18384         do_facet ost1 killall -TERM ofd_access_log_reader
18385         wait
18386         rc=$?
18387
18388         if ((rc != 0)); then
18389                 error "ofd_access_log_reader exited with rc = '${rc}'"
18390         fi
18391
18392         oalr_expect_event_count alr_log_entry "${trace}" 1
18393
18394         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18395         echo "entry = '${entry[*]}'" >&2
18396
18397         pfid2=${entry[4]}
18398         if [[ "${pfid1}" != "${pfid2}" ]]; then
18399                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18400         fi
18401
18402         size=${entry[8]}
18403         if ((size != 524288)); then
18404                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18405         fi
18406
18407         flags=${entry[10]}
18408         if [[ "${flags}" != "r" ]]; then
18409                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18410         fi
18411 }
18412 run_test 165b "ofd access log entries are produced and consumed"
18413
18414 test_165c() {
18415         local trace="/tmp/${tfile}.trace"
18416         local file="${DIR}/${tdir}/${tfile}"
18417
18418         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18419                 skip "OFD access log unsupported"
18420
18421         test_mkdir "${DIR}/${tdir}"
18422
18423         setup_165
18424         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18425         sleep 5
18426
18427         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18428
18429         # 4096 / 64 = 64. Create twice as many entries.
18430         for ((i = 0; i < 128; i++)); do
18431                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18432                         error "cannot create file"
18433         done
18434
18435         sync
18436
18437         do_facet ost1 killall -TERM ofd_access_log_reader
18438         wait
18439         rc=$?
18440         if ((rc != 0)); then
18441                 error "ofd_access_log_reader exited with rc = '${rc}'"
18442         fi
18443
18444         unlinkmany  "${file}-%d" 128
18445 }
18446 run_test 165c "full ofd access logs do not block IOs"
18447
18448 oal_get_read_count() {
18449         local stats="$1"
18450
18451         # STATS lustre-OST0001 alr_read_count 1
18452
18453         do_facet ost1 cat "${stats}" |
18454         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18455              END { print count; }'
18456 }
18457
18458 oal_expect_read_count() {
18459         local stats="$1"
18460         local count
18461         local expect="$2"
18462
18463         # Ask ofd_access_log_reader to write stats.
18464         do_facet ost1 killall -USR1 ofd_access_log_reader
18465
18466         # Allow some time for things to happen.
18467         sleep 1
18468
18469         count=$(oal_get_read_count "${stats}")
18470         if ((count == expect)); then
18471                 return 0
18472         fi
18473
18474         error_noexit "bad read count, got ${count}, expected ${expect}"
18475         do_facet ost1 cat "${stats}" >&2
18476         exit 1
18477 }
18478
18479 test_165d() {
18480         local stats="/tmp/${tfile}.stats"
18481         local file="${DIR}/${tdir}/${tfile}"
18482         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18483
18484         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18485                 skip "OFD access log unsupported"
18486
18487         test_mkdir "${DIR}/${tdir}"
18488
18489         setup_165
18490         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18491         sleep 5
18492
18493         lfs setstripe -c 1 -i 0 "${file}"
18494
18495         do_facet ost1 lctl set_param "${param}=rw"
18496         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18497                 error "cannot create '${file}'"
18498         oal_expect_read_count "${stats}" 1
18499
18500         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18501                 error "cannot read '${file}'"
18502         oal_expect_read_count "${stats}" 2
18503
18504         do_facet ost1 lctl set_param "${param}=r"
18505         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18506                 error "cannot create '${file}'"
18507         oal_expect_read_count "${stats}" 2
18508
18509         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18510                 error "cannot read '${file}'"
18511         oal_expect_read_count "${stats}" 3
18512
18513         do_facet ost1 lctl set_param "${param}=w"
18514         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18515                 error "cannot create '${file}'"
18516         oal_expect_read_count "${stats}" 4
18517
18518         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18519                 error "cannot read '${file}'"
18520         oal_expect_read_count "${stats}" 4
18521
18522         do_facet ost1 lctl set_param "${param}=0"
18523         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18524                 error "cannot create '${file}'"
18525         oal_expect_read_count "${stats}" 4
18526
18527         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18528                 error "cannot read '${file}'"
18529         oal_expect_read_count "${stats}" 4
18530
18531         do_facet ost1 killall -TERM ofd_access_log_reader
18532         wait
18533         rc=$?
18534         if ((rc != 0)); then
18535                 error "ofd_access_log_reader exited with rc = '${rc}'"
18536         fi
18537 }
18538 run_test 165d "ofd_access_log mask works"
18539
18540 test_165e() {
18541         local stats="/tmp/${tfile}.stats"
18542         local file0="${DIR}/${tdir}-0/${tfile}"
18543         local file1="${DIR}/${tdir}-1/${tfile}"
18544
18545         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18546                 skip "OFD access log unsupported"
18547
18548         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18549
18550         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18551         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18552
18553         lfs setstripe -c 1 -i 0 "${file0}"
18554         lfs setstripe -c 1 -i 0 "${file1}"
18555
18556         setup_165
18557         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18558         sleep 5
18559
18560         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18561                 error "cannot create '${file0}'"
18562         sync
18563         oal_expect_read_count "${stats}" 0
18564
18565         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18566                 error "cannot create '${file1}'"
18567         sync
18568         oal_expect_read_count "${stats}" 1
18569
18570         do_facet ost1 killall -TERM ofd_access_log_reader
18571         wait
18572         rc=$?
18573         if ((rc != 0)); then
18574                 error "ofd_access_log_reader exited with rc = '${rc}'"
18575         fi
18576 }
18577 run_test 165e "ofd_access_log MDT index filter works"
18578
18579 test_165f() {
18580         local trace="/tmp/${tfile}.trace"
18581         local rc
18582         local count
18583
18584         setup_165
18585         do_facet ost1 timeout 60 ofd_access_log_reader \
18586                 --exit-on-close --debug=- --trace=- > "${trace}" &
18587         sleep 5
18588         stop ost1
18589
18590         wait
18591         rc=$?
18592
18593         if ((rc != 0)); then
18594                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18595                 cat "${trace}"
18596                 exit 1
18597         fi
18598 }
18599 run_test 165f "ofd_access_log_reader --exit-on-close works"
18600
18601 test_169() {
18602         # do directio so as not to populate the page cache
18603         log "creating a 10 Mb file"
18604         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18605                 error "multiop failed while creating a file"
18606         log "starting reads"
18607         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18608         log "truncating the file"
18609         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18610                 error "multiop failed while truncating the file"
18611         log "killing dd"
18612         kill %+ || true # reads might have finished
18613         echo "wait until dd is finished"
18614         wait
18615         log "removing the temporary file"
18616         rm -rf $DIR/$tfile || error "tmp file removal failed"
18617 }
18618 run_test 169 "parallel read and truncate should not deadlock"
18619
18620 test_170() {
18621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18622
18623         $LCTL clear     # bug 18514
18624         $LCTL debug_daemon start $TMP/${tfile}_log_good
18625         touch $DIR/$tfile
18626         $LCTL debug_daemon stop
18627         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18628                 error "sed failed to read log_good"
18629
18630         $LCTL debug_daemon start $TMP/${tfile}_log_good
18631         rm -rf $DIR/$tfile
18632         $LCTL debug_daemon stop
18633
18634         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18635                error "lctl df log_bad failed"
18636
18637         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18638         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18639
18640         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18641         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18642
18643         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18644                 error "bad_line good_line1 good_line2 are empty"
18645
18646         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18647         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18648         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18649
18650         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18651         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18652         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18653
18654         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18655                 error "bad_line_new good_line_new are empty"
18656
18657         local expected_good=$((good_line1 + good_line2*2))
18658
18659         rm -f $TMP/${tfile}*
18660         # LU-231, short malformed line may not be counted into bad lines
18661         if [ $bad_line -ne $bad_line_new ] &&
18662                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18663                 error "expected $bad_line bad lines, but got $bad_line_new"
18664                 return 1
18665         fi
18666
18667         if [ $expected_good -ne $good_line_new ]; then
18668                 error "expected $expected_good good lines, but got $good_line_new"
18669                 return 2
18670         fi
18671         true
18672 }
18673 run_test 170 "test lctl df to handle corrupted log ====================="
18674
18675 test_171() { # bug20592
18676         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18677
18678         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18679         $LCTL set_param fail_loc=0x50e
18680         $LCTL set_param fail_val=3000
18681         multiop_bg_pause $DIR/$tfile O_s || true
18682         local MULTIPID=$!
18683         kill -USR1 $MULTIPID
18684         # cause log dump
18685         sleep 3
18686         wait $MULTIPID
18687         if dmesg | grep "recursive fault"; then
18688                 error "caught a recursive fault"
18689         fi
18690         $LCTL set_param fail_loc=0
18691         true
18692 }
18693 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18694
18695 test_172() {
18696
18697         #define OBD_FAIL_OBD_CLEANUP  0x60e
18698         $LCTL set_param fail_loc=0x60e
18699         umount $MOUNT || error "umount $MOUNT failed"
18700         stack_trap "mount_client $MOUNT"
18701
18702         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18703                 error "no client OBDs are remained"
18704
18705         $LCTL dl | while read devno state type name foo; do
18706                 case $type in
18707                 lov|osc|lmv|mdc)
18708                         $LCTL --device $name cleanup
18709                         $LCTL --device $name detach
18710                         ;;
18711                 *)
18712                         # skip server devices
18713                         ;;
18714                 esac
18715         done
18716
18717         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18718                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18719                 error "some client OBDs are still remained"
18720         fi
18721
18722 }
18723 run_test 172 "manual device removal with lctl cleanup/detach ======"
18724
18725 # it would be good to share it with obdfilter-survey/iokit-libecho code
18726 setup_obdecho_osc () {
18727         local rc=0
18728         local ost_nid=$1
18729         local obdfilter_name=$2
18730         echo "Creating new osc for $obdfilter_name on $ost_nid"
18731         # make sure we can find loopback nid
18732         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18733
18734         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18735                            ${obdfilter_name}_osc_UUID || rc=2; }
18736         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18737                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18738         return $rc
18739 }
18740
18741 cleanup_obdecho_osc () {
18742         local obdfilter_name=$1
18743         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18744         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18745         return 0
18746 }
18747
18748 obdecho_test() {
18749         local OBD=$1
18750         local node=$2
18751         local pages=${3:-64}
18752         local rc=0
18753         local id
18754
18755         local count=10
18756         local obd_size=$(get_obd_size $node $OBD)
18757         local page_size=$(get_page_size $node)
18758         if [[ -n "$obd_size" ]]; then
18759                 local new_count=$((obd_size / (pages * page_size / 1024)))
18760                 [[ $new_count -ge $count ]] || count=$new_count
18761         fi
18762
18763         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18764         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18765                            rc=2; }
18766         if [ $rc -eq 0 ]; then
18767             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18768             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18769         fi
18770         echo "New object id is $id"
18771         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18772                            rc=4; }
18773         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18774                            "test_brw $count w v $pages $id" || rc=4; }
18775         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18776                            rc=4; }
18777         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18778                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18779         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18780                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18781         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18782         return $rc
18783 }
18784
18785 test_180a() {
18786         skip "obdecho on osc is no longer supported"
18787 }
18788 run_test 180a "test obdecho on osc"
18789
18790 test_180b() {
18791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18792         remote_ost_nodsh && skip "remote OST with nodsh"
18793
18794         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18795                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18796                 error "failed to load module obdecho"
18797
18798         local target=$(do_facet ost1 $LCTL dl |
18799                        awk '/obdfilter/ { print $4; exit; }')
18800
18801         if [ -n "$target" ]; then
18802                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18803         else
18804                 do_facet ost1 $LCTL dl
18805                 error "there is no obdfilter target on ost1"
18806         fi
18807 }
18808 run_test 180b "test obdecho directly on obdfilter"
18809
18810 test_180c() { # LU-2598
18811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18812         remote_ost_nodsh && skip "remote OST with nodsh"
18813         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18814                 skip "Need MDS version at least 2.4.0"
18815
18816         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18817                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18818                 error "failed to load module obdecho"
18819
18820         local target=$(do_facet ost1 $LCTL dl |
18821                        awk '/obdfilter/ { print $4; exit; }')
18822
18823         if [ -n "$target" ]; then
18824                 local pages=16384 # 64MB bulk I/O RPC size
18825
18826                 obdecho_test "$target" ost1 "$pages" ||
18827                         error "obdecho_test with pages=$pages failed with $?"
18828         else
18829                 do_facet ost1 $LCTL dl
18830                 error "there is no obdfilter target on ost1"
18831         fi
18832 }
18833 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18834
18835 test_181() { # bug 22177
18836         test_mkdir $DIR/$tdir
18837         # create enough files to index the directory
18838         createmany -o $DIR/$tdir/foobar 4000
18839         # print attributes for debug purpose
18840         lsattr -d .
18841         # open dir
18842         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18843         MULTIPID=$!
18844         # remove the files & current working dir
18845         unlinkmany $DIR/$tdir/foobar 4000
18846         rmdir $DIR/$tdir
18847         kill -USR1 $MULTIPID
18848         wait $MULTIPID
18849         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18850         return 0
18851 }
18852 run_test 181 "Test open-unlinked dir ========================"
18853
18854 test_182a() {
18855         local fcount=1000
18856         local tcount=10
18857
18858         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18859
18860         $LCTL set_param mdc.*.rpc_stats=clear
18861
18862         for (( i = 0; i < $tcount; i++ )) ; do
18863                 mkdir $DIR/$tdir/$i
18864         done
18865
18866         for (( i = 0; i < $tcount; i++ )) ; do
18867                 createmany -o $DIR/$tdir/$i/f- $fcount &
18868         done
18869         wait
18870
18871         for (( i = 0; i < $tcount; i++ )) ; do
18872                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18873         done
18874         wait
18875
18876         $LCTL get_param mdc.*.rpc_stats
18877
18878         rm -rf $DIR/$tdir
18879 }
18880 run_test 182a "Test parallel modify metadata operations from mdc"
18881
18882 test_182b() {
18883         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18884         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18885         local dcount=1000
18886         local tcount=10
18887         local stime
18888         local etime
18889         local delta
18890
18891         do_facet mds1 $LCTL list_param \
18892                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18893                 skip "MDS lacks parallel RPC handling"
18894
18895         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18896
18897         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18898                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18899
18900         stime=$(date +%s)
18901         createmany -i 0 -d $DIR/$tdir/t- $tcount
18902
18903         for (( i = 0; i < $tcount; i++ )) ; do
18904                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18905         done
18906         wait
18907         etime=$(date +%s)
18908         delta=$((etime - stime))
18909         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18910
18911         stime=$(date +%s)
18912         for (( i = 0; i < $tcount; i++ )) ; do
18913                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18914         done
18915         wait
18916         etime=$(date +%s)
18917         delta=$((etime - stime))
18918         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18919
18920         rm -rf $DIR/$tdir
18921
18922         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18923
18924         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18925
18926         stime=$(date +%s)
18927         createmany -i 0 -d $DIR/$tdir/t- $tcount
18928
18929         for (( i = 0; i < $tcount; i++ )) ; do
18930                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18931         done
18932         wait
18933         etime=$(date +%s)
18934         delta=$((etime - stime))
18935         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18936
18937         stime=$(date +%s)
18938         for (( i = 0; i < $tcount; i++ )) ; do
18939                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18940         done
18941         wait
18942         etime=$(date +%s)
18943         delta=$((etime - stime))
18944         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18945
18946         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18947 }
18948 run_test 182b "Test parallel modify metadata operations from osp"
18949
18950 test_183() { # LU-2275
18951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18952         remote_mds_nodsh && skip "remote MDS with nodsh"
18953         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18954                 skip "Need MDS version at least 2.3.56"
18955
18956         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18957         echo aaa > $DIR/$tdir/$tfile
18958
18959 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18960         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18961
18962         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18963         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18964
18965         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18966
18967         # Flush negative dentry cache
18968         touch $DIR/$tdir/$tfile
18969
18970         # We are not checking for any leaked references here, they'll
18971         # become evident next time we do cleanup with module unload.
18972         rm -rf $DIR/$tdir
18973 }
18974 run_test 183 "No crash or request leak in case of strange dispositions ========"
18975
18976 # test suite 184 is for LU-2016, LU-2017
18977 test_184a() {
18978         check_swap_layouts_support
18979
18980         dir0=$DIR/$tdir/$testnum
18981         test_mkdir -p -c1 $dir0
18982         ref1=/etc/passwd
18983         ref2=/etc/group
18984         file1=$dir0/f1
18985         file2=$dir0/f2
18986         $LFS setstripe -c1 $file1
18987         cp $ref1 $file1
18988         $LFS setstripe -c2 $file2
18989         cp $ref2 $file2
18990         gen1=$($LFS getstripe -g $file1)
18991         gen2=$($LFS getstripe -g $file2)
18992
18993         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18994         gen=$($LFS getstripe -g $file1)
18995         [[ $gen1 != $gen ]] ||
18996                 error "Layout generation on $file1 does not change"
18997         gen=$($LFS getstripe -g $file2)
18998         [[ $gen2 != $gen ]] ||
18999                 error "Layout generation on $file2 does not change"
19000
19001         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
19002         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
19003
19004         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
19005 }
19006 run_test 184a "Basic layout swap"
19007
19008 test_184b() {
19009         check_swap_layouts_support
19010
19011         dir0=$DIR/$tdir/$testnum
19012         mkdir -p $dir0 || error "creating dir $dir0"
19013         file1=$dir0/f1
19014         file2=$dir0/f2
19015         file3=$dir0/f3
19016         dir1=$dir0/d1
19017         dir2=$dir0/d2
19018         mkdir $dir1 $dir2
19019         $LFS setstripe -c1 $file1
19020         $LFS setstripe -c2 $file2
19021         $LFS setstripe -c1 $file3
19022         chown $RUNAS_ID $file3
19023         gen1=$($LFS getstripe -g $file1)
19024         gen2=$($LFS getstripe -g $file2)
19025
19026         $LFS swap_layouts $dir1 $dir2 &&
19027                 error "swap of directories layouts should fail"
19028         $LFS swap_layouts $dir1 $file1 &&
19029                 error "swap of directory and file layouts should fail"
19030         $RUNAS $LFS swap_layouts $file1 $file2 &&
19031                 error "swap of file we cannot write should fail"
19032         $LFS swap_layouts $file1 $file3 &&
19033                 error "swap of file with different owner should fail"
19034         /bin/true # to clear error code
19035 }
19036 run_test 184b "Forbidden layout swap (will generate errors)"
19037
19038 test_184c() {
19039         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
19040         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
19041         check_swap_layouts_support
19042         check_swap_layout_no_dom $DIR
19043
19044         local dir0=$DIR/$tdir/$testnum
19045         mkdir -p $dir0 || error "creating dir $dir0"
19046
19047         local ref1=$dir0/ref1
19048         local ref2=$dir0/ref2
19049         local file1=$dir0/file1
19050         local file2=$dir0/file2
19051         # create a file large enough for the concurrent test
19052         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
19053         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
19054         echo "ref file size: ref1($(stat -c %s $ref1))," \
19055              "ref2($(stat -c %s $ref2))"
19056
19057         cp $ref2 $file2
19058         dd if=$ref1 of=$file1 bs=16k &
19059         local DD_PID=$!
19060
19061         # Make sure dd starts to copy file, but wait at most 5 seconds
19062         local loops=0
19063         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
19064
19065         $LFS swap_layouts $file1 $file2
19066         local rc=$?
19067         wait $DD_PID
19068         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
19069         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
19070
19071         # how many bytes copied before swapping layout
19072         local copied=$(stat -c %s $file2)
19073         local remaining=$(stat -c %s $ref1)
19074         remaining=$((remaining - copied))
19075         echo "Copied $copied bytes before swapping layout..."
19076
19077         cmp -n $copied $file1 $ref2 | grep differ &&
19078                 error "Content mismatch [0, $copied) of ref2 and file1"
19079         cmp -n $copied $file2 $ref1 ||
19080                 error "Content mismatch [0, $copied) of ref1 and file2"
19081         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
19082                 error "Content mismatch [$copied, EOF) of ref1 and file1"
19083
19084         # clean up
19085         rm -f $ref1 $ref2 $file1 $file2
19086 }
19087 run_test 184c "Concurrent write and layout swap"
19088
19089 test_184d() {
19090         check_swap_layouts_support
19091         check_swap_layout_no_dom $DIR
19092         [ -z "$(which getfattr 2>/dev/null)" ] &&
19093                 skip_env "no getfattr command"
19094
19095         local file1=$DIR/$tdir/$tfile-1
19096         local file2=$DIR/$tdir/$tfile-2
19097         local file3=$DIR/$tdir/$tfile-3
19098         local lovea1
19099         local lovea2
19100
19101         mkdir -p $DIR/$tdir
19102         touch $file1 || error "create $file1 failed"
19103         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19104                 error "create $file2 failed"
19105         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19106                 error "create $file3 failed"
19107         lovea1=$(get_layout_param $file1)
19108
19109         $LFS swap_layouts $file2 $file3 ||
19110                 error "swap $file2 $file3 layouts failed"
19111         $LFS swap_layouts $file1 $file2 ||
19112                 error "swap $file1 $file2 layouts failed"
19113
19114         lovea2=$(get_layout_param $file2)
19115         echo "$lovea1"
19116         echo "$lovea2"
19117         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
19118
19119         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19120         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
19121 }
19122 run_test 184d "allow stripeless layouts swap"
19123
19124 test_184e() {
19125         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19126                 skip "Need MDS version at least 2.6.94"
19127         check_swap_layouts_support
19128         check_swap_layout_no_dom $DIR
19129         [ -z "$(which getfattr 2>/dev/null)" ] &&
19130                 skip_env "no getfattr command"
19131
19132         local file1=$DIR/$tdir/$tfile-1
19133         local file2=$DIR/$tdir/$tfile-2
19134         local file3=$DIR/$tdir/$tfile-3
19135         local lovea
19136
19137         mkdir -p $DIR/$tdir
19138         touch $file1 || error "create $file1 failed"
19139         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19140                 error "create $file2 failed"
19141         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19142                 error "create $file3 failed"
19143
19144         $LFS swap_layouts $file1 $file2 ||
19145                 error "swap $file1 $file2 layouts failed"
19146
19147         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19148         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19149
19150         echo 123 > $file1 || error "Should be able to write into $file1"
19151
19152         $LFS swap_layouts $file1 $file3 ||
19153                 error "swap $file1 $file3 layouts failed"
19154
19155         echo 123 > $file1 || error "Should be able to write into $file1"
19156
19157         rm -rf $file1 $file2 $file3
19158 }
19159 run_test 184e "Recreate layout after stripeless layout swaps"
19160
19161 test_184f() {
19162         # Create a file with name longer than sizeof(struct stat) ==
19163         # 144 to see if we can get chars from the file name to appear
19164         # in the returned striping. Note that 'f' == 0x66.
19165         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19166
19167         mkdir -p $DIR/$tdir
19168         mcreate $DIR/$tdir/$file
19169         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19170                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19171         fi
19172 }
19173 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19174
19175 test_185() { # LU-2441
19176         # LU-3553 - no volatile file support in old servers
19177         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19178                 skip "Need MDS version at least 2.3.60"
19179
19180         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19181         touch $DIR/$tdir/spoo
19182         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19183         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19184                 error "cannot create/write a volatile file"
19185         [ "$FILESET" == "" ] &&
19186         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19187                 error "FID is still valid after close"
19188
19189         multiop_bg_pause $DIR/$tdir vVw4096_c
19190         local multi_pid=$!
19191
19192         local OLD_IFS=$IFS
19193         IFS=":"
19194         local fidv=($fid)
19195         IFS=$OLD_IFS
19196         # assume that the next FID for this client is sequential, since stdout
19197         # is unfortunately eaten by multiop_bg_pause
19198         local n=$((${fidv[1]} + 1))
19199         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19200         if [ "$FILESET" == "" ]; then
19201                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19202                         error "FID is missing before close"
19203         fi
19204         kill -USR1 $multi_pid
19205         # 1 second delay, so if mtime change we will see it
19206         sleep 1
19207         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19208         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19209 }
19210 run_test 185 "Volatile file support"
19211
19212 function create_check_volatile() {
19213         local idx=$1
19214         local tgt
19215
19216         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19217         local PID=$!
19218         sleep 1
19219         local FID=$(cat /tmp/${tfile}.fid)
19220         [ "$FID" == "" ] && error "can't get FID for volatile"
19221         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19222         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19223         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19224         kill -USR1 $PID
19225         wait
19226         sleep 1
19227         cancel_lru_locks mdc # flush opencache
19228         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19229         return 0
19230 }
19231
19232 test_185a(){
19233         # LU-12516 - volatile creation via .lustre
19234         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19235                 skip "Need MDS version at least 2.3.55"
19236
19237         create_check_volatile 0
19238         [ $MDSCOUNT -lt 2 ] && return 0
19239
19240         # DNE case
19241         create_check_volatile 1
19242
19243         return 0
19244 }
19245 run_test 185a "Volatile file creation in .lustre/fid/"
19246
19247 test_187a() {
19248         remote_mds_nodsh && skip "remote MDS with nodsh"
19249         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19250                 skip "Need MDS version at least 2.3.0"
19251
19252         local dir0=$DIR/$tdir/$testnum
19253         mkdir -p $dir0 || error "creating dir $dir0"
19254
19255         local file=$dir0/file1
19256         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19257         local dv1=$($LFS data_version $file)
19258         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19259         local dv2=$($LFS data_version $file)
19260         [[ $dv1 != $dv2 ]] ||
19261                 error "data version did not change on write $dv1 == $dv2"
19262
19263         # clean up
19264         rm -f $file1
19265 }
19266 run_test 187a "Test data version change"
19267
19268 test_187b() {
19269         remote_mds_nodsh && skip "remote MDS with nodsh"
19270         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19271                 skip "Need MDS version at least 2.3.0"
19272
19273         local dir0=$DIR/$tdir/$testnum
19274         mkdir -p $dir0 || error "creating dir $dir0"
19275
19276         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19277         [[ ${DV[0]} != ${DV[1]} ]] ||
19278                 error "data version did not change on write"\
19279                       " ${DV[0]} == ${DV[1]}"
19280
19281         # clean up
19282         rm -f $file1
19283 }
19284 run_test 187b "Test data version change on volatile file"
19285
19286 test_200() {
19287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19288         remote_mgs_nodsh && skip "remote MGS with nodsh"
19289         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19290
19291         local POOL=${POOL:-cea1}
19292         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19293         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19294         # Pool OST targets
19295         local first_ost=0
19296         local last_ost=$(($OSTCOUNT - 1))
19297         local ost_step=2
19298         local ost_list=$(seq $first_ost $ost_step $last_ost)
19299         local ost_range="$first_ost $last_ost $ost_step"
19300         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19301         local file_dir=$POOL_ROOT/file_tst
19302         local subdir=$test_path/subdir
19303         local rc=0
19304
19305         while : ; do
19306                 # former test_200a test_200b
19307                 pool_add $POOL                          || { rc=$? ; break; }
19308                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19309                 # former test_200c test_200d
19310                 mkdir -p $test_path
19311                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19312                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19313                 mkdir -p $subdir
19314                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19315                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19316                                                         || { rc=$? ; break; }
19317                 # former test_200e test_200f
19318                 local files=$((OSTCOUNT*3))
19319                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19320                                                         || { rc=$? ; break; }
19321                 pool_create_files $POOL $file_dir $files "$ost_list" \
19322                                                         || { rc=$? ; break; }
19323                 # former test_200g test_200h
19324                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19325                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19326
19327                 # former test_201a test_201b test_201c
19328                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19329
19330                 local f=$test_path/$tfile
19331                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19332                 pool_remove $POOL $f                    || { rc=$? ; break; }
19333                 break
19334         done
19335
19336         destroy_test_pools
19337
19338         return $rc
19339 }
19340 run_test 200 "OST pools"
19341
19342 # usage: default_attr <count | size | offset>
19343 default_attr() {
19344         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19345 }
19346
19347 # usage: check_default_stripe_attr
19348 check_default_stripe_attr() {
19349         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19350         case $1 in
19351         --stripe-count|-c)
19352                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19353         --stripe-size|-S)
19354                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19355         --stripe-index|-i)
19356                 EXPECTED=-1;;
19357         *)
19358                 error "unknown getstripe attr '$1'"
19359         esac
19360
19361         [ $ACTUAL == $EXPECTED ] ||
19362                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19363 }
19364
19365 test_204a() {
19366         test_mkdir $DIR/$tdir
19367         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19368
19369         check_default_stripe_attr --stripe-count
19370         check_default_stripe_attr --stripe-size
19371         check_default_stripe_attr --stripe-index
19372 }
19373 run_test 204a "Print default stripe attributes"
19374
19375 test_204b() {
19376         test_mkdir $DIR/$tdir
19377         $LFS setstripe --stripe-count 1 $DIR/$tdir
19378
19379         check_default_stripe_attr --stripe-size
19380         check_default_stripe_attr --stripe-index
19381 }
19382 run_test 204b "Print default stripe size and offset"
19383
19384 test_204c() {
19385         test_mkdir $DIR/$tdir
19386         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19387
19388         check_default_stripe_attr --stripe-count
19389         check_default_stripe_attr --stripe-index
19390 }
19391 run_test 204c "Print default stripe count and offset"
19392
19393 test_204d() {
19394         test_mkdir $DIR/$tdir
19395         $LFS setstripe --stripe-index 0 $DIR/$tdir
19396
19397         check_default_stripe_attr --stripe-count
19398         check_default_stripe_attr --stripe-size
19399 }
19400 run_test 204d "Print default stripe count and size"
19401
19402 test_204e() {
19403         test_mkdir $DIR/$tdir
19404         $LFS setstripe -d $DIR/$tdir
19405
19406         check_default_stripe_attr --stripe-count --raw
19407         check_default_stripe_attr --stripe-size --raw
19408         check_default_stripe_attr --stripe-index --raw
19409 }
19410 run_test 204e "Print raw stripe attributes"
19411
19412 test_204f() {
19413         test_mkdir $DIR/$tdir
19414         $LFS setstripe --stripe-count 1 $DIR/$tdir
19415
19416         check_default_stripe_attr --stripe-size --raw
19417         check_default_stripe_attr --stripe-index --raw
19418 }
19419 run_test 204f "Print raw stripe size and offset"
19420
19421 test_204g() {
19422         test_mkdir $DIR/$tdir
19423         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19424
19425         check_default_stripe_attr --stripe-count --raw
19426         check_default_stripe_attr --stripe-index --raw
19427 }
19428 run_test 204g "Print raw stripe count and offset"
19429
19430 test_204h() {
19431         test_mkdir $DIR/$tdir
19432         $LFS setstripe --stripe-index 0 $DIR/$tdir
19433
19434         check_default_stripe_attr --stripe-count --raw
19435         check_default_stripe_attr --stripe-size --raw
19436 }
19437 run_test 204h "Print raw stripe count and size"
19438
19439 # Figure out which job scheduler is being used, if any,
19440 # or use a fake one
19441 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19442         JOBENV=SLURM_JOB_ID
19443 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19444         JOBENV=LSB_JOBID
19445 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19446         JOBENV=PBS_JOBID
19447 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19448         JOBENV=LOADL_STEP_ID
19449 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19450         JOBENV=JOB_ID
19451 else
19452         $LCTL list_param jobid_name > /dev/null 2>&1
19453         if [ $? -eq 0 ]; then
19454                 JOBENV=nodelocal
19455         else
19456                 JOBENV=FAKE_JOBID
19457         fi
19458 fi
19459 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19460
19461 verify_jobstats() {
19462         local cmd=($1)
19463         shift
19464         local facets="$@"
19465
19466 # we don't really need to clear the stats for this test to work, since each
19467 # command has a unique jobid, but it makes debugging easier if needed.
19468 #       for facet in $facets; do
19469 #               local dev=$(convert_facet2label $facet)
19470 #               # clear old jobstats
19471 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19472 #       done
19473
19474         # use a new JobID for each test, or we might see an old one
19475         [ "$JOBENV" = "FAKE_JOBID" ] &&
19476                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19477
19478         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19479
19480         [ "$JOBENV" = "nodelocal" ] && {
19481                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19482                 $LCTL set_param jobid_name=$FAKE_JOBID
19483                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19484         }
19485
19486         log "Test: ${cmd[*]}"
19487         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19488
19489         if [ $JOBENV = "FAKE_JOBID" ]; then
19490                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19491         else
19492                 ${cmd[*]}
19493         fi
19494
19495         # all files are created on OST0000
19496         for facet in $facets; do
19497                 local stats="*.$(convert_facet2label $facet).job_stats"
19498
19499                 # strip out libtool wrappers for in-tree executables
19500                 if (( $(do_facet $facet lctl get_param $stats |
19501                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19502                         do_facet $facet lctl get_param $stats
19503                         error "No jobstats for $JOBVAL found on $facet::$stats"
19504                 fi
19505         done
19506 }
19507
19508 jobstats_set() {
19509         local new_jobenv=$1
19510
19511         set_persistent_param_and_check client "jobid_var" \
19512                 "$FSNAME.sys.jobid_var" $new_jobenv
19513 }
19514
19515 test_205a() { # Job stats
19516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19517         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19518                 skip "Need MDS version with at least 2.7.1"
19519         remote_mgs_nodsh && skip "remote MGS with nodsh"
19520         remote_mds_nodsh && skip "remote MDS with nodsh"
19521         remote_ost_nodsh && skip "remote OST with nodsh"
19522         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19523                 skip "Server doesn't support jobstats"
19524         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19525
19526         local old_jobenv=$($LCTL get_param -n jobid_var)
19527         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19528         stack_trap "jobstats_set $old_jobenv" EXIT
19529
19530         changelog_register
19531
19532         local old_jobid_name=$($LCTL get_param jobid_name)
19533         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19534
19535         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19536                                 mdt.*.job_cleanup_interval | head -n 1)
19537         local new_interval=5
19538         do_facet $SINGLEMDS \
19539                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19540         stack_trap "do_facet $SINGLEMDS \
19541                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19542         local start=$SECONDS
19543
19544         local cmd
19545         # mkdir
19546         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19547         verify_jobstats "$cmd" "$SINGLEMDS"
19548         # rmdir
19549         cmd="rmdir $DIR/$tdir"
19550         verify_jobstats "$cmd" "$SINGLEMDS"
19551         # mkdir on secondary MDT
19552         if [ $MDSCOUNT -gt 1 ]; then
19553                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19554                 verify_jobstats "$cmd" "mds2"
19555         fi
19556         # mknod
19557         cmd="mknod $DIR/$tfile c 1 3"
19558         verify_jobstats "$cmd" "$SINGLEMDS"
19559         # unlink
19560         cmd="rm -f $DIR/$tfile"
19561         verify_jobstats "$cmd" "$SINGLEMDS"
19562         # create all files on OST0000 so verify_jobstats can find OST stats
19563         # open & close
19564         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19565         verify_jobstats "$cmd" "$SINGLEMDS"
19566         # setattr
19567         cmd="touch $DIR/$tfile"
19568         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19569         # write
19570         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19571         verify_jobstats "$cmd" "ost1"
19572         # read
19573         cancel_lru_locks osc
19574         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19575         verify_jobstats "$cmd" "ost1"
19576         # truncate
19577         cmd="$TRUNCATE $DIR/$tfile 0"
19578         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19579         # rename
19580         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19581         verify_jobstats "$cmd" "$SINGLEMDS"
19582         # jobstats expiry - sleep until old stats should be expired
19583         local left=$((new_interval + 5 - (SECONDS - start)))
19584         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19585                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19586                         "0" $left
19587         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19588         verify_jobstats "$cmd" "$SINGLEMDS"
19589         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19590             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19591
19592         # Ensure that jobid are present in changelog (if supported by MDS)
19593         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19594                 changelog_dump | tail -10
19595                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19596                 [ $jobids -eq 9 ] ||
19597                         error "Wrong changelog jobid count $jobids != 9"
19598
19599                 # LU-5862
19600                 JOBENV="disable"
19601                 jobstats_set $JOBENV
19602                 touch $DIR/$tfile
19603                 changelog_dump | grep $tfile
19604                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19605                 [ $jobids -eq 0 ] ||
19606                         error "Unexpected jobids when jobid_var=$JOBENV"
19607         fi
19608
19609         # test '%j' access to environment variable - if supported
19610         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19611                 JOBENV="JOBCOMPLEX"
19612                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19613
19614                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19615         fi
19616
19617         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19618                 JOBENV="JOBCOMPLEX"
19619                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19620
19621                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19622         fi
19623
19624         # test '%j' access to per-session jobid - if supported
19625         if lctl list_param jobid_this_session > /dev/null 2>&1
19626         then
19627                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19628                 lctl set_param jobid_this_session=$USER
19629
19630                 JOBENV="JOBCOMPLEX"
19631                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19632
19633                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19634         fi
19635 }
19636 run_test 205a "Verify job stats"
19637
19638 # LU-13117, LU-13597, LU-16599
19639 test_205b() {
19640         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19641                 skip "Need MDS version at least 2.13.54.91"
19642
19643         local job_stats="mdt.*.job_stats"
19644         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19645
19646         do_facet mds1 $LCTL set_param $job_stats=clear
19647
19648         # Setting jobid_var to USER might not be supported
19649         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19650         $LCTL set_param jobid_var=USER || true
19651         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19652         $LCTL set_param jobid_name="%j.%e.%u"
19653
19654         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19655         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19656                 { do_facet mds1 $LCTL get_param $job_stats;
19657                   error "Unexpected jobid found"; }
19658         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19659                 { do_facet mds1 $LCTL get_param $job_stats;
19660                   error "wrong job_stats format found"; }
19661
19662         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19663                 echo "MDS does not yet escape jobid" && return 0
19664
19665         mkdir_on_mdt0 $DIR/$tdir
19666         $LCTL set_param jobid_var=TEST205b
19667         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19668         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19669                       awk '/has\\x20sp/ {print $3}')
19670         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19671                   error "jobid not escaped"; }
19672
19673         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19674                 # need to run such a command on mds1:
19675                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19676                 #
19677                 # there might be multiple MDTs on single mds server, so need to
19678                 # specifiy MDT0000. Or the command will fail due to other MDTs
19679                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19680                         error "cannot clear escaped jobid in job_stats";
19681         else
19682                 echo "MDS does not support clearing escaped jobid"
19683         fi
19684 }
19685 run_test 205b "Verify job stats jobid and output format"
19686
19687 # LU-13733
19688 test_205c() {
19689         $LCTL set_param llite.*.stats=0
19690         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19691         $LCTL get_param llite.*.stats
19692         $LCTL get_param llite.*.stats | grep \
19693                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19694                         error "wrong client stats format found"
19695 }
19696 run_test 205c "Verify client stats format"
19697
19698 test_205d() {
19699         local file=$DIR/$tdir/$tfile
19700
19701         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19702                 skip "need lustre >= 2.15.53 for lljobstat"
19703         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19704                 skip "need lustre >= 2.15.53 for lljobstat"
19705         verify_yaml_available || skip_env "YAML verification not installed"
19706
19707         test_mkdir -i 0 $DIR/$tdir
19708         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19709
19710         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19711                 error "failed to write data to $file"
19712         mv $file $file.2
19713
19714         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19715         echo -n 'verify rename_stats...'
19716         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19717                 verify_yaml || error "rename_stats is not valid YAML"
19718         echo " OK"
19719
19720         echo -n 'verify mdt job_stats...'
19721         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19722                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19723         echo " OK"
19724
19725         echo -n 'verify ost job_stats...'
19726         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19727                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19728         echo " OK"
19729 }
19730 run_test 205d "verify the format of some stats files"
19731
19732 test_205e() {
19733         local ops_comma
19734         local file=$DIR/$tdir/$tfile
19735         local -a cli_params
19736
19737         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19738                 skip "need lustre >= 2.15.53 for lljobstat"
19739         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19740                 skip "need lustre >= 2.15.53 for lljobstat"
19741         verify_yaml_available || skip_env "YAML verification not installed"
19742
19743         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19744         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19745         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19746
19747         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19748
19749         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19750                 error "failed to create $file on ost1"
19751         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19752                 error "failed to write data to $file"
19753
19754         do_facet mds1 "$LCTL get_param *.*.job_stats"
19755         do_facet ost1 "$LCTL get_param *.*.job_stats"
19756
19757         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19758         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19759                 error "The output of lljobstat is not an valid YAML"
19760
19761         # verify that job dd.0 does exist and has some ops on ost1
19762         # typically this line is like:
19763         # - 205e.dd.0:            {ops: 20, ...}
19764         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19765                     awk '$2=="205e.dd.0:" {print $4}')
19766
19767         (( ${ops_comma%,} >= 10 )) ||
19768                 error "cannot find job 205e.dd.0 with ops >= 10"
19769 }
19770 run_test 205e "verify the output of lljobstat"
19771
19772 test_205f() {
19773         verify_yaml_available || skip_env "YAML verification not installed"
19774
19775         # check both qos_ost_weights and qos_mdt_weights
19776         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19777         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19778                 error "qos_ost_weights is not valid YAML"
19779 }
19780 run_test 205f "verify qos_ost_weights YAML format "
19781
19782 __test_205_jobstats_dump() {
19783         local -a pids
19784         local nbr_instance=$1
19785
19786         while true; do
19787                 if (( ${#pids[@]} >= nbr_instance )); then
19788                         wait ${pids[@]}
19789                         pids=()
19790                 fi
19791
19792                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19793                 pids+=( $! )
19794         done
19795 }
19796
19797 __test_205_cleanup() {
19798         kill $@
19799         # Clear all job entries
19800         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19801 }
19802
19803 test_205g() {
19804         local -a mds1_params
19805         local -a cli_params
19806         local pids
19807         local interval=5
19808
19809         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19810         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19811         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19812
19813         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19814         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19815         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19816
19817         # start jobs loop
19818         export TEST205G_ID=205g
19819         stack_trap "unset TEST205G_ID" EXIT
19820         while true; do
19821                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19822         done & pids="$! "
19823
19824         __test_205_jobstats_dump 4 & pids+="$! "
19825         stack_trap "__test_205_cleanup $pids" EXIT INT
19826
19827         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19828 }
19829 run_test 205g "stress test for job_stats procfile"
19830
19831 # LU-1480, LU-1773 and LU-1657
19832 test_206() {
19833         mkdir -p $DIR/$tdir
19834         $LFS setstripe -c -1 $DIR/$tdir
19835 #define OBD_FAIL_LOV_INIT 0x1403
19836         $LCTL set_param fail_loc=0xa0001403
19837         $LCTL set_param fail_val=1
19838         touch $DIR/$tdir/$tfile || true
19839 }
19840 run_test 206 "fail lov_init_raid0() doesn't lbug"
19841
19842 test_207a() {
19843         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19844         local fsz=`stat -c %s $DIR/$tfile`
19845         cancel_lru_locks mdc
19846
19847         # do not return layout in getattr intent
19848 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19849         $LCTL set_param fail_loc=0x170
19850         local sz=`stat -c %s $DIR/$tfile`
19851
19852         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19853
19854         rm -rf $DIR/$tfile
19855 }
19856 run_test 207a "can refresh layout at glimpse"
19857
19858 test_207b() {
19859         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19860         local cksum=`md5sum $DIR/$tfile`
19861         local fsz=`stat -c %s $DIR/$tfile`
19862         cancel_lru_locks mdc
19863         cancel_lru_locks osc
19864
19865         # do not return layout in getattr intent
19866 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19867         $LCTL set_param fail_loc=0x171
19868
19869         # it will refresh layout after the file is opened but before read issues
19870         echo checksum is "$cksum"
19871         echo "$cksum" |md5sum -c --quiet || error "file differs"
19872
19873         rm -rf $DIR/$tfile
19874 }
19875 run_test 207b "can refresh layout at open"
19876
19877 test_208() {
19878         # FIXME: in this test suite, only RD lease is used. This is okay
19879         # for now as only exclusive open is supported. After generic lease
19880         # is done, this test suite should be revised. - Jinshan
19881
19882         remote_mds_nodsh && skip "remote MDS with nodsh"
19883         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19884                 skip "Need MDS version at least 2.4.52"
19885
19886         echo "==== test 1: verify get lease work"
19887         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19888
19889         echo "==== test 2: verify lease can be broken by upcoming open"
19890         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19891         local PID=$!
19892         sleep 2
19893
19894         $MULTIOP $DIR/$tfile oO_RDWR:c
19895         kill -USR1 $PID && wait $PID || error "break lease error"
19896
19897         echo "==== test 3: verify lease can't be granted if an open already exists"
19898         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19899         local PID=$!
19900         sleep 2
19901
19902         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19903         kill -USR1 $PID && wait $PID || error "open file error"
19904
19905         echo "==== test 4: lease can sustain over recovery"
19906         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19907         PID=$!
19908         sleep 2
19909
19910         fail mds1
19911
19912         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19913
19914         echo "==== test 5: lease broken can't be regained by replay"
19915         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19916         PID=$!
19917         sleep 2
19918
19919         # open file to break lease and then recovery
19920         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19921         fail mds1
19922
19923         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19924
19925         rm -f $DIR/$tfile
19926 }
19927 run_test 208 "Exclusive open"
19928
19929 test_209() {
19930         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19931                 skip_env "must have disp_stripe"
19932
19933         touch $DIR/$tfile
19934         sync; sleep 5; sync;
19935
19936         echo 3 > /proc/sys/vm/drop_caches
19937         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19938                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19939         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19940
19941         # open/close 500 times
19942         for i in $(seq 500); do
19943                 cat $DIR/$tfile
19944         done
19945
19946         echo 3 > /proc/sys/vm/drop_caches
19947         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19948                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19949         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19950
19951         echo "before: $req_before, after: $req_after"
19952         [ $((req_after - req_before)) -ge 300 ] &&
19953                 error "open/close requests are not freed"
19954         return 0
19955 }
19956 run_test 209 "read-only open/close requests should be freed promptly"
19957
19958 test_210() {
19959         local pid
19960
19961         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19962         pid=$!
19963         sleep 1
19964
19965         $LFS getstripe $DIR/$tfile
19966         kill -USR1 $pid
19967         wait $pid || error "multiop failed"
19968
19969         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19970         pid=$!
19971         sleep 1
19972
19973         $LFS getstripe $DIR/$tfile
19974         kill -USR1 $pid
19975         wait $pid || error "multiop failed"
19976 }
19977 run_test 210 "lfs getstripe does not break leases"
19978
19979 test_212() {
19980         size=`date +%s`
19981         size=$((size % 8192 + 1))
19982         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19983         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19984         rm -f $DIR/f212 $DIR/f212.xyz
19985 }
19986 run_test 212 "Sendfile test ============================================"
19987
19988 test_213() {
19989         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19990         cancel_lru_locks osc
19991         lctl set_param fail_loc=0x8000040f
19992         # generate a read lock
19993         cat $DIR/$tfile > /dev/null
19994         # write to the file, it will try to cancel the above read lock.
19995         cat /etc/hosts >> $DIR/$tfile
19996 }
19997 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19998
19999 test_214() { # for bug 20133
20000         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
20001         for (( i=0; i < 340; i++ )) ; do
20002                 touch $DIR/$tdir/d214c/a$i
20003         done
20004
20005         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
20006         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
20007         ls $DIR/d214c || error "ls $DIR/d214c failed"
20008         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
20009         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
20010 }
20011 run_test 214 "hash-indexed directory test - bug 20133"
20012
20013 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
20014 create_lnet_proc_files() {
20015         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
20016 }
20017
20018 # counterpart of create_lnet_proc_files
20019 remove_lnet_proc_files() {
20020         rm -f $TMP/lnet_$1.sys
20021 }
20022
20023 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20024 # 3rd arg as regexp for body
20025 check_lnet_proc_stats() {
20026         local l=$(cat "$TMP/lnet_$1" |wc -l)
20027         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
20028
20029         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
20030 }
20031
20032 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
20033 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
20034 # optional and can be regexp for 2nd line (lnet.routes case)
20035 check_lnet_proc_entry() {
20036         local blp=2          # blp stands for 'position of 1st line of body'
20037         [ -z "$5" ] || blp=3 # lnet.routes case
20038
20039         local l=$(cat "$TMP/lnet_$1" |wc -l)
20040         # subtracting one from $blp because the body can be empty
20041         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
20042
20043         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
20044                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
20045
20046         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
20047                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
20048
20049         # bail out if any unexpected line happened
20050         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
20051         [ "$?" != 0 ] || error "$2 misformatted"
20052 }
20053
20054 test_215() { # for bugs 18102, 21079, 21517
20055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20056
20057         local N='(0|[1-9][0-9]*)'       # non-negative numeric
20058         local P='[1-9][0-9]*'           # positive numeric
20059         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
20060         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
20061         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
20062         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
20063
20064         local L1 # regexp for 1st line
20065         local L2 # regexp for 2nd line (optional)
20066         local BR # regexp for the rest (body)
20067
20068         # lnet.stats should look as 11 space-separated non-negative numerics
20069         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
20070         create_lnet_proc_files "stats"
20071         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
20072         remove_lnet_proc_files "stats"
20073
20074         # lnet.routes should look like this:
20075         # Routing disabled/enabled
20076         # net hops priority state router
20077         # where net is a string like tcp0, hops > 0, priority >= 0,
20078         # state is up/down,
20079         # router is a string like 192.168.1.1@tcp2
20080         L1="^Routing (disabled|enabled)$"
20081         L2="^net +hops +priority +state +router$"
20082         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
20083         create_lnet_proc_files "routes"
20084         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
20085         remove_lnet_proc_files "routes"
20086
20087         # lnet.routers should look like this:
20088         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
20089         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
20090         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
20091         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
20092         L1="^ref +rtr_ref +alive +router$"
20093         BR="^$P +$P +(up|down) +$NID$"
20094         create_lnet_proc_files "routers"
20095         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
20096         remove_lnet_proc_files "routers"
20097
20098         # lnet.peers should look like this:
20099         # nid refs state last max rtr min tx min queue
20100         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
20101         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
20102         # numeric (0 or >0 or <0), queue >= 0.
20103         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
20104         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
20105         create_lnet_proc_files "peers"
20106         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
20107         remove_lnet_proc_files "peers"
20108
20109         # lnet.buffers  should look like this:
20110         # pages count credits min
20111         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
20112         L1="^pages +count +credits +min$"
20113         BR="^ +$N +$N +$I +$I$"
20114         create_lnet_proc_files "buffers"
20115         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
20116         remove_lnet_proc_files "buffers"
20117
20118         # lnet.nis should look like this:
20119         # nid status alive refs peer rtr max tx min
20120         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
20121         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20122         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20123         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20124         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20125         create_lnet_proc_files "nis"
20126         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20127         remove_lnet_proc_files "nis"
20128
20129         # can we successfully write to lnet.stats?
20130         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20131 }
20132 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20133
20134 test_216() { # bug 20317
20135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20136         remote_ost_nodsh && skip "remote OST with nodsh"
20137
20138         local node
20139         local facets=$(get_facets OST)
20140         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20141
20142         save_lustre_params client "osc.*.contention_seconds" > $p
20143         save_lustre_params $facets \
20144                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20145         save_lustre_params $facets \
20146                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20147         save_lustre_params $facets \
20148                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20149         clear_stats osc.*.osc_stats
20150
20151         # agressive lockless i/o settings
20152         do_nodes $(comma_list $(osts_nodes)) \
20153                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20154                         ldlm.namespaces.filter-*.contended_locks=0 \
20155                         ldlm.namespaces.filter-*.contention_seconds=60"
20156         lctl set_param -n osc.*.contention_seconds=60
20157
20158         $DIRECTIO write $DIR/$tfile 0 10 4096
20159         $CHECKSTAT -s 40960 $DIR/$tfile
20160
20161         # disable lockless i/o
20162         do_nodes $(comma_list $(osts_nodes)) \
20163                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20164                         ldlm.namespaces.filter-*.contended_locks=32 \
20165                         ldlm.namespaces.filter-*.contention_seconds=0"
20166         lctl set_param -n osc.*.contention_seconds=0
20167         clear_stats osc.*.osc_stats
20168
20169         dd if=/dev/zero of=$DIR/$tfile count=0
20170         $CHECKSTAT -s 0 $DIR/$tfile
20171
20172         restore_lustre_params <$p
20173         rm -f $p
20174         rm $DIR/$tfile
20175 }
20176 run_test 216 "check lockless direct write updates file size and kms correctly"
20177
20178 test_217() { # bug 22430
20179         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20180
20181         local node
20182
20183         for node in $(nodes_list); do
20184                 local nid=$(host_nids_address $node $NETTYPE)
20185                 local node_ip=$(do_node $node getent ahostsv4 $node |
20186                                 awk '{ print $1; exit; }')
20187
20188                 echo "node: '$node', nid: '$nid', node_ip='$node_ip'"
20189                 # if hostname matches any NID, use hostname for better testing
20190                 if [[ -z "$nid" || "$nid" =~ "$node_ip" ]]; then
20191                         echo "lctl ping node $node@$NETTYPE"
20192                         lctl ping $node@$NETTYPE
20193                 else # otherwise, at least test 'lctl ping' is working
20194                         echo "lctl ping nid $(h2nettype $nid)"
20195                         lctl ping $(h2nettype $nid)
20196                         echo "skipping $node (no hyphen detected)"
20197                 fi
20198         done
20199 }
20200 run_test 217 "check lctl ping for hostnames with embedded hyphen ('-')"
20201
20202 test_218() {
20203         # do directio so as not to populate the page cache
20204         log "creating a 10 Mb file"
20205         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
20206                 error "multiop failed while creating a file"
20207         log "starting reads"
20208         dd if=$DIR/$tfile of=/dev/null bs=4096 &
20209         log "truncating the file"
20210         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
20211                 error "multiop failed while truncating the file"
20212         log "killing dd"
20213         kill %+ || true # reads might have finished
20214         echo "wait until dd is finished"
20215         wait
20216         log "removing the temporary file"
20217         rm -rf $DIR/$tfile || error "tmp file removal failed"
20218 }
20219 run_test 218 "parallel read and truncate should not deadlock"
20220
20221 test_219() {
20222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20223
20224         # write one partial page
20225         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20226         # set no grant so vvp_io_commit_write will do sync write
20227         $LCTL set_param fail_loc=0x411
20228         # write a full page at the end of file
20229         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20230
20231         $LCTL set_param fail_loc=0
20232         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20233         $LCTL set_param fail_loc=0x411
20234         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20235
20236         # LU-4201
20237         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20238         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20239 }
20240 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20241
20242 test_220() { #LU-325
20243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20244         remote_ost_nodsh && skip "remote OST with nodsh"
20245         remote_mds_nodsh && skip "remote MDS with nodsh"
20246         remote_mgs_nodsh && skip "remote MGS with nodsh"
20247
20248         local OSTIDX=0
20249
20250         # create on MDT0000 so the last_id and next_id are correct
20251         mkdir_on_mdt0 $DIR/$tdir
20252         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20253         OST=${OST%_UUID}
20254
20255         # on the mdt's osc
20256         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20257         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20258                         osp.$mdtosc_proc1.prealloc_last_id)
20259         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20260                         osp.$mdtosc_proc1.prealloc_next_id)
20261
20262         $LFS df -i
20263
20264         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20265         #define OBD_FAIL_OST_ENOINO              0x229
20266         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20267         create_pool $FSNAME.$TESTNAME || return 1
20268         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20269
20270         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20271
20272         MDSOBJS=$((last_id - next_id))
20273         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20274
20275         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20276         echo "OST still has $count kbytes free"
20277
20278         echo "create $MDSOBJS files @next_id..."
20279         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20280
20281         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20282                         osp.$mdtosc_proc1.prealloc_last_id)
20283         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20284                         osp.$mdtosc_proc1.prealloc_next_id)
20285
20286         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20287         $LFS df -i
20288
20289         echo "cleanup..."
20290
20291         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20292         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20293
20294         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20295                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20296         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20297                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20298         echo "unlink $MDSOBJS files @$next_id..."
20299         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20300 }
20301 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20302
20303 test_221() {
20304         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20305
20306         dd if=`which date` of=$MOUNT/date oflag=sync
20307         chmod +x $MOUNT/date
20308
20309         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20310         $LCTL set_param fail_loc=0x80001401
20311
20312         $MOUNT/date > /dev/null
20313         rm -f $MOUNT/date
20314 }
20315 run_test 221 "make sure fault and truncate race to not cause OOM"
20316
20317 test_222a () {
20318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20319
20320         rm -rf $DIR/$tdir
20321         test_mkdir $DIR/$tdir
20322         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20323         createmany -o $DIR/$tdir/$tfile 10
20324         cancel_lru_locks mdc
20325         cancel_lru_locks osc
20326         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20327         $LCTL set_param fail_loc=0x31a
20328         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20329         $LCTL set_param fail_loc=0
20330         rm -r $DIR/$tdir
20331 }
20332 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20333
20334 test_222b () {
20335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20336
20337         rm -rf $DIR/$tdir
20338         test_mkdir $DIR/$tdir
20339         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20340         createmany -o $DIR/$tdir/$tfile 10
20341         cancel_lru_locks mdc
20342         cancel_lru_locks osc
20343         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20344         $LCTL set_param fail_loc=0x31a
20345         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20346         $LCTL set_param fail_loc=0
20347 }
20348 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20349
20350 test_223 () {
20351         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20352
20353         rm -rf $DIR/$tdir
20354         test_mkdir $DIR/$tdir
20355         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20356         createmany -o $DIR/$tdir/$tfile 10
20357         cancel_lru_locks mdc
20358         cancel_lru_locks osc
20359         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20360         $LCTL set_param fail_loc=0x31b
20361         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20362         $LCTL set_param fail_loc=0
20363         rm -r $DIR/$tdir
20364 }
20365 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20366
20367 test_224a() { # LU-1039, MRP-303
20368         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20369         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20370         $LCTL set_param fail_loc=0x508
20371         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20372         $LCTL set_param fail_loc=0
20373         df $DIR
20374 }
20375 run_test 224a "Don't panic on bulk IO failure"
20376
20377 test_224bd_sub() { # LU-1039, MRP-303
20378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20379         local timeout=$1
20380
20381         shift
20382         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20383
20384         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20385
20386         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20387         cancel_lru_locks osc
20388         set_checksums 0
20389         stack_trap "set_checksums $ORIG_CSUM" EXIT
20390         local at_max_saved=0
20391
20392         # adaptive timeouts may prevent seeing the issue
20393         if at_is_enabled; then
20394                 at_max_saved=$(at_max_get mds)
20395                 at_max_set 0 mds client
20396                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20397         fi
20398
20399         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20400         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20401         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20402
20403         do_facet ost1 $LCTL set_param fail_loc=0
20404         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20405         df $DIR
20406 }
20407
20408 test_224b() {
20409         test_224bd_sub 3 error "dd failed"
20410 }
20411 run_test 224b "Don't panic on bulk IO failure"
20412
20413 test_224c() { # LU-6441
20414         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20415         remote_mds_nodsh && skip "remote MDS with nodsh"
20416
20417         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20418         save_writethrough $p
20419         set_cache writethrough on
20420
20421         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20422         local at_max=$($LCTL get_param -n at_max)
20423         local timeout=$($LCTL get_param -n timeout)
20424         local test_at="at_max"
20425         local param_at="$FSNAME.sys.at_max"
20426         local test_timeout="timeout"
20427         local param_timeout="$FSNAME.sys.timeout"
20428
20429         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20430
20431         set_persistent_param_and_check client "$test_at" "$param_at" 0
20432         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20433
20434         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20435         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20436         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20437         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20438         sync
20439         do_facet ost1 "$LCTL set_param fail_loc=0"
20440
20441         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20442         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20443                 $timeout
20444
20445         $LCTL set_param -n $pages_per_rpc
20446         restore_lustre_params < $p
20447         rm -f $p
20448 }
20449 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20450
20451 test_224d() { # LU-11169
20452         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20453 }
20454 run_test 224d "Don't corrupt data on bulk IO timeout"
20455
20456 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20457 test_225a () {
20458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20459         if [ -z ${MDSSURVEY} ]; then
20460                 skip_env "mds-survey not found"
20461         fi
20462         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20463                 skip "Need MDS version at least 2.2.51"
20464
20465         local mds=$(facet_host $SINGLEMDS)
20466         local target=$(do_nodes $mds 'lctl dl' |
20467                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20468
20469         local cmd1="file_count=1000 thrhi=4"
20470         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20471         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20472         local cmd="$cmd1 $cmd2 $cmd3"
20473
20474         rm -f ${TMP}/mds_survey*
20475         echo + $cmd
20476         eval $cmd || error "mds-survey with zero-stripe failed"
20477         cat ${TMP}/mds_survey*
20478         rm -f ${TMP}/mds_survey*
20479 }
20480 run_test 225a "Metadata survey sanity with zero-stripe"
20481
20482 test_225b () {
20483         if [ -z ${MDSSURVEY} ]; then
20484                 skip_env "mds-survey not found"
20485         fi
20486         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20487                 skip "Need MDS version at least 2.2.51"
20488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20489         remote_mds_nodsh && skip "remote MDS with nodsh"
20490         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20491                 skip_env "Need to mount OST to test"
20492         fi
20493
20494         local mds=$(facet_host $SINGLEMDS)
20495         local target=$(do_nodes $mds 'lctl dl' |
20496                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20497
20498         local cmd1="file_count=1000 thrhi=4"
20499         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20500         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20501         local cmd="$cmd1 $cmd2 $cmd3"
20502
20503         rm -f ${TMP}/mds_survey*
20504         echo + $cmd
20505         eval $cmd || error "mds-survey with stripe_count failed"
20506         cat ${TMP}/mds_survey*
20507         rm -f ${TMP}/mds_survey*
20508 }
20509 run_test 225b "Metadata survey sanity with stripe_count = 1"
20510
20511 mcreate_path2fid () {
20512         local mode=$1
20513         local major=$2
20514         local minor=$3
20515         local name=$4
20516         local desc=$5
20517         local path=$DIR/$tdir/$name
20518         local fid
20519         local rc
20520         local fid_path
20521
20522         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20523                 error "cannot create $desc"
20524
20525         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20526         rc=$?
20527         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20528
20529         fid_path=$($LFS fid2path $MOUNT $fid)
20530         rc=$?
20531         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20532
20533         [ "$path" == "$fid_path" ] ||
20534                 error "fid2path returned $fid_path, expected $path"
20535
20536         echo "pass with $path and $fid"
20537 }
20538
20539 test_226a () {
20540         rm -rf $DIR/$tdir
20541         mkdir -p $DIR/$tdir
20542
20543         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20544         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20545         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20546         mcreate_path2fid 0040666 0 0 dir "directory"
20547         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20548         mcreate_path2fid 0100666 0 0 file "regular file"
20549         mcreate_path2fid 0120666 0 0 link "symbolic link"
20550         mcreate_path2fid 0140666 0 0 sock "socket"
20551 }
20552 run_test 226a "call path2fid and fid2path on files of all type"
20553
20554 test_226b () {
20555         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20556
20557         local MDTIDX=1
20558
20559         rm -rf $DIR/$tdir
20560         mkdir -p $DIR/$tdir
20561         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20562                 error "create remote directory failed"
20563         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20564         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20565                                 "character special file (null)"
20566         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20567                                 "character special file (no device)"
20568         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20569         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20570                                 "block special file (loop)"
20571         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20572         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20573         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20574 }
20575 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20576
20577 test_226c () {
20578         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20579         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20580                 skip "Need MDS version at least 2.13.55"
20581
20582         local submnt=/mnt/submnt
20583         local srcfile=/etc/passwd
20584         local dstfile=$submnt/passwd
20585         local path
20586         local fid
20587
20588         rm -rf $DIR/$tdir
20589         rm -rf $submnt
20590         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20591                 error "create remote directory failed"
20592         mkdir -p $submnt || error "create $submnt failed"
20593         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20594                 error "mount $submnt failed"
20595         stack_trap "umount $submnt" EXIT
20596
20597         cp $srcfile $dstfile
20598         fid=$($LFS path2fid $dstfile)
20599         path=$($LFS fid2path $submnt "$fid")
20600         [ "$path" = "$dstfile" ] ||
20601                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20602 }
20603 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20604
20605 # LU-1299 Executing or running ldd on a truncated executable does not
20606 # cause an out-of-memory condition.
20607 test_227() {
20608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20609         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20610
20611         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20612         chmod +x $MOUNT/date
20613
20614         $MOUNT/date > /dev/null
20615         ldd $MOUNT/date > /dev/null
20616         rm -f $MOUNT/date
20617 }
20618 run_test 227 "running truncated executable does not cause OOM"
20619
20620 # LU-1512 try to reuse idle OI blocks
20621 test_228a() {
20622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20623         remote_mds_nodsh && skip "remote MDS with nodsh"
20624         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20625
20626         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20627         local myDIR=$DIR/$tdir
20628
20629         mkdir -p $myDIR
20630         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20631         $LCTL set_param fail_loc=0x80001002
20632         createmany -o $myDIR/t- 10000
20633         $LCTL set_param fail_loc=0
20634         # The guard is current the largest FID holder
20635         touch $myDIR/guard
20636         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20637                     tr -d '[')
20638         local IDX=$(($SEQ % 64))
20639
20640         do_facet $SINGLEMDS sync
20641         # Make sure journal flushed.
20642         sleep 6
20643         local blk1=$(do_facet $SINGLEMDS \
20644                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20645                      grep Blockcount | awk '{print $4}')
20646
20647         # Remove old files, some OI blocks will become idle.
20648         unlinkmany $myDIR/t- 10000
20649         # Create new files, idle OI blocks should be reused.
20650         createmany -o $myDIR/t- 2000
20651         do_facet $SINGLEMDS sync
20652         # Make sure journal flushed.
20653         sleep 6
20654         local blk2=$(do_facet $SINGLEMDS \
20655                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20656                      grep Blockcount | awk '{print $4}')
20657
20658         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20659 }
20660 run_test 228a "try to reuse idle OI blocks"
20661
20662 test_228b() {
20663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20664         remote_mds_nodsh && skip "remote MDS with nodsh"
20665         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20666
20667         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20668         local myDIR=$DIR/$tdir
20669
20670         mkdir -p $myDIR
20671         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20672         $LCTL set_param fail_loc=0x80001002
20673         createmany -o $myDIR/t- 10000
20674         $LCTL set_param fail_loc=0
20675         # The guard is current the largest FID holder
20676         touch $myDIR/guard
20677         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20678                     tr -d '[')
20679         local IDX=$(($SEQ % 64))
20680
20681         do_facet $SINGLEMDS sync
20682         # Make sure journal flushed.
20683         sleep 6
20684         local blk1=$(do_facet $SINGLEMDS \
20685                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20686                      grep Blockcount | awk '{print $4}')
20687
20688         # Remove old files, some OI blocks will become idle.
20689         unlinkmany $myDIR/t- 10000
20690
20691         # stop the MDT
20692         stop $SINGLEMDS || error "Fail to stop MDT."
20693         # remount the MDT
20694         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20695                 error "Fail to start MDT."
20696
20697         client_up || error "Fail to df."
20698         # Create new files, idle OI blocks should be reused.
20699         createmany -o $myDIR/t- 2000
20700         do_facet $SINGLEMDS sync
20701         # Make sure journal flushed.
20702         sleep 6
20703         local blk2=$(do_facet $SINGLEMDS \
20704                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20705                      grep Blockcount | awk '{print $4}')
20706
20707         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20708 }
20709 run_test 228b "idle OI blocks can be reused after MDT restart"
20710
20711 #LU-1881
20712 test_228c() {
20713         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20714         remote_mds_nodsh && skip "remote MDS with nodsh"
20715         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20716
20717         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20718         local myDIR=$DIR/$tdir
20719
20720         mkdir -p $myDIR
20721         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20722         $LCTL set_param fail_loc=0x80001002
20723         # 20000 files can guarantee there are index nodes in the OI file
20724         createmany -o $myDIR/t- 20000
20725         $LCTL set_param fail_loc=0
20726         # The guard is current the largest FID holder
20727         touch $myDIR/guard
20728         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20729                     tr -d '[')
20730         local IDX=$(($SEQ % 64))
20731
20732         do_facet $SINGLEMDS sync
20733         # Make sure journal flushed.
20734         sleep 6
20735         local blk1=$(do_facet $SINGLEMDS \
20736                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20737                      grep Blockcount | awk '{print $4}')
20738
20739         # Remove old files, some OI blocks will become idle.
20740         unlinkmany $myDIR/t- 20000
20741         rm -f $myDIR/guard
20742         # The OI file should become empty now
20743
20744         # Create new files, idle OI blocks should be reused.
20745         createmany -o $myDIR/t- 2000
20746         do_facet $SINGLEMDS sync
20747         # Make sure journal flushed.
20748         sleep 6
20749         local blk2=$(do_facet $SINGLEMDS \
20750                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20751                      grep Blockcount | awk '{print $4}')
20752
20753         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20754 }
20755 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20756
20757 test_229() { # LU-2482, LU-3448
20758         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20759         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20760         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20761                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20762
20763         rm -f $DIR/$tfile
20764
20765         # Create a file with a released layout and stripe count 2.
20766         $MULTIOP $DIR/$tfile H2c ||
20767                 error "failed to create file with released layout"
20768
20769         $LFS getstripe -v $DIR/$tfile
20770
20771         local pattern=$($LFS getstripe -L $DIR/$tfile)
20772         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20773
20774         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20775                 error "getstripe"
20776         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20777         stat $DIR/$tfile || error "failed to stat released file"
20778
20779         chown $RUNAS_ID $DIR/$tfile ||
20780                 error "chown $RUNAS_ID $DIR/$tfile failed"
20781
20782         chgrp $RUNAS_ID $DIR/$tfile ||
20783                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20784
20785         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20786         rm $DIR/$tfile || error "failed to remove released file"
20787 }
20788 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20789
20790 test_230a() {
20791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20792         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20793         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20794                 skip "Need MDS version at least 2.11.52"
20795
20796         local MDTIDX=1
20797
20798         test_mkdir $DIR/$tdir
20799         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20800         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20801         [ $mdt_idx -ne 0 ] &&
20802                 error "create local directory on wrong MDT $mdt_idx"
20803
20804         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20805                         error "create remote directory failed"
20806         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20807         [ $mdt_idx -ne $MDTIDX ] &&
20808                 error "create remote directory on wrong MDT $mdt_idx"
20809
20810         createmany -o $DIR/$tdir/test_230/t- 10 ||
20811                 error "create files on remote directory failed"
20812         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20813         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20814         rm -r $DIR/$tdir || error "unlink remote directory failed"
20815 }
20816 run_test 230a "Create remote directory and files under the remote directory"
20817
20818 test_230b() {
20819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20820         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20821         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20822                 skip "Need MDS version at least 2.11.52"
20823
20824         local MDTIDX=1
20825         local mdt_index
20826         local i
20827         local file
20828         local pid
20829         local stripe_count
20830         local migrate_dir=$DIR/$tdir/migrate_dir
20831         local other_dir=$DIR/$tdir/other_dir
20832
20833         test_mkdir $DIR/$tdir
20834         test_mkdir -i0 -c1 $migrate_dir
20835         test_mkdir -i0 -c1 $other_dir
20836         for ((i=0; i<10; i++)); do
20837                 mkdir -p $migrate_dir/dir_${i}
20838                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20839                         error "create files under remote dir failed $i"
20840         done
20841
20842         cp /etc/passwd $migrate_dir/$tfile
20843         cp /etc/passwd $other_dir/$tfile
20844         chattr +SAD $migrate_dir
20845         chattr +SAD $migrate_dir/$tfile
20846
20847         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20848         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20849         local old_dir_mode=$(stat -c%f $migrate_dir)
20850         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20851
20852         mkdir -p $migrate_dir/dir_default_stripe2
20853         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20854         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20855
20856         mkdir -p $other_dir
20857         ln $migrate_dir/$tfile $other_dir/luna
20858         ln $migrate_dir/$tfile $migrate_dir/sofia
20859         ln $other_dir/$tfile $migrate_dir/david
20860         ln -s $migrate_dir/$tfile $other_dir/zachary
20861         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20862         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20863
20864         local len
20865         local lnktgt
20866
20867         # inline symlink
20868         for len in 58 59 60; do
20869                 lnktgt=$(str_repeat 'l' $len)
20870                 touch $migrate_dir/$lnktgt
20871                 ln -s $lnktgt $migrate_dir/${len}char_ln
20872         done
20873
20874         # PATH_MAX
20875         for len in 4094 4095; do
20876                 lnktgt=$(str_repeat 'l' $len)
20877                 ln -s $lnktgt $migrate_dir/${len}char_ln
20878         done
20879
20880         # NAME_MAX
20881         for len in 254 255; do
20882                 touch $migrate_dir/$(str_repeat 'l' $len)
20883         done
20884
20885         $LFS migrate -m $MDTIDX $migrate_dir ||
20886                 error "fails on migrating remote dir to MDT1"
20887
20888         echo "migratate to MDT1, then checking.."
20889         for ((i = 0; i < 10; i++)); do
20890                 for file in $(find $migrate_dir/dir_${i}); do
20891                         mdt_index=$($LFS getstripe -m $file)
20892                         # broken symlink getstripe will fail
20893                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20894                                 error "$file is not on MDT${MDTIDX}"
20895                 done
20896         done
20897
20898         # the multiple link file should still in MDT0
20899         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20900         [ $mdt_index == 0 ] ||
20901                 error "$file is not on MDT${MDTIDX}"
20902
20903         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20904         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20905                 error " expect $old_dir_flag get $new_dir_flag"
20906
20907         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20908         [ "$old_file_flag" = "$new_file_flag" ] ||
20909                 error " expect $old_file_flag get $new_file_flag"
20910
20911         local new_dir_mode=$(stat -c%f $migrate_dir)
20912         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20913                 error "expect mode $old_dir_mode get $new_dir_mode"
20914
20915         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20916         [ "$old_file_mode" = "$new_file_mode" ] ||
20917                 error "expect mode $old_file_mode get $new_file_mode"
20918
20919         diff /etc/passwd $migrate_dir/$tfile ||
20920                 error "$tfile different after migration"
20921
20922         diff /etc/passwd $other_dir/luna ||
20923                 error "luna different after migration"
20924
20925         diff /etc/passwd $migrate_dir/sofia ||
20926                 error "sofia different after migration"
20927
20928         diff /etc/passwd $migrate_dir/david ||
20929                 error "david different after migration"
20930
20931         diff /etc/passwd $other_dir/zachary ||
20932                 error "zachary different after migration"
20933
20934         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20935                 error "${tfile}_ln different after migration"
20936
20937         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20938                 error "${tfile}_ln_other different after migration"
20939
20940         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20941         [ $stripe_count = 2 ] ||
20942                 error "dir strpe_count $d != 2 after migration."
20943
20944         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20945         [ $stripe_count = 2 ] ||
20946                 error "file strpe_count $d != 2 after migration."
20947
20948         #migrate back to MDT0
20949         MDTIDX=0
20950
20951         $LFS migrate -m $MDTIDX $migrate_dir ||
20952                 error "fails on migrating remote dir to MDT0"
20953
20954         echo "migrate back to MDT0, checking.."
20955         for file in $(find $migrate_dir); do
20956                 mdt_index=$($LFS getstripe -m $file)
20957                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20958                         error "$file is not on MDT${MDTIDX}"
20959         done
20960
20961         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20962         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20963                 error " expect $old_dir_flag get $new_dir_flag"
20964
20965         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20966         [ "$old_file_flag" = "$new_file_flag" ] ||
20967                 error " expect $old_file_flag get $new_file_flag"
20968
20969         local new_dir_mode=$(stat -c%f $migrate_dir)
20970         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20971                 error "expect mode $old_dir_mode get $new_dir_mode"
20972
20973         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20974         [ "$old_file_mode" = "$new_file_mode" ] ||
20975                 error "expect mode $old_file_mode get $new_file_mode"
20976
20977         diff /etc/passwd ${migrate_dir}/$tfile ||
20978                 error "$tfile different after migration"
20979
20980         diff /etc/passwd ${other_dir}/luna ||
20981                 error "luna different after migration"
20982
20983         diff /etc/passwd ${migrate_dir}/sofia ||
20984                 error "sofia different after migration"
20985
20986         diff /etc/passwd ${other_dir}/zachary ||
20987                 error "zachary different after migration"
20988
20989         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20990                 error "${tfile}_ln different after migration"
20991
20992         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20993                 error "${tfile}_ln_other different after migration"
20994
20995         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20996         [ $stripe_count = 2 ] ||
20997                 error "dir strpe_count $d != 2 after migration."
20998
20999         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
21000         [ $stripe_count = 2 ] ||
21001                 error "file strpe_count $d != 2 after migration."
21002
21003         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21004 }
21005 run_test 230b "migrate directory"
21006
21007 test_230c() {
21008         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21009         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21010         remote_mds_nodsh && skip "remote MDS with nodsh"
21011         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21012                 skip "Need MDS version at least 2.11.52"
21013
21014         local MDTIDX=1
21015         local total=3
21016         local mdt_index
21017         local file
21018         local migrate_dir=$DIR/$tdir/migrate_dir
21019
21020         #If migrating directory fails in the middle, all entries of
21021         #the directory is still accessiable.
21022         test_mkdir $DIR/$tdir
21023         test_mkdir -i0 -c1 $migrate_dir
21024         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
21025         stat $migrate_dir
21026         createmany -o $migrate_dir/f $total ||
21027                 error "create files under ${migrate_dir} failed"
21028
21029         # fail after migrating top dir, and this will fail only once, so the
21030         # first sub file migration will fail (currently f3), others succeed.
21031         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
21032         do_facet mds1 lctl set_param fail_loc=0x1801
21033         local t=$(ls $migrate_dir | wc -l)
21034         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
21035                 error "migrate should fail"
21036         local u=$(ls $migrate_dir | wc -l)
21037         [ "$u" == "$t" ] || error "$u != $t during migration"
21038
21039         # add new dir/file should succeed
21040         mkdir $migrate_dir/dir ||
21041                 error "mkdir failed under migrating directory"
21042         touch $migrate_dir/file ||
21043                 error "create file failed under migrating directory"
21044
21045         # add file with existing name should fail
21046         for file in $migrate_dir/f*; do
21047                 stat $file > /dev/null || error "stat $file failed"
21048                 $OPENFILE -f O_CREAT:O_EXCL $file &&
21049                         error "open(O_CREAT|O_EXCL) $file should fail"
21050                 $MULTIOP $file m && error "create $file should fail"
21051                 touch $DIR/$tdir/remote_dir/$tfile ||
21052                         error "touch $tfile failed"
21053                 ln $DIR/$tdir/remote_dir/$tfile $file &&
21054                         error "link $file should fail"
21055                 mdt_index=$($LFS getstripe -m $file)
21056                 if [ $mdt_index == 0 ]; then
21057                         # file failed to migrate is not allowed to rename to
21058                         mv $DIR/$tdir/remote_dir/$tfile $file &&
21059                                 error "rename to $file should fail"
21060                 else
21061                         mv $DIR/$tdir/remote_dir/$tfile $file ||
21062                                 error "rename to $file failed"
21063                 fi
21064                 echo hello >> $file || error "write $file failed"
21065         done
21066
21067         # resume migration with different options should fail
21068         $LFS migrate -m 0 $migrate_dir &&
21069                 error "migrate -m 0 $migrate_dir should fail"
21070
21071         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
21072                 error "migrate -c 2 $migrate_dir should fail"
21073
21074         # resume migration should succeed
21075         $LFS migrate -m $MDTIDX $migrate_dir ||
21076                 error "migrate $migrate_dir failed"
21077
21078         echo "Finish migration, then checking.."
21079         for file in $(find $migrate_dir); do
21080                 mdt_index=$($LFS getstripe -m $file)
21081                 [ $mdt_index == $MDTIDX ] ||
21082                         error "$file is not on MDT${MDTIDX}"
21083         done
21084
21085         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21086 }
21087 run_test 230c "check directory accessiblity if migration failed"
21088
21089 test_230d() {
21090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21091         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21092         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21093                 skip "Need MDS version at least 2.11.52"
21094         # LU-11235
21095         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
21096
21097         local migrate_dir=$DIR/$tdir/migrate_dir
21098         local old_index
21099         local new_index
21100         local old_count
21101         local new_count
21102         local new_hash
21103         local mdt_index
21104         local i
21105         local j
21106
21107         old_index=$((RANDOM % MDSCOUNT))
21108         old_count=$((MDSCOUNT - old_index))
21109         new_index=$((RANDOM % MDSCOUNT))
21110         new_count=$((MDSCOUNT - new_index))
21111         new_hash=1 # for all_char
21112
21113         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
21114         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
21115
21116         test_mkdir $DIR/$tdir
21117         test_mkdir -i $old_index -c $old_count $migrate_dir
21118
21119         for ((i=0; i<100; i++)); do
21120                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
21121                 createmany -o $migrate_dir/dir_${i}/f 100 ||
21122                         error "create files under remote dir failed $i"
21123         done
21124
21125         echo -n "Migrate from MDT$old_index "
21126         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
21127         echo -n "to MDT$new_index"
21128         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
21129         echo
21130
21131         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21132         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21133                 error "migrate remote dir error"
21134
21135         echo "Finish migration, then checking.."
21136         for file in $(find $migrate_dir -maxdepth 1); do
21137                 mdt_index=$($LFS getstripe -m $file)
21138                 if [ $mdt_index -lt $new_index ] ||
21139                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21140                         error "$file is on MDT$mdt_index"
21141                 fi
21142         done
21143
21144         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21145 }
21146 run_test 230d "check migrate big directory"
21147
21148 test_230e() {
21149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21151         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21152                 skip "Need MDS version at least 2.11.52"
21153
21154         local i
21155         local j
21156         local a_fid
21157         local b_fid
21158
21159         mkdir_on_mdt0 $DIR/$tdir
21160         mkdir $DIR/$tdir/migrate_dir
21161         mkdir $DIR/$tdir/other_dir
21162         touch $DIR/$tdir/migrate_dir/a
21163         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21164         ls $DIR/$tdir/other_dir
21165
21166         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21167                 error "migrate dir fails"
21168
21169         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21170         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21171
21172         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21173         [ $mdt_index == 0 ] || error "a is not on MDT0"
21174
21175         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21176                 error "migrate dir fails"
21177
21178         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21179         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21180
21181         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21182         [ $mdt_index == 1 ] || error "a is not on MDT1"
21183
21184         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21185         [ $mdt_index == 1 ] || error "b is not on MDT1"
21186
21187         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21188         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21189
21190         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21191
21192         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21193 }
21194 run_test 230e "migrate mulitple local link files"
21195
21196 test_230f() {
21197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21198         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21199         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21200                 skip "Need MDS version at least 2.11.52"
21201
21202         local a_fid
21203         local ln_fid
21204
21205         mkdir -p $DIR/$tdir
21206         mkdir $DIR/$tdir/migrate_dir
21207         $LFS mkdir -i1 $DIR/$tdir/other_dir
21208         touch $DIR/$tdir/migrate_dir/a
21209         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21210         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21211         ls $DIR/$tdir/other_dir
21212
21213         # a should be migrated to MDT1, since no other links on MDT0
21214         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21215                 error "#1 migrate dir fails"
21216         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21217         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21218         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21219         [ $mdt_index == 1 ] || error "a is not on MDT1"
21220
21221         # a should stay on MDT1, because it is a mulitple link file
21222         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21223                 error "#2 migrate dir fails"
21224         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21225         [ $mdt_index == 1 ] || error "a is not on MDT1"
21226
21227         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21228                 error "#3 migrate dir fails"
21229
21230         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21231         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21232         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21233
21234         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21235         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21236
21237         # a should be migrated to MDT0, since no other links on MDT1
21238         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21239                 error "#4 migrate dir fails"
21240         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21241         [ $mdt_index == 0 ] || error "a is not on MDT0"
21242
21243         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21244 }
21245 run_test 230f "migrate mulitple remote link files"
21246
21247 test_230g() {
21248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21249         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21250         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21251                 skip "Need MDS version at least 2.11.52"
21252
21253         mkdir -p $DIR/$tdir/migrate_dir
21254
21255         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21256                 error "migrating dir to non-exist MDT succeeds"
21257         true
21258 }
21259 run_test 230g "migrate dir to non-exist MDT"
21260
21261 test_230h() {
21262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21264         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21265                 skip "Need MDS version at least 2.11.52"
21266
21267         local mdt_index
21268
21269         mkdir -p $DIR/$tdir/migrate_dir
21270
21271         $LFS migrate -m1 $DIR &&
21272                 error "migrating mountpoint1 should fail"
21273
21274         $LFS migrate -m1 $DIR/$tdir/.. &&
21275                 error "migrating mountpoint2 should fail"
21276
21277         # same as mv
21278         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21279                 error "migrating $tdir/migrate_dir/.. should fail"
21280
21281         true
21282 }
21283 run_test 230h "migrate .. and root"
21284
21285 test_230i() {
21286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21287         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21288         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21289                 skip "Need MDS version at least 2.11.52"
21290
21291         mkdir -p $DIR/$tdir/migrate_dir
21292
21293         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21294                 error "migration fails with a tailing slash"
21295
21296         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21297                 error "migration fails with two tailing slashes"
21298 }
21299 run_test 230i "lfs migrate -m tolerates trailing slashes"
21300
21301 test_230j() {
21302         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21303         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21304                 skip "Need MDS version at least 2.11.52"
21305
21306         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21307         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21308                 error "create $tfile failed"
21309         cat /etc/passwd > $DIR/$tdir/$tfile
21310
21311         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21312
21313         cmp /etc/passwd $DIR/$tdir/$tfile ||
21314                 error "DoM file mismatch after migration"
21315 }
21316 run_test 230j "DoM file data not changed after dir migration"
21317
21318 test_230k() {
21319         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21320         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21321                 skip "Need MDS version at least 2.11.56"
21322
21323         local total=20
21324         local files_on_starting_mdt=0
21325
21326         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21327         $LFS getdirstripe $DIR/$tdir
21328         for i in $(seq $total); do
21329                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21330                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21331                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21332         done
21333
21334         echo "$files_on_starting_mdt files on MDT0"
21335
21336         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21337         $LFS getdirstripe $DIR/$tdir
21338
21339         files_on_starting_mdt=0
21340         for i in $(seq $total); do
21341                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21342                         error "file $tfile.$i mismatch after migration"
21343                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21344                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21345         done
21346
21347         echo "$files_on_starting_mdt files on MDT1 after migration"
21348         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21349
21350         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21351         $LFS getdirstripe $DIR/$tdir
21352
21353         files_on_starting_mdt=0
21354         for i in $(seq $total); do
21355                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21356                         error "file $tfile.$i mismatch after 2nd migration"
21357                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21358                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21359         done
21360
21361         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21362         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21363
21364         true
21365 }
21366 run_test 230k "file data not changed after dir migration"
21367
21368 test_230l() {
21369         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21370         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21371                 skip "Need MDS version at least 2.11.56"
21372
21373         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21374         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21375                 error "create files under remote dir failed $i"
21376         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21377 }
21378 run_test 230l "readdir between MDTs won't crash"
21379
21380 test_230m() {
21381         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21382         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21383                 skip "Need MDS version at least 2.11.56"
21384
21385         local MDTIDX=1
21386         local mig_dir=$DIR/$tdir/migrate_dir
21387         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21388         local shortstr="b"
21389         local val
21390
21391         echo "Creating files and dirs with xattrs"
21392         test_mkdir $DIR/$tdir
21393         test_mkdir -i0 -c1 $mig_dir
21394         mkdir $mig_dir/dir
21395         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21396                 error "cannot set xattr attr1 on dir"
21397         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21398                 error "cannot set xattr attr2 on dir"
21399         touch $mig_dir/dir/f0
21400         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21401                 error "cannot set xattr attr1 on file"
21402         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21403                 error "cannot set xattr attr2 on file"
21404         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21405         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21406         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21407         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21408         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21409         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21410         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21411         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21412         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21413
21414         echo "Migrating to MDT1"
21415         $LFS migrate -m $MDTIDX $mig_dir ||
21416                 error "fails on migrating dir to MDT1"
21417
21418         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21419         echo "Checking xattrs"
21420         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21421         [ "$val" = $longstr ] ||
21422                 error "expecting xattr1 $longstr on dir, found $val"
21423         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21424         [ "$val" = $shortstr ] ||
21425                 error "expecting xattr2 $shortstr on dir, found $val"
21426         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21427         [ "$val" = $longstr ] ||
21428                 error "expecting xattr1 $longstr on file, found $val"
21429         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21430         [ "$val" = $shortstr ] ||
21431                 error "expecting xattr2 $shortstr on file, found $val"
21432 }
21433 run_test 230m "xattrs not changed after dir migration"
21434
21435 test_230n() {
21436         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21437         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21438                 skip "Need MDS version at least 2.13.53"
21439
21440         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21441         cat /etc/hosts > $DIR/$tdir/$tfile
21442         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21443         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21444
21445         cmp /etc/hosts $DIR/$tdir/$tfile ||
21446                 error "File data mismatch after migration"
21447 }
21448 run_test 230n "Dir migration with mirrored file"
21449
21450 test_230o() {
21451         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21452         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21453                 skip "Need MDS version at least 2.13.52"
21454
21455         local mdts=$(comma_list $(mdts_nodes))
21456         local timeout=100
21457         local restripe_status
21458         local delta
21459         local i
21460
21461         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21462
21463         # in case "crush" hash type is not set
21464         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21465
21466         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21467                            mdt.*MDT0000.enable_dir_restripe)
21468         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21469         stack_trap "do_nodes $mdts $LCTL set_param \
21470                     mdt.*.enable_dir_restripe=$restripe_status"
21471
21472         mkdir $DIR/$tdir
21473         createmany -m $DIR/$tdir/f 100 ||
21474                 error "create files under remote dir failed $i"
21475         createmany -d $DIR/$tdir/d 100 ||
21476                 error "create dirs under remote dir failed $i"
21477
21478         for i in $(seq 2 $MDSCOUNT); do
21479                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21480                 $LFS setdirstripe -c $i $DIR/$tdir ||
21481                         error "split -c $i $tdir failed"
21482                 wait_update $HOSTNAME \
21483                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21484                         error "dir split not finished"
21485                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21486                         awk '/migrate/ {sum += $2} END { print sum }')
21487                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21488                 # delta is around total_files/stripe_count
21489                 (( $delta < 200 / (i - 1) + 4 )) ||
21490                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21491         done
21492 }
21493 run_test 230o "dir split"
21494
21495 test_230p() {
21496         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21497         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21498                 skip "Need MDS version at least 2.13.52"
21499
21500         local mdts=$(comma_list $(mdts_nodes))
21501         local timeout=100
21502         local restripe_status
21503         local delta
21504         local c
21505
21506         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21507
21508         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21509
21510         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21511                            mdt.*MDT0000.enable_dir_restripe)
21512         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21513         stack_trap "do_nodes $mdts $LCTL set_param \
21514                     mdt.*.enable_dir_restripe=$restripe_status"
21515
21516         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21517         createmany -m $DIR/$tdir/f 100 ||
21518                 error "create files under remote dir failed"
21519         createmany -d $DIR/$tdir/d 100 ||
21520                 error "create dirs under remote dir failed"
21521
21522         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21523                 local mdt_hash="crush"
21524
21525                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21526                 $LFS setdirstripe -c $c $DIR/$tdir ||
21527                         error "split -c $c $tdir failed"
21528                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21529                         mdt_hash="$mdt_hash,fixed"
21530                 elif [ $c -eq 1 ]; then
21531                         mdt_hash="none"
21532                 fi
21533                 wait_update $HOSTNAME \
21534                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21535                         error "dir merge not finished"
21536                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21537                         awk '/migrate/ {sum += $2} END { print sum }')
21538                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21539                 # delta is around total_files/stripe_count
21540                 (( delta < 200 / c + 4 )) ||
21541                         error "$delta files migrated >= $((200 / c + 4))"
21542         done
21543 }
21544 run_test 230p "dir merge"
21545
21546 test_230q() {
21547         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21548         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21549                 skip "Need MDS version at least 2.13.52"
21550
21551         local mdts=$(comma_list $(mdts_nodes))
21552         local saved_threshold=$(do_facet mds1 \
21553                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21554         local saved_delta=$(do_facet mds1 \
21555                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21556         local threshold=100
21557         local delta=2
21558         local total=0
21559         local stripe_count=0
21560         local stripe_index
21561         local nr_files
21562         local create
21563
21564         # test with fewer files on ZFS
21565         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21566
21567         stack_trap "do_nodes $mdts $LCTL set_param \
21568                     mdt.*.dir_split_count=$saved_threshold"
21569         stack_trap "do_nodes $mdts $LCTL set_param \
21570                     mdt.*.dir_split_delta=$saved_delta"
21571         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21572         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21573         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21574         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21575         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21576         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21577
21578         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21579         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21580
21581         create=$((threshold * 3 / 2))
21582         while [ $stripe_count -lt $MDSCOUNT ]; do
21583                 createmany -m $DIR/$tdir/f $total $create ||
21584                         error "create sub files failed"
21585                 stat $DIR/$tdir > /dev/null
21586                 total=$((total + create))
21587                 stripe_count=$((stripe_count + delta))
21588                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21589
21590                 wait_update $HOSTNAME \
21591                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21592                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21593
21594                 wait_update $HOSTNAME \
21595                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21596                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21597
21598                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21599                 echo "$nr_files/$total files on MDT$stripe_index after split"
21600                 # allow 10% margin of imbalance with crush hash
21601                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21602                         error "$nr_files files on MDT$stripe_index after split"
21603
21604                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21605                 [ $nr_files -eq $total ] ||
21606                         error "total sub files $nr_files != $total"
21607         done
21608
21609         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21610
21611         echo "fixed layout directory won't auto split"
21612         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21613         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21614                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21615         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21616                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21617 }
21618 run_test 230q "dir auto split"
21619
21620 test_230r() {
21621         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21622         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21623         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21624                 skip "Need MDS version at least 2.13.54"
21625
21626         # maximum amount of local locks:
21627         # parent striped dir - 2 locks
21628         # new stripe in parent to migrate to - 1 lock
21629         # source and target - 2 locks
21630         # Total 5 locks for regular file
21631         mkdir -p $DIR/$tdir
21632         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21633         touch $DIR/$tdir/dir1/eee
21634
21635         # create 4 hardlink for 4 more locks
21636         # Total: 9 locks > RS_MAX_LOCKS (8)
21637         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21638         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21639         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21640         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21641         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21642         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21643         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21644         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21645
21646         cancel_lru_locks mdc
21647
21648         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21649                 error "migrate dir fails"
21650
21651         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21652 }
21653 run_test 230r "migrate with too many local locks"
21654
21655 test_230s() {
21656         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21657                 skip "Need MDS version at least 2.14.52"
21658
21659         local mdts=$(comma_list $(mdts_nodes))
21660         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21661                                 mdt.*MDT0000.enable_dir_restripe)
21662
21663         stack_trap "do_nodes $mdts $LCTL set_param \
21664                     mdt.*.enable_dir_restripe=$restripe_status"
21665
21666         local st
21667         for st in 0 1; do
21668                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21669                 test_mkdir $DIR/$tdir
21670                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21671                         error "$LFS mkdir should return EEXIST if target exists"
21672                 rmdir $DIR/$tdir
21673         done
21674 }
21675 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21676
21677 test_230t()
21678 {
21679         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21680         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21681                 skip "Need MDS version at least 2.14.50"
21682
21683         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21684         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21685         $LFS project -p 1 -s $DIR/$tdir ||
21686                 error "set $tdir project id failed"
21687         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21688                 error "set subdir project id failed"
21689         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21690 }
21691 run_test 230t "migrate directory with project ID set"
21692
21693 test_230u()
21694 {
21695         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21696         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21697                 skip "Need MDS version at least 2.14.53"
21698
21699         local count
21700
21701         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21702         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21703         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21704         for i in $(seq 0 $((MDSCOUNT - 1))); do
21705                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21706                 echo "$count dirs migrated to MDT$i"
21707         done
21708         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21709         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21710 }
21711 run_test 230u "migrate directory by QOS"
21712
21713 test_230v()
21714 {
21715         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21716         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21717                 skip "Need MDS version at least 2.14.53"
21718
21719         local count
21720
21721         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21722         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21723         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21724         for i in $(seq 0 $((MDSCOUNT - 1))); do
21725                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21726                 echo "$count subdirs migrated to MDT$i"
21727                 (( i == 3 )) && (( count > 0 )) &&
21728                         error "subdir shouldn't be migrated to MDT3"
21729         done
21730         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21731         (( count == 3 )) || error "dirs migrated to $count MDTs"
21732 }
21733 run_test 230v "subdir migrated to the MDT where its parent is located"
21734
21735 test_230w() {
21736         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21737         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21738                 skip "Need MDS version at least 2.15.0"
21739
21740         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21741         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21742         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21743
21744         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21745                 error "migrate failed"
21746
21747         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21748                 error "$tdir stripe count mismatch"
21749
21750         for i in $(seq 0 9); do
21751                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21752                         error "d$i is striped"
21753         done
21754 }
21755 run_test 230w "non-recursive mode dir migration"
21756
21757 test_230x() {
21758         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21759         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21760                 skip "Need MDS version at least 2.15.0"
21761
21762         mkdir -p $DIR/$tdir || error "mkdir failed"
21763         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21764
21765         local mdt_name=$(mdtname_from_index 0)
21766         local low=$(do_facet mds2 $LCTL get_param -n \
21767                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21768         local high=$(do_facet mds2 $LCTL get_param -n \
21769                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21770         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21771         local maxage=$(do_facet mds2 $LCTL get_param -n \
21772                 osp.*$mdt_name-osp-MDT0001.maxage)
21773
21774         stack_trap "do_facet mds2 $LCTL set_param -n \
21775                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21776                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21777         stack_trap "do_facet mds2 $LCTL set_param -n \
21778                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21779
21780         do_facet mds2 $LCTL set_param -n \
21781                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21782         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21783         sleep 4
21784         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21785                 error "migrate $tdir should fail"
21786
21787         do_facet mds2 $LCTL set_param -n \
21788                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21789         do_facet mds2 $LCTL set_param -n \
21790                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21791         sleep 4
21792         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21793                 error "migrate failed"
21794         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21795                 error "$tdir stripe count mismatch"
21796 }
21797 run_test 230x "dir migration check space"
21798
21799 test_231a()
21800 {
21801         # For simplicity this test assumes that max_pages_per_rpc
21802         # is the same across all OSCs
21803         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21804         local bulk_size=$((max_pages * PAGE_SIZE))
21805         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21806                                        head -n 1)
21807
21808         mkdir -p $DIR/$tdir
21809         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21810                 error "failed to set stripe with -S ${brw_size}M option"
21811
21812         # clear the OSC stats
21813         $LCTL set_param osc.*.stats=0 &>/dev/null
21814         stop_writeback
21815
21816         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21817         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21818                 oflag=direct &>/dev/null || error "dd failed"
21819
21820         sync; sleep 1; sync # just to be safe
21821         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21822         if [ x$nrpcs != "x1" ]; then
21823                 $LCTL get_param osc.*.stats
21824                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21825         fi
21826
21827         start_writeback
21828         # Drop the OSC cache, otherwise we will read from it
21829         cancel_lru_locks osc
21830
21831         # clear the OSC stats
21832         $LCTL set_param osc.*.stats=0 &>/dev/null
21833
21834         # Client reads $bulk_size.
21835         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21836                 iflag=direct &>/dev/null || error "dd failed"
21837
21838         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21839         if [ x$nrpcs != "x1" ]; then
21840                 $LCTL get_param osc.*.stats
21841                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21842         fi
21843 }
21844 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21845
21846 test_231b() {
21847         mkdir -p $DIR/$tdir
21848         local i
21849         for i in {0..1023}; do
21850                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21851                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21852                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21853         done
21854         sync
21855 }
21856 run_test 231b "must not assert on fully utilized OST request buffer"
21857
21858 test_232a() {
21859         mkdir -p $DIR/$tdir
21860         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21861
21862         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21863         do_facet ost1 $LCTL set_param fail_loc=0x31c
21864
21865         # ignore dd failure
21866         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21867
21868         do_facet ost1 $LCTL set_param fail_loc=0
21869         umount_client $MOUNT || error "umount failed"
21870         mount_client $MOUNT || error "mount failed"
21871         stop ost1 || error "cannot stop ost1"
21872         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21873 }
21874 run_test 232a "failed lock should not block umount"
21875
21876 test_232b() {
21877         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21878                 skip "Need MDS version at least 2.10.58"
21879
21880         mkdir -p $DIR/$tdir
21881         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21882         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21883         sync
21884         cancel_lru_locks osc
21885
21886         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21887         do_facet ost1 $LCTL set_param fail_loc=0x31c
21888
21889         # ignore failure
21890         $LFS data_version $DIR/$tdir/$tfile || true
21891
21892         do_facet ost1 $LCTL set_param fail_loc=0
21893         umount_client $MOUNT || error "umount failed"
21894         mount_client $MOUNT || error "mount failed"
21895         stop ost1 || error "cannot stop ost1"
21896         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21897 }
21898 run_test 232b "failed data version lock should not block umount"
21899
21900 test_233a() {
21901         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21902                 skip "Need MDS version at least 2.3.64"
21903         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21904
21905         local fid=$($LFS path2fid $MOUNT)
21906
21907         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21908                 error "cannot access $MOUNT using its FID '$fid'"
21909 }
21910 run_test 233a "checking that OBF of the FS root succeeds"
21911
21912 test_233b() {
21913         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21914                 skip "Need MDS version at least 2.5.90"
21915         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21916
21917         local fid=$($LFS path2fid $MOUNT/.lustre)
21918
21919         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21920                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21921
21922         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21923         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21924                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21925 }
21926 run_test 233b "checking that OBF of the FS .lustre succeeds"
21927
21928 test_234() {
21929         local p="$TMP/sanityN-$TESTNAME.parameters"
21930         save_lustre_params client "llite.*.xattr_cache" > $p
21931         lctl set_param llite.*.xattr_cache 1 ||
21932                 skip_env "xattr cache is not supported"
21933
21934         mkdir -p $DIR/$tdir || error "mkdir failed"
21935         touch $DIR/$tdir/$tfile || error "touch failed"
21936         # OBD_FAIL_LLITE_XATTR_ENOMEM
21937         $LCTL set_param fail_loc=0x1405
21938         getfattr -n user.attr $DIR/$tdir/$tfile &&
21939                 error "getfattr should have failed with ENOMEM"
21940         $LCTL set_param fail_loc=0x0
21941         rm -rf $DIR/$tdir
21942
21943         restore_lustre_params < $p
21944         rm -f $p
21945 }
21946 run_test 234 "xattr cache should not crash on ENOMEM"
21947
21948 test_235() {
21949         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21950                 skip "Need MDS version at least 2.4.52"
21951
21952         flock_deadlock $DIR/$tfile
21953         local RC=$?
21954         case $RC in
21955                 0)
21956                 ;;
21957                 124) error "process hangs on a deadlock"
21958                 ;;
21959                 *) error "error executing flock_deadlock $DIR/$tfile"
21960                 ;;
21961         esac
21962 }
21963 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21964
21965 #LU-2935
21966 test_236() {
21967         check_swap_layouts_support
21968
21969         local ref1=/etc/passwd
21970         local ref2=/etc/group
21971         local file1=$DIR/$tdir/f1
21972         local file2=$DIR/$tdir/f2
21973
21974         test_mkdir -c1 $DIR/$tdir
21975         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21976         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21977         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21978         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21979         local fd=$(free_fd)
21980         local cmd="exec $fd<>$file2"
21981         eval $cmd
21982         rm $file2
21983         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21984                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21985         cmd="exec $fd>&-"
21986         eval $cmd
21987         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21988
21989         #cleanup
21990         rm -rf $DIR/$tdir
21991 }
21992 run_test 236 "Layout swap on open unlinked file"
21993
21994 # LU-4659 linkea consistency
21995 test_238() {
21996         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21997                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21998                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21999                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
22000
22001         touch $DIR/$tfile
22002         ln $DIR/$tfile $DIR/$tfile.lnk
22003         touch $DIR/$tfile.new
22004         mv $DIR/$tfile.new $DIR/$tfile
22005         local fid1=$($LFS path2fid $DIR/$tfile)
22006         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
22007         local path1=$($LFS fid2path $FSNAME "$fid1")
22008         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
22009         local path2=$($LFS fid2path $FSNAME "$fid2")
22010         [ $tfile.lnk == $path2 ] ||
22011                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
22012         rm -f $DIR/$tfile*
22013 }
22014 run_test 238 "Verify linkea consistency"
22015
22016 test_239A() { # was test_239
22017         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
22018                 skip "Need MDS version at least 2.5.60"
22019
22020         local list=$(comma_list $(mdts_nodes))
22021
22022         mkdir -p $DIR/$tdir
22023         createmany -o $DIR/$tdir/f- 5000
22024         unlinkmany $DIR/$tdir/f- 5000
22025         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
22026                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
22027         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
22028                         osp.*MDT*.sync_in_flight" | calc_sum)
22029         [ "$changes" -eq 0 ] || error "$changes not synced"
22030 }
22031 run_test 239A "osp_sync test"
22032
22033 test_239a() { #LU-5297
22034         remote_mds_nodsh && skip "remote MDS with nodsh"
22035
22036         touch $DIR/$tfile
22037         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
22038         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
22039         chgrp $RUNAS_GID $DIR/$tfile
22040         wait_delete_completed
22041 }
22042 run_test 239a "process invalid osp sync record correctly"
22043
22044 test_239b() { #LU-5297
22045         remote_mds_nodsh && skip "remote MDS with nodsh"
22046
22047         touch $DIR/$tfile1
22048         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
22049         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
22050         chgrp $RUNAS_GID $DIR/$tfile1
22051         wait_delete_completed
22052         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
22053         touch $DIR/$tfile2
22054         chgrp $RUNAS_GID $DIR/$tfile2
22055         wait_delete_completed
22056 }
22057 run_test 239b "process osp sync record with ENOMEM error correctly"
22058
22059 test_240() {
22060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
22061         remote_mds_nodsh && skip "remote MDS with nodsh"
22062
22063         mkdir -p $DIR/$tdir
22064
22065         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
22066                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
22067         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
22068                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
22069
22070         umount_client $MOUNT || error "umount failed"
22071         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
22072         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
22073         mount_client $MOUNT || error "failed to mount client"
22074
22075         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
22076         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
22077 }
22078 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
22079
22080 test_241_bio() {
22081         local count=$1
22082         local bsize=$2
22083
22084         for LOOP in $(seq $count); do
22085                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
22086                 cancel_lru_locks $OSC || true
22087         done
22088 }
22089
22090 test_241_dio() {
22091         local count=$1
22092         local bsize=$2
22093
22094         for LOOP in $(seq $1); do
22095                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
22096                         2>/dev/null
22097         done
22098 }
22099
22100 test_241a() { # was test_241
22101         local bsize=$PAGE_SIZE
22102
22103         (( bsize < 40960 )) && bsize=40960
22104         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22105         ls -la $DIR/$tfile
22106         cancel_lru_locks $OSC
22107         test_241_bio 1000 $bsize &
22108         PID=$!
22109         test_241_dio 1000 $bsize
22110         wait $PID
22111 }
22112 run_test 241a "bio vs dio"
22113
22114 test_241b() {
22115         local bsize=$PAGE_SIZE
22116
22117         (( bsize < 40960 )) && bsize=40960
22118         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
22119         ls -la $DIR/$tfile
22120         test_241_dio 1000 $bsize &
22121         PID=$!
22122         test_241_dio 1000 $bsize
22123         wait $PID
22124 }
22125 run_test 241b "dio vs dio"
22126
22127 test_242() {
22128         remote_mds_nodsh && skip "remote MDS with nodsh"
22129
22130         mkdir_on_mdt0 $DIR/$tdir
22131         touch $DIR/$tdir/$tfile
22132
22133         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22134         do_facet mds1 lctl set_param fail_loc=0x105
22135         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22136
22137         do_facet mds1 lctl set_param fail_loc=0
22138         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22139 }
22140 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22141
22142 test_243()
22143 {
22144         test_mkdir $DIR/$tdir
22145         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22146 }
22147 run_test 243 "various group lock tests"
22148
22149 test_244a()
22150 {
22151         test_mkdir $DIR/$tdir
22152         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22153         sendfile_grouplock $DIR/$tdir/$tfile || \
22154                 error "sendfile+grouplock failed"
22155         rm -rf $DIR/$tdir
22156 }
22157 run_test 244a "sendfile with group lock tests"
22158
22159 test_244b()
22160 {
22161         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22162
22163         local threads=50
22164         local size=$((1024*1024))
22165
22166         test_mkdir $DIR/$tdir
22167         for i in $(seq 1 $threads); do
22168                 local file=$DIR/$tdir/file_$((i / 10))
22169                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22170                 local pids[$i]=$!
22171         done
22172         for i in $(seq 1 $threads); do
22173                 wait ${pids[$i]}
22174         done
22175 }
22176 run_test 244b "multi-threaded write with group lock"
22177
22178 test_245a() {
22179         local flagname="multi_mod_rpcs"
22180         local connect_data_name="max_mod_rpcs"
22181         local out
22182
22183         # check if multiple modify RPCs flag is set
22184         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22185                 grep "connect_flags:")
22186         echo "$out"
22187
22188         echo "$out" | grep -qw $flagname
22189         if [ $? -ne 0 ]; then
22190                 echo "connect flag $flagname is not set"
22191                 return
22192         fi
22193
22194         # check if multiple modify RPCs data is set
22195         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22196         echo "$out"
22197
22198         echo "$out" | grep -qw $connect_data_name ||
22199                 error "import should have connect data $connect_data_name"
22200 }
22201 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22202
22203 test_245b() {
22204         local flagname="multi_mod_rpcs"
22205         local connect_data_name="max_mod_rpcs"
22206         local out
22207
22208         remote_mds_nodsh && skip "remote MDS with nodsh"
22209         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22210
22211         # check if multiple modify RPCs flag is set
22212         out=$(do_facet mds1 \
22213               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22214               grep "connect_flags:")
22215         echo "$out"
22216
22217         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22218
22219         # check if multiple modify RPCs data is set
22220         out=$(do_facet mds1 \
22221               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22222
22223         [[ "$out" =~ $connect_data_name ]] ||
22224                 {
22225                         echo "$out"
22226                         error "missing connect data $connect_data_name"
22227                 }
22228 }
22229 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22230
22231 cleanup_247() {
22232         local submount=$1
22233
22234         trap 0
22235         umount_client $submount
22236         rmdir $submount
22237 }
22238
22239 test_247a() {
22240         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22241                 grep -q subtree ||
22242                 skip_env "Fileset feature is not supported"
22243
22244         local submount=${MOUNT}_$tdir
22245
22246         mkdir $MOUNT/$tdir
22247         mkdir -p $submount || error "mkdir $submount failed"
22248         FILESET="$FILESET/$tdir" mount_client $submount ||
22249                 error "mount $submount failed"
22250         trap "cleanup_247 $submount" EXIT
22251         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22252         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22253                 error "read $MOUNT/$tdir/$tfile failed"
22254         cleanup_247 $submount
22255 }
22256 run_test 247a "mount subdir as fileset"
22257
22258 test_247b() {
22259         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22260                 skip_env "Fileset feature is not supported"
22261
22262         local submount=${MOUNT}_$tdir
22263
22264         rm -rf $MOUNT/$tdir
22265         mkdir -p $submount || error "mkdir $submount failed"
22266         SKIP_FILESET=1
22267         FILESET="$FILESET/$tdir" mount_client $submount &&
22268                 error "mount $submount should fail"
22269         rmdir $submount
22270 }
22271 run_test 247b "mount subdir that dose not exist"
22272
22273 test_247c() {
22274         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22275                 skip_env "Fileset feature is not supported"
22276
22277         local submount=${MOUNT}_$tdir
22278
22279         mkdir -p $MOUNT/$tdir/dir1
22280         mkdir -p $submount || error "mkdir $submount failed"
22281         trap "cleanup_247 $submount" EXIT
22282         FILESET="$FILESET/$tdir" mount_client $submount ||
22283                 error "mount $submount failed"
22284         local fid=$($LFS path2fid $MOUNT/)
22285         $LFS fid2path $submount $fid && error "fid2path should fail"
22286         cleanup_247 $submount
22287 }
22288 run_test 247c "running fid2path outside subdirectory root"
22289
22290 test_247d() {
22291         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22292                 skip "Fileset feature is not supported"
22293
22294         local submount=${MOUNT}_$tdir
22295
22296         mkdir -p $MOUNT/$tdir/dir1
22297         mkdir -p $submount || error "mkdir $submount failed"
22298         FILESET="$FILESET/$tdir" mount_client $submount ||
22299                 error "mount $submount failed"
22300         trap "cleanup_247 $submount" EXIT
22301
22302         local td=$submount/dir1
22303         local fid=$($LFS path2fid $td)
22304         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22305
22306         # check that we get the same pathname back
22307         local rootpath
22308         local found
22309         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22310                 echo "$rootpath $fid"
22311                 found=$($LFS fid2path $rootpath "$fid")
22312                 [ -n "$found" ] || error "fid2path should succeed"
22313                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22314         done
22315         # check wrong root path format
22316         rootpath=$submount"_wrong"
22317         found=$($LFS fid2path $rootpath "$fid")
22318         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22319
22320         cleanup_247 $submount
22321 }
22322 run_test 247d "running fid2path inside subdirectory root"
22323
22324 # LU-8037
22325 test_247e() {
22326         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22327                 grep -q subtree ||
22328                 skip "Fileset feature is not supported"
22329
22330         local submount=${MOUNT}_$tdir
22331
22332         mkdir $MOUNT/$tdir
22333         mkdir -p $submount || error "mkdir $submount failed"
22334         FILESET="$FILESET/.." mount_client $submount &&
22335                 error "mount $submount should fail"
22336         rmdir $submount
22337 }
22338 run_test 247e "mount .. as fileset"
22339
22340 test_247f() {
22341         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22342         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22343                 skip "Need at least version 2.14.50.162"
22344         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22345                 skip "Fileset feature is not supported"
22346
22347         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22348         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22349                 error "mkdir remote failed"
22350         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22351                 error "mkdir remote/subdir failed"
22352         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22353                 error "mkdir striped failed"
22354         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22355
22356         local submount=${MOUNT}_$tdir
22357
22358         mkdir -p $submount || error "mkdir $submount failed"
22359         stack_trap "rmdir $submount"
22360
22361         local dir
22362         local fileset=$FILESET
22363         local mdts=$(comma_list $(mdts_nodes))
22364
22365         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22366         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22367                 $tdir/striped/subdir $tdir/striped/.; do
22368                 FILESET="$fileset/$dir" mount_client $submount ||
22369                         error "mount $dir failed"
22370                 umount_client $submount
22371         done
22372 }
22373 run_test 247f "mount striped or remote directory as fileset"
22374
22375 test_subdir_mount_lock()
22376 {
22377         local testdir=$1
22378         local submount=${MOUNT}_$(basename $testdir)
22379
22380         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22381
22382         mkdir -p $submount || error "mkdir $submount failed"
22383         stack_trap "rmdir $submount"
22384
22385         FILESET="$fileset/$testdir" mount_client $submount ||
22386                 error "mount $FILESET failed"
22387         stack_trap "umount $submount"
22388
22389         local mdts=$(comma_list $(mdts_nodes))
22390
22391         local nrpcs
22392
22393         stat $submount > /dev/null || error "stat $submount failed"
22394         cancel_lru_locks $MDC
22395         stat $submount > /dev/null || error "stat $submount failed"
22396         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22397         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22398         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22399         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22400                 awk '/getattr/ {sum += $2} END {print sum}')
22401
22402         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22403 }
22404
22405 test_247g() {
22406         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22407
22408         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22409                 error "mkdir $tdir failed"
22410         test_subdir_mount_lock $tdir
22411 }
22412 run_test 247g "striped directory submount revalidate ROOT from cache"
22413
22414 test_247h() {
22415         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22416         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22417                 skip "Need MDS version at least 2.15.51"
22418
22419         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22420         test_subdir_mount_lock $tdir
22421         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22422         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22423                 error "mkdir $tdir.1 failed"
22424         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22425 }
22426 run_test 247h "remote directory submount revalidate ROOT from cache"
22427
22428 test_248a() {
22429         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22430         [ -z "$fast_read_sav" ] && skip "no fast read support"
22431
22432         # create a large file for fast read verification
22433         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22434
22435         # make sure the file is created correctly
22436         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22437                 { rm -f $DIR/$tfile; skip "file creation error"; }
22438
22439         echo "Test 1: verify that fast read is 4 times faster on cache read"
22440
22441         # small read with fast read enabled
22442         $LCTL set_param -n llite.*.fast_read=1
22443         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22444                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22445                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22446         # small read with fast read disabled
22447         $LCTL set_param -n llite.*.fast_read=0
22448         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22449                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22450                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22451
22452         # verify that fast read is 4 times faster for cache read
22453         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22454                 error_not_in_vm "fast read was not 4 times faster: " \
22455                            "$t_fast vs $t_slow"
22456
22457         echo "Test 2: verify the performance between big and small read"
22458         $LCTL set_param -n llite.*.fast_read=1
22459
22460         # 1k non-cache read
22461         cancel_lru_locks osc
22462         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22463                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22464                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22465
22466         # 1M non-cache read
22467         cancel_lru_locks osc
22468         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22469                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22470                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22471
22472         # verify that big IO is not 4 times faster than small IO
22473         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22474                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22475
22476         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22477         rm -f $DIR/$tfile
22478 }
22479 run_test 248a "fast read verification"
22480
22481 test_248b() {
22482         # Default short_io_bytes=16384, try both smaller and larger sizes.
22483         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22484         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22485         echo "bs=53248 count=113 normal buffered write"
22486         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22487                 error "dd of initial data file failed"
22488         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22489
22490         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22491         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22492                 error "dd with sync normal writes failed"
22493         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22494
22495         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22496         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22497                 error "dd with sync small writes failed"
22498         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22499
22500         cancel_lru_locks osc
22501
22502         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22503         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22504         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22505         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22506                 iflag=direct || error "dd with O_DIRECT small read failed"
22507         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22508         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22509                 error "compare $TMP/$tfile.1 failed"
22510
22511         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22512         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22513
22514         # just to see what the maximum tunable value is, and test parsing
22515         echo "test invalid parameter 2MB"
22516         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22517                 error "too-large short_io_bytes allowed"
22518         echo "test maximum parameter 512KB"
22519         # if we can set a larger short_io_bytes, run test regardless of version
22520         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22521                 # older clients may not allow setting it this large, that's OK
22522                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22523                         skip "Need at least client version 2.13.50"
22524                 error "medium short_io_bytes failed"
22525         fi
22526         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22527         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22528
22529         echo "test large parameter 64KB"
22530         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22531         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22532
22533         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22534         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22535                 error "dd with sync large writes failed"
22536         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22537
22538         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22539         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22540         num=$((113 * 4096 / PAGE_SIZE))
22541         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22542         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22543                 error "dd with O_DIRECT large writes failed"
22544         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22545                 error "compare $DIR/$tfile.3 failed"
22546
22547         cancel_lru_locks osc
22548
22549         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22550         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22551                 error "dd with O_DIRECT large read failed"
22552         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22553                 error "compare $TMP/$tfile.2 failed"
22554
22555         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22556         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22557                 error "dd with O_DIRECT large read failed"
22558         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22559                 error "compare $TMP/$tfile.3 failed"
22560 }
22561 run_test 248b "test short_io read and write for both small and large sizes"
22562
22563 test_249() { # LU-7890
22564         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22565                 skip "Need at least version 2.8.54"
22566
22567         rm -f $DIR/$tfile
22568         $LFS setstripe -c 1 $DIR/$tfile
22569         # Offset 2T == 4k * 512M
22570         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22571                 error "dd to 2T offset failed"
22572 }
22573 run_test 249 "Write above 2T file size"
22574
22575 test_250() {
22576         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22577          && skip "no 16TB file size limit on ZFS"
22578
22579         $LFS setstripe -c 1 $DIR/$tfile
22580         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22581         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22582         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22583         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22584                 conv=notrunc,fsync && error "append succeeded"
22585         return 0
22586 }
22587 run_test 250 "Write above 16T limit"
22588
22589 test_251() {
22590         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22591
22592         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22593         #Skip once - writing the first stripe will succeed
22594         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22595         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22596                 error "short write happened"
22597
22598         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22599         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22600                 error "short read happened"
22601
22602         rm -f $DIR/$tfile
22603 }
22604 run_test 251 "Handling short read and write correctly"
22605
22606 test_252() {
22607         remote_mds_nodsh && skip "remote MDS with nodsh"
22608         remote_ost_nodsh && skip "remote OST with nodsh"
22609         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22610                 skip_env "ldiskfs only test"
22611         fi
22612
22613         local tgt
22614         local dev
22615         local out
22616         local uuid
22617         local num
22618         local gen
22619
22620         # check lr_reader on OST0000
22621         tgt=ost1
22622         dev=$(facet_device $tgt)
22623         out=$(do_facet $tgt $LR_READER $dev)
22624         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22625         echo "$out"
22626         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22627         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22628                 error "Invalid uuid returned by $LR_READER on target $tgt"
22629         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22630
22631         # check lr_reader -c on MDT0000
22632         tgt=mds1
22633         dev=$(facet_device $tgt)
22634         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22635                 skip "$LR_READER does not support additional options"
22636         fi
22637         out=$(do_facet $tgt $LR_READER -c $dev)
22638         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22639         echo "$out"
22640         num=$(echo "$out" | grep -c "mdtlov")
22641         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22642                 error "Invalid number of mdtlov clients returned by $LR_READER"
22643         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22644
22645         # check lr_reader -cr on MDT0000
22646         out=$(do_facet $tgt $LR_READER -cr $dev)
22647         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22648         echo "$out"
22649         echo "$out" | grep -q "^reply_data:$" ||
22650                 error "$LR_READER should have returned 'reply_data' section"
22651         num=$(echo "$out" | grep -c "client_generation")
22652         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22653 }
22654 run_test 252 "check lr_reader tool"
22655
22656 test_253() {
22657         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22658         remote_mds_nodsh && skip "remote MDS with nodsh"
22659         remote_mgs_nodsh && skip "remote MGS with nodsh"
22660
22661         local ostidx=0
22662         local rc=0
22663         local ost_name=$(ostname_from_index $ostidx)
22664
22665         # on the mdt's osc
22666         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22667         do_facet $SINGLEMDS $LCTL get_param -n \
22668                 osp.$mdtosc_proc1.reserved_mb_high ||
22669                 skip  "remote MDS does not support reserved_mb_high"
22670
22671         rm -rf $DIR/$tdir
22672         wait_mds_ost_sync
22673         wait_delete_completed
22674         mkdir $DIR/$tdir
22675
22676         pool_add $TESTNAME || error "Pool creation failed"
22677         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22678
22679         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22680                 error "Setstripe failed"
22681
22682         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22683
22684         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22685                     grep "watermarks")
22686         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22687
22688         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22689                         osp.$mdtosc_proc1.prealloc_status)
22690         echo "prealloc_status $oa_status"
22691
22692         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22693                 error "File creation should fail"
22694
22695         #object allocation was stopped, but we still able to append files
22696         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22697                 oflag=append || error "Append failed"
22698
22699         rm -f $DIR/$tdir/$tfile.0
22700
22701         # For this test, we want to delete the files we created to go out of
22702         # space but leave the watermark, so we remain nearly out of space
22703         ost_watermarks_enospc_delete_files $tfile $ostidx
22704
22705         wait_delete_completed
22706
22707         sleep_maxage
22708
22709         for i in $(seq 10 12); do
22710                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22711                         2>/dev/null || error "File creation failed after rm"
22712         done
22713
22714         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22715                         osp.$mdtosc_proc1.prealloc_status)
22716         echo "prealloc_status $oa_status"
22717
22718         if (( oa_status != 0 )); then
22719                 error "Object allocation still disable after rm"
22720         fi
22721 }
22722 run_test 253 "Check object allocation limit"
22723
22724 test_254() {
22725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22726         remote_mds_nodsh && skip "remote MDS with nodsh"
22727
22728         local mdt=$(facet_svc $SINGLEMDS)
22729
22730         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22731                 skip "MDS does not support changelog_size"
22732
22733         local cl_user
22734
22735         changelog_register || error "changelog_register failed"
22736
22737         changelog_clear 0 || error "changelog_clear failed"
22738
22739         local size1=$(do_facet $SINGLEMDS \
22740                       $LCTL get_param -n mdd.$mdt.changelog_size)
22741         echo "Changelog size $size1"
22742
22743         rm -rf $DIR/$tdir
22744         $LFS mkdir -i 0 $DIR/$tdir
22745         # change something
22746         mkdir -p $DIR/$tdir/pics/2008/zachy
22747         touch $DIR/$tdir/pics/2008/zachy/timestamp
22748         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22749         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22750         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22751         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22752         rm $DIR/$tdir/pics/desktop.jpg
22753
22754         local size2=$(do_facet $SINGLEMDS \
22755                       $LCTL get_param -n mdd.$mdt.changelog_size)
22756         echo "Changelog size after work $size2"
22757
22758         (( $size2 > $size1 )) ||
22759                 error "new Changelog size=$size2 less than old size=$size1"
22760 }
22761 run_test 254 "Check changelog size"
22762
22763 ladvise_no_type()
22764 {
22765         local type=$1
22766         local file=$2
22767
22768         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22769                 awk -F: '{print $2}' | grep $type > /dev/null
22770         if [ $? -ne 0 ]; then
22771                 return 0
22772         fi
22773         return 1
22774 }
22775
22776 ladvise_no_ioctl()
22777 {
22778         local file=$1
22779
22780         lfs ladvise -a willread $file > /dev/null 2>&1
22781         if [ $? -eq 0 ]; then
22782                 return 1
22783         fi
22784
22785         lfs ladvise -a willread $file 2>&1 |
22786                 grep "Inappropriate ioctl for device" > /dev/null
22787         if [ $? -eq 0 ]; then
22788                 return 0
22789         fi
22790         return 1
22791 }
22792
22793 percent() {
22794         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22795 }
22796
22797 # run a random read IO workload
22798 # usage: random_read_iops <filename> <filesize> <iosize>
22799 random_read_iops() {
22800         local file=$1
22801         local fsize=$2
22802         local iosize=${3:-4096}
22803
22804         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22805                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22806 }
22807
22808 drop_file_oss_cache() {
22809         local file="$1"
22810         local nodes="$2"
22811
22812         $LFS ladvise -a dontneed $file 2>/dev/null ||
22813                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22814 }
22815
22816 ladvise_willread_performance()
22817 {
22818         local repeat=10
22819         local average_origin=0
22820         local average_cache=0
22821         local average_ladvise=0
22822
22823         for ((i = 1; i <= $repeat; i++)); do
22824                 echo "Iter $i/$repeat: reading without willread hint"
22825                 cancel_lru_locks osc
22826                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22827                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22828                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22829                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22830
22831                 cancel_lru_locks osc
22832                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22833                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22834                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22835
22836                 cancel_lru_locks osc
22837                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22838                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22839                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22840                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22841                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22842         done
22843         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22844         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22845         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22846
22847         speedup_cache=$(percent $average_cache $average_origin)
22848         speedup_ladvise=$(percent $average_ladvise $average_origin)
22849
22850         echo "Average uncached read: $average_origin"
22851         echo "Average speedup with OSS cached read: " \
22852                 "$average_cache = +$speedup_cache%"
22853         echo "Average speedup with ladvise willread: " \
22854                 "$average_ladvise = +$speedup_ladvise%"
22855
22856         local lowest_speedup=20
22857         if (( ${average_cache%.*} < $lowest_speedup )); then
22858                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22859                      " got $average_cache%. Skipping ladvise willread check."
22860                 return 0
22861         fi
22862
22863         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22864         # it is still good to run until then to exercise 'ladvise willread'
22865         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22866                 [ "$ost1_FSTYPE" = "zfs" ] &&
22867                 echo "osd-zfs does not support dontneed or drop_caches" &&
22868                 return 0
22869
22870         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22871         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22872                 error_not_in_vm "Speedup with willread is less than " \
22873                         "$lowest_speedup%, got $average_ladvise%"
22874 }
22875
22876 test_255a() {
22877         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22878                 skip "lustre < 2.8.54 does not support ladvise "
22879         remote_ost_nodsh && skip "remote OST with nodsh"
22880
22881         stack_trap "rm -f $DIR/$tfile"
22882         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22883
22884         ladvise_no_type willread $DIR/$tfile &&
22885                 skip "willread ladvise is not supported"
22886
22887         ladvise_no_ioctl $DIR/$tfile &&
22888                 skip "ladvise ioctl is not supported"
22889
22890         local size_mb=100
22891         local size=$((size_mb * 1048576))
22892         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22893                 error "dd to $DIR/$tfile failed"
22894
22895         lfs ladvise -a willread $DIR/$tfile ||
22896                 error "Ladvise failed with no range argument"
22897
22898         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22899                 error "Ladvise failed with no -l or -e argument"
22900
22901         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22902                 error "Ladvise failed with only -e argument"
22903
22904         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22905                 error "Ladvise failed with only -l argument"
22906
22907         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22908                 error "End offset should not be smaller than start offset"
22909
22910         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22911                 error "End offset should not be equal to start offset"
22912
22913         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22914                 error "Ladvise failed with overflowing -s argument"
22915
22916         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22917                 error "Ladvise failed with overflowing -e argument"
22918
22919         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22920                 error "Ladvise failed with overflowing -l argument"
22921
22922         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22923                 error "Ladvise succeeded with conflicting -l and -e arguments"
22924
22925         echo "Synchronous ladvise should wait"
22926         local delay=4
22927 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22928         do_nodes $(comma_list $(osts_nodes)) \
22929                 $LCTL set_param fail_val=$delay fail_loc=0x237
22930
22931         local start_ts=$SECONDS
22932         lfs ladvise -a willread $DIR/$tfile ||
22933                 error "Ladvise failed with no range argument"
22934         local end_ts=$SECONDS
22935         local inteval_ts=$((end_ts - start_ts))
22936
22937         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22938                 error "Synchronous advice didn't wait reply"
22939         fi
22940
22941         echo "Asynchronous ladvise shouldn't wait"
22942         local start_ts=$SECONDS
22943         lfs ladvise -a willread -b $DIR/$tfile ||
22944                 error "Ladvise failed with no range argument"
22945         local end_ts=$SECONDS
22946         local inteval_ts=$((end_ts - start_ts))
22947
22948         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22949                 error "Asynchronous advice blocked"
22950         fi
22951
22952         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22953         ladvise_willread_performance
22954 }
22955 run_test 255a "check 'lfs ladvise -a willread'"
22956
22957 facet_meminfo() {
22958         local facet=$1
22959         local info=$2
22960
22961         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22962 }
22963
22964 test_255b() {
22965         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22966                 skip "lustre < 2.8.54 does not support ladvise "
22967         remote_ost_nodsh && skip "remote OST with nodsh"
22968
22969         stack_trap "rm -f $DIR/$tfile"
22970         lfs setstripe -c 1 -i 0 $DIR/$tfile
22971
22972         ladvise_no_type dontneed $DIR/$tfile &&
22973                 skip "dontneed ladvise is not supported"
22974
22975         ladvise_no_ioctl $DIR/$tfile &&
22976                 skip "ladvise ioctl is not supported"
22977
22978         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22979                 [ "$ost1_FSTYPE" = "zfs" ] &&
22980                 skip "zfs-osd does not support 'ladvise dontneed'"
22981
22982         local size_mb=100
22983         local size=$((size_mb * 1048576))
22984         # In order to prevent disturbance of other processes, only check 3/4
22985         # of the memory usage
22986         local kibibytes=$((size_mb * 1024 * 3 / 4))
22987
22988         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22989                 error "dd to $DIR/$tfile failed"
22990
22991         #force write to complete before dropping OST cache & checking memory
22992         sync
22993
22994         local total=$(facet_meminfo ost1 MemTotal)
22995         echo "Total memory: $total KiB"
22996
22997         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22998         local before_read=$(facet_meminfo ost1 Cached)
22999         echo "Cache used before read: $before_read KiB"
23000
23001         lfs ladvise -a willread $DIR/$tfile ||
23002                 error "Ladvise willread failed"
23003         local after_read=$(facet_meminfo ost1 Cached)
23004         echo "Cache used after read: $after_read KiB"
23005
23006         lfs ladvise -a dontneed $DIR/$tfile ||
23007                 error "Ladvise dontneed again failed"
23008         local no_read=$(facet_meminfo ost1 Cached)
23009         echo "Cache used after dontneed ladvise: $no_read KiB"
23010
23011         if [ $total -lt $((before_read + kibibytes)) ]; then
23012                 echo "Memory is too small, abort checking"
23013                 return 0
23014         fi
23015
23016         if [ $((before_read + kibibytes)) -gt $after_read ]; then
23017                 error "Ladvise willread should use more memory" \
23018                         "than $kibibytes KiB"
23019         fi
23020
23021         if [ $((no_read + kibibytes)) -gt $after_read ]; then
23022                 error "Ladvise dontneed should release more memory" \
23023                         "than $kibibytes KiB"
23024         fi
23025 }
23026 run_test 255b "check 'lfs ladvise -a dontneed'"
23027
23028 test_255c() {
23029         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
23030                 skip "lustre < 2.10.50 does not support lockahead"
23031
23032         local ost1_imp=$(get_osc_import_name client ost1)
23033         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
23034                          cut -d'.' -f2)
23035         local count
23036         local new_count
23037         local difference
23038         local i
23039         local rc
23040
23041         test_mkdir -p $DIR/$tdir
23042         $LFS setstripe -i 0 -c 1 $DIR/$tdir
23043
23044         #test 10 returns only success/failure
23045         i=10
23046         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23047         rc=$?
23048         if [ $rc -eq 255 ]; then
23049                 error "Ladvise test${i} failed, ${rc}"
23050         fi
23051
23052         #test 11 counts lock enqueue requests, all others count new locks
23053         i=11
23054         count=$(do_facet ost1 \
23055                 $LCTL get_param -n ost.OSS.ost.stats)
23056         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
23057
23058         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23059         rc=$?
23060         if [ $rc -eq 255 ]; then
23061                 error "Ladvise test${i} failed, ${rc}"
23062         fi
23063
23064         new_count=$(do_facet ost1 \
23065                 $LCTL get_param -n ost.OSS.ost.stats)
23066         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
23067                    awk '{ print $2 }')
23068
23069         difference="$((new_count - count))"
23070         if [ $difference -ne $rc ]; then
23071                 error "Ladvise test${i}, bad enqueue count, returned " \
23072                       "${rc}, actual ${difference}"
23073         fi
23074
23075         for i in $(seq 12 21); do
23076                 # If we do not do this, we run the risk of having too many
23077                 # locks and starting lock cancellation while we are checking
23078                 # lock counts.
23079                 cancel_lru_locks osc
23080
23081                 count=$($LCTL get_param -n \
23082                        ldlm.namespaces.$imp_name.lock_unused_count)
23083
23084                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
23085                 rc=$?
23086                 if [ $rc -eq 255 ]; then
23087                         error "Ladvise test ${i} failed, ${rc}"
23088                 fi
23089
23090                 new_count=$($LCTL get_param -n \
23091                        ldlm.namespaces.$imp_name.lock_unused_count)
23092                 difference="$((new_count - count))"
23093
23094                 # Test 15 output is divided by 100 to map down to valid return
23095                 if [ $i -eq 15 ]; then
23096                         rc="$((rc * 100))"
23097                 fi
23098
23099                 if [ $difference -ne $rc ]; then
23100                         error "Ladvise test ${i}, bad lock count, returned " \
23101                               "${rc}, actual ${difference}"
23102                 fi
23103         done
23104
23105         #test 22 returns only success/failure
23106         i=22
23107         lockahead_test -d $DIR/$tdir -t $i -f $tfile
23108         rc=$?
23109         if [ $rc -eq 255 ]; then
23110                 error "Ladvise test${i} failed, ${rc}"
23111         fi
23112 }
23113 run_test 255c "suite of ladvise lockahead tests"
23114
23115 test_256() {
23116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
23117         remote_mds_nodsh && skip "remote MDS with nodsh"
23118         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23119         changelog_users $SINGLEMDS | grep "^cl" &&
23120                 skip "active changelog user"
23121
23122         local cl_user
23123         local cat_sl
23124         local mdt_dev
23125
23126         mdt_dev=$(facet_device $SINGLEMDS)
23127         echo $mdt_dev
23128
23129         changelog_register || error "changelog_register failed"
23130
23131         rm -rf $DIR/$tdir
23132         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23133
23134         changelog_clear 0 || error "changelog_clear failed"
23135
23136         # change something
23137         touch $DIR/$tdir/{1..10}
23138
23139         # stop the MDT
23140         stop $SINGLEMDS || error "Fail to stop MDT"
23141
23142         # remount the MDT
23143         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23144                 error "Fail to start MDT"
23145
23146         #after mount new plainllog is used
23147         touch $DIR/$tdir/{11..19}
23148         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23149         stack_trap "rm -f $tmpfile"
23150         cat_sl=$(do_facet $SINGLEMDS "sync; \
23151                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23152                  llog_reader $tmpfile | grep -c type=1064553b")
23153         do_facet $SINGLEMDS llog_reader $tmpfile
23154
23155         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23156
23157         changelog_clear 0 || error "changelog_clear failed"
23158
23159         cat_sl=$(do_facet $SINGLEMDS "sync; \
23160                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23161                  llog_reader $tmpfile | grep -c type=1064553b")
23162
23163         if (( cat_sl == 2 )); then
23164                 error "Empty plain llog was not deleted from changelog catalog"
23165         elif (( cat_sl != 1 )); then
23166                 error "Active plain llog shouldn't be deleted from catalog"
23167         fi
23168 }
23169 run_test 256 "Check llog delete for empty and not full state"
23170
23171 test_257() {
23172         remote_mds_nodsh && skip "remote MDS with nodsh"
23173         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23174                 skip "Need MDS version at least 2.8.55"
23175
23176         test_mkdir $DIR/$tdir
23177
23178         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23179                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23180         stat $DIR/$tdir
23181
23182 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23183         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23184         local facet=mds$((mdtidx + 1))
23185         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23186         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23187
23188         stop $facet || error "stop MDS failed"
23189         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23190                 error "start MDS fail"
23191         wait_recovery_complete $facet
23192 }
23193 run_test 257 "xattr locks are not lost"
23194
23195 # Verify we take the i_mutex when security requires it
23196 test_258a() {
23197 #define OBD_FAIL_IMUTEX_SEC 0x141c
23198         $LCTL set_param fail_loc=0x141c
23199         touch $DIR/$tfile
23200         chmod u+s $DIR/$tfile
23201         chmod a+rwx $DIR/$tfile
23202         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23203         RC=$?
23204         if [ $RC -ne 0 ]; then
23205                 error "error, failed to take i_mutex, rc=$?"
23206         fi
23207         rm -f $DIR/$tfile
23208 }
23209 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23210
23211 # Verify we do NOT take the i_mutex in the normal case
23212 test_258b() {
23213 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23214         $LCTL set_param fail_loc=0x141d
23215         touch $DIR/$tfile
23216         chmod a+rwx $DIR
23217         chmod a+rw $DIR/$tfile
23218         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23219         RC=$?
23220         if [ $RC -ne 0 ]; then
23221                 error "error, took i_mutex unnecessarily, rc=$?"
23222         fi
23223         rm -f $DIR/$tfile
23224
23225 }
23226 run_test 258b "verify i_mutex security behavior"
23227
23228 test_259() {
23229         local file=$DIR/$tfile
23230         local before
23231         local after
23232
23233         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23234
23235         stack_trap "rm -f $file" EXIT
23236
23237         wait_delete_completed
23238         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23239         echo "before: $before"
23240
23241         $LFS setstripe -i 0 -c 1 $file
23242         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23243         sync_all_data
23244         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23245         echo "after write: $after"
23246
23247 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23248         do_facet ost1 $LCTL set_param fail_loc=0x2301
23249         $TRUNCATE $file 0
23250         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23251         echo "after truncate: $after"
23252
23253         stop ost1
23254         do_facet ost1 $LCTL set_param fail_loc=0
23255         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23256         sleep 2
23257         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23258         echo "after restart: $after"
23259         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23260                 error "missing truncate?"
23261
23262         return 0
23263 }
23264 run_test 259 "crash at delayed truncate"
23265
23266 test_260() {
23267 #define OBD_FAIL_MDC_CLOSE               0x806
23268         $LCTL set_param fail_loc=0x80000806
23269         touch $DIR/$tfile
23270
23271 }
23272 run_test 260 "Check mdc_close fail"
23273
23274 ### Data-on-MDT sanity tests ###
23275 test_270a() {
23276         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23277                 skip "Need MDS version at least 2.10.55 for DoM"
23278
23279         # create DoM file
23280         local dom=$DIR/$tdir/dom_file
23281         local tmp=$DIR/$tdir/tmp_file
23282
23283         mkdir_on_mdt0 $DIR/$tdir
23284
23285         # basic checks for DoM component creation
23286         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23287                 error "Can set MDT layout to non-first entry"
23288
23289         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23290                 error "Can define multiple entries as MDT layout"
23291
23292         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23293
23294         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23295         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23296         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23297
23298         local mdtidx=$($LFS getstripe -m $dom)
23299         local mdtname=MDT$(printf %04x $mdtidx)
23300         local facet=mds$((mdtidx + 1))
23301         local space_check=1
23302
23303         # Skip free space checks with ZFS
23304         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23305
23306         # write
23307         sync
23308         local size_tmp=$((65536 * 3))
23309         local mdtfree1=$(do_facet $facet \
23310                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23311
23312         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23313         # check also direct IO along write
23314         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23315         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23316         sync
23317         cmp $tmp $dom || error "file data is different"
23318         [ $(stat -c%s $dom) == $size_tmp ] ||
23319                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23320         if [ $space_check == 1 ]; then
23321                 local mdtfree2=$(do_facet $facet \
23322                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23323
23324                 # increase in usage from by $size_tmp
23325                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23326                         error "MDT free space wrong after write: " \
23327                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23328         fi
23329
23330         # truncate
23331         local size_dom=10000
23332
23333         $TRUNCATE $dom $size_dom
23334         [ $(stat -c%s $dom) == $size_dom ] ||
23335                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23336         if [ $space_check == 1 ]; then
23337                 mdtfree1=$(do_facet $facet \
23338                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23339                 # decrease in usage from $size_tmp to new $size_dom
23340                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23341                   $(((size_tmp - size_dom) / 1024)) ] ||
23342                         error "MDT free space is wrong after truncate: " \
23343                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23344         fi
23345
23346         # append
23347         cat $tmp >> $dom
23348         sync
23349         size_dom=$((size_dom + size_tmp))
23350         [ $(stat -c%s $dom) == $size_dom ] ||
23351                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23352         if [ $space_check == 1 ]; then
23353                 mdtfree2=$(do_facet $facet \
23354                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23355                 # increase in usage by $size_tmp from previous
23356                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23357                         error "MDT free space is wrong after append: " \
23358                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23359         fi
23360
23361         # delete
23362         rm $dom
23363         if [ $space_check == 1 ]; then
23364                 mdtfree1=$(do_facet $facet \
23365                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23366                 # decrease in usage by $size_dom from previous
23367                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23368                         error "MDT free space is wrong after removal: " \
23369                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23370         fi
23371
23372         # combined striping
23373         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23374                 error "Can't create DoM + OST striping"
23375
23376         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23377         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23378         # check also direct IO along write
23379         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23380         sync
23381         cmp $tmp $dom || error "file data is different"
23382         [ $(stat -c%s $dom) == $size_tmp ] ||
23383                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23384         rm $dom $tmp
23385
23386         return 0
23387 }
23388 run_test 270a "DoM: basic functionality tests"
23389
23390 test_270b() {
23391         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23392                 skip "Need MDS version at least 2.10.55"
23393
23394         local dom=$DIR/$tdir/dom_file
23395         local max_size=1048576
23396
23397         mkdir -p $DIR/$tdir
23398         $LFS setstripe -E $max_size -L mdt $dom
23399
23400         # truncate over the limit
23401         $TRUNCATE $dom $(($max_size + 1)) &&
23402                 error "successful truncate over the maximum size"
23403         # write over the limit
23404         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23405                 error "successful write over the maximum size"
23406         # append over the limit
23407         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23408         echo "12345" >> $dom && error "successful append over the maximum size"
23409         rm $dom
23410
23411         return 0
23412 }
23413 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23414
23415 test_270c() {
23416         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23417                 skip "Need MDS version at least 2.10.55"
23418
23419         mkdir -p $DIR/$tdir
23420         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23421
23422         # check files inherit DoM EA
23423         touch $DIR/$tdir/first
23424         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23425                 error "bad pattern"
23426         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23427                 error "bad stripe count"
23428         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23429                 error "bad stripe size"
23430
23431         # check directory inherits DoM EA and uses it as default
23432         mkdir $DIR/$tdir/subdir
23433         touch $DIR/$tdir/subdir/second
23434         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23435                 error "bad pattern in sub-directory"
23436         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23437                 error "bad stripe count in sub-directory"
23438         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23439                 error "bad stripe size in sub-directory"
23440         return 0
23441 }
23442 run_test 270c "DoM: DoM EA inheritance tests"
23443
23444 test_270d() {
23445         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23446                 skip "Need MDS version at least 2.10.55"
23447
23448         mkdir -p $DIR/$tdir
23449         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23450
23451         # inherit default DoM striping
23452         mkdir $DIR/$tdir/subdir
23453         touch $DIR/$tdir/subdir/f1
23454
23455         # change default directory striping
23456         $LFS setstripe -c 1 $DIR/$tdir/subdir
23457         touch $DIR/$tdir/subdir/f2
23458         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23459                 error "wrong default striping in file 2"
23460         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23461                 error "bad pattern in file 2"
23462         return 0
23463 }
23464 run_test 270d "DoM: change striping from DoM to RAID0"
23465
23466 test_270e() {
23467         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23468                 skip "Need MDS version at least 2.10.55"
23469
23470         mkdir -p $DIR/$tdir/dom
23471         mkdir -p $DIR/$tdir/norm
23472         DOMFILES=20
23473         NORMFILES=10
23474         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23475         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23476
23477         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23478         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23479
23480         # find DoM files by layout
23481         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23482         [ $NUM -eq  $DOMFILES ] ||
23483                 error "lfs find -L: found $NUM, expected $DOMFILES"
23484         echo "Test 1: lfs find 20 DOM files by layout: OK"
23485
23486         # there should be 1 dir with default DOM striping
23487         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23488         [ $NUM -eq  1 ] ||
23489                 error "lfs find -L: found $NUM, expected 1 dir"
23490         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23491
23492         # find DoM files by stripe size
23493         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23494         [ $NUM -eq  $DOMFILES ] ||
23495                 error "lfs find -S: found $NUM, expected $DOMFILES"
23496         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23497
23498         # find files by stripe offset except DoM files
23499         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23500         [ $NUM -eq  $NORMFILES ] ||
23501                 error "lfs find -i: found $NUM, expected $NORMFILES"
23502         echo "Test 5: lfs find no DOM files by stripe index: OK"
23503         return 0
23504 }
23505 run_test 270e "DoM: lfs find with DoM files test"
23506
23507 test_270f() {
23508         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23509                 skip "Need MDS version at least 2.10.55"
23510
23511         local mdtname=${FSNAME}-MDT0000-mdtlov
23512         local dom=$DIR/$tdir/dom_file
23513         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23514                                                 lod.$mdtname.dom_stripesize)
23515         local dom_limit=131072
23516
23517         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23518         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23519                                                 lod.$mdtname.dom_stripesize)
23520         [ ${dom_limit} -eq ${dom_current} ] ||
23521                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23522
23523         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23524         $LFS setstripe -d $DIR/$tdir
23525         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23526                 error "Can't set directory default striping"
23527
23528         # exceed maximum stripe size
23529         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23530                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23531         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23532                 error "Able to create DoM component size more than LOD limit"
23533
23534         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23535         dom_current=$(do_facet mds1 $LCTL get_param -n \
23536                                                 lod.$mdtname.dom_stripesize)
23537         [ 0 -eq ${dom_current} ] ||
23538                 error "Can't set zero DoM stripe limit"
23539         rm $dom
23540
23541         # attempt to create DoM file on server with disabled DoM should
23542         # remove DoM entry from layout and be succeed
23543         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23544                 error "Can't create DoM file (DoM is disabled)"
23545         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23546                 error "File has DoM component while DoM is disabled"
23547         rm $dom
23548
23549         # attempt to create DoM file with only DoM stripe should return error
23550         $LFS setstripe -E $dom_limit -L mdt $dom &&
23551                 error "Able to create DoM-only file while DoM is disabled"
23552
23553         # too low values to be aligned with smallest stripe size 64K
23554         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23555         dom_current=$(do_facet mds1 $LCTL get_param -n \
23556                                                 lod.$mdtname.dom_stripesize)
23557         [ 30000 -eq ${dom_current} ] &&
23558                 error "Can set too small DoM stripe limit"
23559
23560         # 64K is a minimal stripe size in Lustre, expect limit of that size
23561         [ 65536 -eq ${dom_current} ] ||
23562                 error "Limit is not set to 64K but ${dom_current}"
23563
23564         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23565         dom_current=$(do_facet mds1 $LCTL get_param -n \
23566                                                 lod.$mdtname.dom_stripesize)
23567         echo $dom_current
23568         [ 2147483648 -eq ${dom_current} ] &&
23569                 error "Can set too large DoM stripe limit"
23570
23571         do_facet mds1 $LCTL set_param -n \
23572                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23573         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23574                 error "Can't create DoM component size after limit change"
23575         do_facet mds1 $LCTL set_param -n \
23576                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23577         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23578                 error "Can't create DoM file after limit decrease"
23579         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23580                 error "Can create big DoM component after limit decrease"
23581         touch ${dom}_def ||
23582                 error "Can't create file with old default layout"
23583
23584         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23585         return 0
23586 }
23587 run_test 270f "DoM: maximum DoM stripe size checks"
23588
23589 test_270g() {
23590         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23591                 skip "Need MDS version at least 2.13.52"
23592         local dom=$DIR/$tdir/$tfile
23593
23594         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23595         local lodname=${FSNAME}-MDT0000-mdtlov
23596
23597         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23598         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23599         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23600         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23601
23602         local dom_limit=1024
23603         local dom_threshold="50%"
23604
23605         $LFS setstripe -d $DIR/$tdir
23606         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23607                 error "Can't set directory default striping"
23608
23609         do_facet mds1 $LCTL set_param -n \
23610                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23611         # set 0 threshold and create DOM file to change tunable stripesize
23612         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23613         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23614                 error "Failed to create $dom file"
23615         # now tunable dom_cur_stripesize should reach maximum
23616         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23617                                         lod.${lodname}.dom_stripesize_cur_kb)
23618         [[ $dom_current == $dom_limit ]] ||
23619                 error "Current DOM stripesize is not maximum"
23620         rm $dom
23621
23622         # set threshold for further tests
23623         do_facet mds1 $LCTL set_param -n \
23624                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23625         echo "DOM threshold is $dom_threshold free space"
23626         local dom_def
23627         local dom_set
23628         # Spoof bfree to exceed threshold
23629         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23630         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23631         for spfree in 40 20 0 15 30 55; do
23632                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23633                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23634                         error "Failed to create $dom file"
23635                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23636                                         lod.${lodname}.dom_stripesize_cur_kb)
23637                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23638                 [[ $dom_def != $dom_current ]] ||
23639                         error "Default stripe size was not changed"
23640                 if (( spfree > 0 )) ; then
23641                         dom_set=$($LFS getstripe -S $dom)
23642                         (( dom_set == dom_def * 1024 )) ||
23643                                 error "DOM component size is still old"
23644                 else
23645                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23646                                 error "DoM component is set with no free space"
23647                 fi
23648                 rm $dom
23649                 dom_current=$dom_def
23650         done
23651 }
23652 run_test 270g "DoM: default DoM stripe size depends on free space"
23653
23654 test_270h() {
23655         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23656                 skip "Need MDS version at least 2.13.53"
23657
23658         local mdtname=${FSNAME}-MDT0000-mdtlov
23659         local dom=$DIR/$tdir/$tfile
23660         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23661
23662         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23663         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23664
23665         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23666         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23667                 error "can't create OST file"
23668         # mirrored file with DOM entry in the second mirror
23669         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23670                 error "can't create mirror with DoM component"
23671
23672         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23673
23674         # DOM component in the middle and has other enries in the same mirror,
23675         # should succeed but lost DoM component
23676         $LFS setstripe --copy=${dom}_1 $dom ||
23677                 error "Can't create file from OST|DOM mirror layout"
23678         # check new file has no DoM layout after all
23679         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23680                 error "File has DoM component while DoM is disabled"
23681 }
23682 run_test 270h "DoM: DoM stripe removal when disabled on server"
23683
23684 test_270i() {
23685         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23686                 skip "Need MDS version at least 2.14.54"
23687
23688         mkdir $DIR/$tdir
23689         # DoM with plain layout
23690         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23691                 error "default plain layout with DoM must fail"
23692         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23693                 error "setstripe plain file layout with DoM must fail"
23694         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23695                 error "default DoM layout with bad striping must fail"
23696         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23697                 error "setstripe to DoM layout with bad striping must fail"
23698         return 0
23699 }
23700 run_test 270i "DoM: setting invalid DoM striping should fail"
23701
23702 test_271a() {
23703         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23704                 skip "Need MDS version at least 2.10.55"
23705
23706         local dom=$DIR/$tdir/dom
23707
23708         mkdir -p $DIR/$tdir
23709
23710         $LFS setstripe -E 1024K -L mdt $dom
23711
23712         lctl set_param -n mdc.*.stats=clear
23713         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23714         cat $dom > /dev/null
23715         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23716         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23717         ls $dom
23718         rm -f $dom
23719 }
23720 run_test 271a "DoM: data is cached for read after write"
23721
23722 test_271b() {
23723         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23724                 skip "Need MDS version at least 2.10.55"
23725
23726         local dom=$DIR/$tdir/dom
23727
23728         mkdir -p $DIR/$tdir
23729
23730         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23731
23732         lctl set_param -n mdc.*.stats=clear
23733         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23734         cancel_lru_locks mdc
23735         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23736         # second stat to check size is cached on client
23737         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23738         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23739         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23740         rm -f $dom
23741 }
23742 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23743
23744 test_271ba() {
23745         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23746                 skip "Need MDS version at least 2.10.55"
23747
23748         local dom=$DIR/$tdir/dom
23749
23750         mkdir -p $DIR/$tdir
23751
23752         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23753
23754         lctl set_param -n mdc.*.stats=clear
23755         lctl set_param -n osc.*.stats=clear
23756         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23757         cancel_lru_locks mdc
23758         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23759         # second stat to check size is cached on client
23760         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23761         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23762         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23763         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23764         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23765         rm -f $dom
23766 }
23767 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23768
23769
23770 get_mdc_stats() {
23771         local mdtidx=$1
23772         local param=$2
23773         local mdt=MDT$(printf %04x $mdtidx)
23774
23775         if [ -z $param ]; then
23776                 lctl get_param -n mdc.*$mdt*.stats
23777         else
23778                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23779         fi
23780 }
23781
23782 test_271c() {
23783         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23784                 skip "Need MDS version at least 2.10.55"
23785
23786         local dom=$DIR/$tdir/dom
23787
23788         mkdir -p $DIR/$tdir
23789
23790         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23791
23792         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23793         local facet=mds$((mdtidx + 1))
23794
23795         cancel_lru_locks mdc
23796         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23797         createmany -o $dom 1000
23798         lctl set_param -n mdc.*.stats=clear
23799         smalliomany -w $dom 1000 200
23800         get_mdc_stats $mdtidx
23801         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23802         # Each file has 1 open, 1 IO enqueues, total 2000
23803         # but now we have also +1 getxattr for security.capability, total 3000
23804         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23805         unlinkmany $dom 1000
23806
23807         cancel_lru_locks mdc
23808         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23809         createmany -o $dom 1000
23810         lctl set_param -n mdc.*.stats=clear
23811         smalliomany -w $dom 1000 200
23812         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23813         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23814         # for OPEN and IO lock.
23815         [ $((enq - enq_2)) -ge 1000 ] ||
23816                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23817         unlinkmany $dom 1000
23818         return 0
23819 }
23820 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23821
23822 cleanup_271def_tests() {
23823         trap 0
23824         rm -f $1
23825 }
23826
23827 test_271d() {
23828         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23829                 skip "Need MDS version at least 2.10.57"
23830
23831         local dom=$DIR/$tdir/dom
23832         local tmp=$TMP/$tfile
23833         trap "cleanup_271def_tests $tmp" EXIT
23834
23835         mkdir -p $DIR/$tdir
23836
23837         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23838
23839         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23840
23841         cancel_lru_locks mdc
23842         dd if=/dev/urandom of=$tmp bs=1000 count=1
23843         dd if=$tmp of=$dom bs=1000 count=1
23844         cancel_lru_locks mdc
23845
23846         cat /etc/hosts >> $tmp
23847         lctl set_param -n mdc.*.stats=clear
23848
23849         # append data to the same file it should update local page
23850         echo "Append to the same page"
23851         cat /etc/hosts >> $dom
23852         local num=$(get_mdc_stats $mdtidx ost_read)
23853         local ra=$(get_mdc_stats $mdtidx req_active)
23854         local rw=$(get_mdc_stats $mdtidx req_waittime)
23855
23856         [ -z $num ] || error "$num READ RPC occured"
23857         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23858         echo "... DONE"
23859
23860         # compare content
23861         cmp $tmp $dom || error "file miscompare"
23862
23863         cancel_lru_locks mdc
23864         lctl set_param -n mdc.*.stats=clear
23865
23866         echo "Open and read file"
23867         cat $dom > /dev/null
23868         local num=$(get_mdc_stats $mdtidx ost_read)
23869         local ra=$(get_mdc_stats $mdtidx req_active)
23870         local rw=$(get_mdc_stats $mdtidx req_waittime)
23871
23872         [ -z $num ] || error "$num READ RPC occured"
23873         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23874         echo "... DONE"
23875
23876         # compare content
23877         cmp $tmp $dom || error "file miscompare"
23878
23879         return 0
23880 }
23881 run_test 271d "DoM: read on open (1K file in reply buffer)"
23882
23883 test_271f() {
23884         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23885                 skip "Need MDS version at least 2.10.57"
23886
23887         local dom=$DIR/$tdir/dom
23888         local tmp=$TMP/$tfile
23889         trap "cleanup_271def_tests $tmp" EXIT
23890
23891         mkdir -p $DIR/$tdir
23892
23893         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23894
23895         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23896
23897         cancel_lru_locks mdc
23898         dd if=/dev/urandom of=$tmp bs=265000 count=1
23899         dd if=$tmp of=$dom bs=265000 count=1
23900         cancel_lru_locks mdc
23901         cat /etc/hosts >> $tmp
23902         lctl set_param -n mdc.*.stats=clear
23903
23904         echo "Append to the same page"
23905         cat /etc/hosts >> $dom
23906         local num=$(get_mdc_stats $mdtidx ost_read)
23907         local ra=$(get_mdc_stats $mdtidx req_active)
23908         local rw=$(get_mdc_stats $mdtidx req_waittime)
23909
23910         [ -z $num ] || error "$num READ RPC occured"
23911         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23912         echo "... DONE"
23913
23914         # compare content
23915         cmp $tmp $dom || error "file miscompare"
23916
23917         cancel_lru_locks mdc
23918         lctl set_param -n mdc.*.stats=clear
23919
23920         echo "Open and read file"
23921         cat $dom > /dev/null
23922         local num=$(get_mdc_stats $mdtidx ost_read)
23923         local ra=$(get_mdc_stats $mdtidx req_active)
23924         local rw=$(get_mdc_stats $mdtidx req_waittime)
23925
23926         [ -z $num ] && num=0
23927         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23928         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23929         echo "... DONE"
23930
23931         # compare content
23932         cmp $tmp $dom || error "file miscompare"
23933
23934         return 0
23935 }
23936 run_test 271f "DoM: read on open (200K file and read tail)"
23937
23938 test_271g() {
23939         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23940                 skip "Skipping due to old client or server version"
23941
23942         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23943         # to get layout
23944         $CHECKSTAT -t file $DIR1/$tfile
23945
23946         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23947         MULTIOP_PID=$!
23948         sleep 1
23949         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23950         $LCTL set_param fail_loc=0x80000314
23951         rm $DIR1/$tfile || error "Unlink fails"
23952         RC=$?
23953         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23954         [ $RC -eq 0 ] || error "Failed write to stale object"
23955 }
23956 run_test 271g "Discard DoM data vs client flush race"
23957
23958 test_272a() {
23959         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23960                 skip "Need MDS version at least 2.11.50"
23961
23962         local dom=$DIR/$tdir/dom
23963         mkdir -p $DIR/$tdir
23964
23965         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23966         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23967                 error "failed to write data into $dom"
23968         local old_md5=$(md5sum $dom)
23969
23970         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23971                 error "failed to migrate to the same DoM component"
23972
23973         local new_md5=$(md5sum $dom)
23974
23975         [ "$old_md5" == "$new_md5" ] ||
23976                 error "md5sum differ: $old_md5, $new_md5"
23977
23978         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23979                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23980 }
23981 run_test 272a "DoM migration: new layout with the same DOM component"
23982
23983 test_272b() {
23984         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23985                 skip "Need MDS version at least 2.11.50"
23986
23987         local dom=$DIR/$tdir/dom
23988         mkdir -p $DIR/$tdir
23989         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23990
23991         local mdtidx=$($LFS getstripe -m $dom)
23992         local mdtname=MDT$(printf %04x $mdtidx)
23993         local facet=mds$((mdtidx + 1))
23994
23995         local mdtfree1=$(do_facet $facet \
23996                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23997         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23998                 error "failed to write data into $dom"
23999         local old_md5=$(md5sum $dom)
24000         cancel_lru_locks mdc
24001         local mdtfree1=$(do_facet $facet \
24002                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24003
24004         $LFS migrate -c2 $dom ||
24005                 error "failed to migrate to the new composite layout"
24006         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24007                 error "MDT stripe was not removed"
24008
24009         cancel_lru_locks mdc
24010         local new_md5=$(md5sum $dom)
24011         [ "$old_md5" == "$new_md5" ] ||
24012                 error "$old_md5 != $new_md5"
24013
24014         # Skip free space checks with ZFS
24015         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24016                 local mdtfree2=$(do_facet $facet \
24017                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24018                 [ $mdtfree2 -gt $mdtfree1 ] ||
24019                         error "MDT space is not freed after migration"
24020         fi
24021         return 0
24022 }
24023 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
24024
24025 test_272c() {
24026         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24027                 skip "Need MDS version at least 2.11.50"
24028
24029         local dom=$DIR/$tdir/$tfile
24030         mkdir -p $DIR/$tdir
24031         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24032
24033         local mdtidx=$($LFS getstripe -m $dom)
24034         local mdtname=MDT$(printf %04x $mdtidx)
24035         local facet=mds$((mdtidx + 1))
24036
24037         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24038                 error "failed to write data into $dom"
24039         local old_md5=$(md5sum $dom)
24040         cancel_lru_locks mdc
24041         local mdtfree1=$(do_facet $facet \
24042                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24043
24044         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
24045                 error "failed to migrate to the new composite layout"
24046         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
24047                 error "MDT stripe was not removed"
24048
24049         cancel_lru_locks mdc
24050         local new_md5=$(md5sum $dom)
24051         [ "$old_md5" == "$new_md5" ] ||
24052                 error "$old_md5 != $new_md5"
24053
24054         # Skip free space checks with ZFS
24055         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24056                 local mdtfree2=$(do_facet $facet \
24057                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24058                 [ $mdtfree2 -gt $mdtfree1 ] ||
24059                         error "MDS space is not freed after migration"
24060         fi
24061         return 0
24062 }
24063 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
24064
24065 test_272d() {
24066         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24067                 skip "Need MDS version at least 2.12.55"
24068
24069         local dom=$DIR/$tdir/$tfile
24070         mkdir -p $DIR/$tdir
24071         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
24072
24073         local mdtidx=$($LFS getstripe -m $dom)
24074         local mdtname=MDT$(printf %04x $mdtidx)
24075         local facet=mds$((mdtidx + 1))
24076
24077         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24078                 error "failed to write data into $dom"
24079         local old_md5=$(md5sum $dom)
24080         cancel_lru_locks mdc
24081         local mdtfree1=$(do_facet $facet \
24082                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24083
24084         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
24085                 error "failed mirroring to the new composite layout"
24086         $LFS mirror resync $dom ||
24087                 error "failed mirror resync"
24088         $LFS mirror split --mirror-id 1 -d $dom ||
24089                 error "failed mirror split"
24090
24091         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
24092                 error "MDT stripe was not removed"
24093
24094         cancel_lru_locks mdc
24095         local new_md5=$(md5sum $dom)
24096         [ "$old_md5" == "$new_md5" ] ||
24097                 error "$old_md5 != $new_md5"
24098
24099         # Skip free space checks with ZFS
24100         if [ "$(facet_fstype $facet)" != "zfs" ]; then
24101                 local mdtfree2=$(do_facet $facet \
24102                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
24103                 [ $mdtfree2 -gt $mdtfree1 ] ||
24104                         error "MDS space is not freed after DOM mirror deletion"
24105         fi
24106         return 0
24107 }
24108 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
24109
24110 test_272e() {
24111         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24112                 skip "Need MDS version at least 2.12.55"
24113
24114         local dom=$DIR/$tdir/$tfile
24115         mkdir -p $DIR/$tdir
24116         $LFS setstripe -c 2 $dom
24117
24118         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24119                 error "failed to write data into $dom"
24120         local old_md5=$(md5sum $dom)
24121         cancel_lru_locks
24122
24123         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
24124                 error "failed mirroring to the DOM layout"
24125         $LFS mirror resync $dom ||
24126                 error "failed mirror resync"
24127         $LFS mirror split --mirror-id 1 -d $dom ||
24128                 error "failed mirror split"
24129
24130         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24131                 error "MDT stripe wasn't set"
24132
24133         cancel_lru_locks
24134         local new_md5=$(md5sum $dom)
24135         [ "$old_md5" == "$new_md5" ] ||
24136                 error "$old_md5 != $new_md5"
24137
24138         return 0
24139 }
24140 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24141
24142 test_272f() {
24143         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24144                 skip "Need MDS version at least 2.12.55"
24145
24146         local dom=$DIR/$tdir/$tfile
24147         mkdir -p $DIR/$tdir
24148         $LFS setstripe -c 2 $dom
24149
24150         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24151                 error "failed to write data into $dom"
24152         local old_md5=$(md5sum $dom)
24153         cancel_lru_locks
24154
24155         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24156                 error "failed migrating to the DOM file"
24157
24158         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24159                 error "MDT stripe wasn't set"
24160
24161         cancel_lru_locks
24162         local new_md5=$(md5sum $dom)
24163         [ "$old_md5" != "$new_md5" ] &&
24164                 error "$old_md5 != $new_md5"
24165
24166         return 0
24167 }
24168 run_test 272f "DoM migration: OST-striped file to DOM file"
24169
24170 test_273a() {
24171         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24172                 skip "Need MDS version at least 2.11.50"
24173
24174         # Layout swap cannot be done if either file has DOM component,
24175         # this will never be supported, migration should be used instead
24176
24177         local dom=$DIR/$tdir/$tfile
24178         mkdir -p $DIR/$tdir
24179
24180         $LFS setstripe -c2 ${dom}_plain
24181         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24182         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24183                 error "can swap layout with DoM component"
24184         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24185                 error "can swap layout with DoM component"
24186
24187         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24188         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24189                 error "can swap layout with DoM component"
24190         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24191                 error "can swap layout with DoM component"
24192         return 0
24193 }
24194 run_test 273a "DoM: layout swapping should fail with DOM"
24195
24196 test_273b() {
24197         mkdir -p $DIR/$tdir
24198         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24199
24200 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24201         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24202
24203         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24204 }
24205 run_test 273b "DoM: race writeback and object destroy"
24206
24207 test_273c() {
24208         mkdir -p $DIR/$tdir
24209         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24210
24211         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24212         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24213
24214         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24215 }
24216 run_test 273c "race writeback and object destroy"
24217
24218 test_275() {
24219         remote_ost_nodsh && skip "remote OST with nodsh"
24220         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24221                 skip "Need OST version >= 2.10.57"
24222
24223         local file=$DIR/$tfile
24224         local oss
24225
24226         oss=$(comma_list $(osts_nodes))
24227
24228         dd if=/dev/urandom of=$file bs=1M count=2 ||
24229                 error "failed to create a file"
24230         cancel_lru_locks osc
24231
24232         #lock 1
24233         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24234                 error "failed to read a file"
24235
24236 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24237         $LCTL set_param fail_loc=0x8000031f
24238
24239         cancel_lru_locks osc &
24240         sleep 1
24241
24242 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24243         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24244         #IO takes another lock, but matches the PENDING one
24245         #and places it to the IO RPC
24246         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24247                 error "failed to read a file with PENDING lock"
24248 }
24249 run_test 275 "Read on a canceled duplicate lock"
24250
24251 test_276() {
24252         remote_ost_nodsh && skip "remote OST with nodsh"
24253         local pid
24254
24255         do_facet ost1 "(while true; do \
24256                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24257                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24258         pid=$!
24259
24260         for LOOP in $(seq 20); do
24261                 stop ost1
24262                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24263         done
24264         kill -9 $pid
24265         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24266                 rm $TMP/sanity_276_pid"
24267 }
24268 run_test 276 "Race between mount and obd_statfs"
24269
24270 test_277() {
24271         $LCTL set_param ldlm.namespaces.*.lru_size=0
24272         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24273         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24274                         grep ^used_mb | awk '{print $2}')
24275         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24276         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24277                 oflag=direct conv=notrunc
24278         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24279                         grep ^used_mb | awk '{print $2}')
24280         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24281 }
24282 run_test 277 "Direct IO shall drop page cache"
24283
24284 test_278() {
24285         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24286         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24287         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24288                 skip "needs the same host for mdt1 mdt2" && return
24289
24290         local pid1
24291         local pid2
24292
24293 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24294         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24295         stop mds2 &
24296         pid2=$!
24297
24298         stop mds1
24299
24300         echo "Starting MDTs"
24301         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24302         wait $pid2
24303 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24304 #will return NULL
24305         do_facet mds2 $LCTL set_param fail_loc=0
24306
24307         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24308         wait_recovery_complete mds2
24309 }
24310 run_test 278 "Race starting MDS between MDTs stop/start"
24311
24312 test_280() {
24313         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24314                 skip "Need MGS version at least 2.13.52"
24315         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24316         combined_mgs_mds || skip "needs combined MGS/MDT"
24317
24318         umount_client $MOUNT
24319 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24320         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24321
24322         mount_client $MOUNT &
24323         sleep 1
24324         stop mgs || error "stop mgs failed"
24325         #for a race mgs would crash
24326         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24327         # make sure we unmount client before remounting
24328         wait
24329         umount_client $MOUNT
24330         mount_client $MOUNT || error "mount client failed"
24331 }
24332 run_test 280 "Race between MGS umount and client llog processing"
24333
24334 cleanup_test_300() {
24335         trap 0
24336         umask $SAVE_UMASK
24337 }
24338 test_striped_dir() {
24339         local mdt_index=$1
24340         local stripe_count
24341         local stripe_index
24342
24343         mkdir -p $DIR/$tdir
24344
24345         SAVE_UMASK=$(umask)
24346         trap cleanup_test_300 RETURN EXIT
24347
24348         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24349                                                 $DIR/$tdir/striped_dir ||
24350                 error "set striped dir error"
24351
24352         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24353         [ "$mode" = "755" ] || error "expect 755 got $mode"
24354
24355         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24356                 error "getdirstripe failed"
24357         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24358         if [ "$stripe_count" != "2" ]; then
24359                 error "1:stripe_count is $stripe_count, expect 2"
24360         fi
24361         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24362         if [ "$stripe_count" != "2" ]; then
24363                 error "2:stripe_count is $stripe_count, expect 2"
24364         fi
24365
24366         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24367         if [ "$stripe_index" != "$mdt_index" ]; then
24368                 error "stripe_index is $stripe_index, expect $mdt_index"
24369         fi
24370
24371         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24372                 error "nlink error after create striped dir"
24373
24374         mkdir $DIR/$tdir/striped_dir/a
24375         mkdir $DIR/$tdir/striped_dir/b
24376
24377         stat $DIR/$tdir/striped_dir/a ||
24378                 error "create dir under striped dir failed"
24379         stat $DIR/$tdir/striped_dir/b ||
24380                 error "create dir under striped dir failed"
24381
24382         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24383                 error "nlink error after mkdir"
24384
24385         rmdir $DIR/$tdir/striped_dir/a
24386         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24387                 error "nlink error after rmdir"
24388
24389         rmdir $DIR/$tdir/striped_dir/b
24390         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24391                 error "nlink error after rmdir"
24392
24393         chattr +i $DIR/$tdir/striped_dir
24394         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24395                 error "immutable flags not working under striped dir!"
24396         chattr -i $DIR/$tdir/striped_dir
24397
24398         rmdir $DIR/$tdir/striped_dir ||
24399                 error "rmdir striped dir error"
24400
24401         cleanup_test_300
24402
24403         true
24404 }
24405
24406 test_300a() {
24407         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24408                 skip "skipped for lustre < 2.7.0"
24409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24410         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24411
24412         test_striped_dir 0 || error "failed on striped dir on MDT0"
24413         test_striped_dir 1 || error "failed on striped dir on MDT0"
24414 }
24415 run_test 300a "basic striped dir sanity test"
24416
24417 test_300b() {
24418         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24419                 skip "skipped for lustre < 2.7.0"
24420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24422
24423         local i
24424         local mtime1
24425         local mtime2
24426         local mtime3
24427
24428         test_mkdir $DIR/$tdir || error "mkdir fail"
24429         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24430                 error "set striped dir error"
24431         for i in {0..9}; do
24432                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24433                 sleep 1
24434                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24435                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24436                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24437                 sleep 1
24438                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24439                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24440                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24441         done
24442         true
24443 }
24444 run_test 300b "check ctime/mtime for striped dir"
24445
24446 test_300c() {
24447         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24448                 skip "skipped for lustre < 2.7.0"
24449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24450         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24451
24452         local file_count
24453
24454         mkdir_on_mdt0 $DIR/$tdir
24455         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24456                 error "set striped dir error"
24457
24458         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24459                 error "chown striped dir failed"
24460
24461         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24462                 error "create 5k files failed"
24463
24464         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24465
24466         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24467
24468         rm -rf $DIR/$tdir
24469 }
24470 run_test 300c "chown && check ls under striped directory"
24471
24472 test_300d() {
24473         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24474                 skip "skipped for lustre < 2.7.0"
24475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24476         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24477
24478         local stripe_count
24479         local file
24480
24481         mkdir -p $DIR/$tdir
24482         $LFS setstripe -c 2 $DIR/$tdir
24483
24484         #local striped directory
24485         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24486                 error "set striped dir error"
24487         #look at the directories for debug purposes
24488         ls -l $DIR/$tdir
24489         $LFS getdirstripe $DIR/$tdir
24490         ls -l $DIR/$tdir/striped_dir
24491         $LFS getdirstripe $DIR/$tdir/striped_dir
24492         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24493                 error "create 10 files failed"
24494
24495         #remote striped directory
24496         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24497                 error "set striped dir error"
24498         #look at the directories for debug purposes
24499         ls -l $DIR/$tdir
24500         $LFS getdirstripe $DIR/$tdir
24501         ls -l $DIR/$tdir/remote_striped_dir
24502         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24503         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24504                 error "create 10 files failed"
24505
24506         for file in $(find $DIR/$tdir); do
24507                 stripe_count=$($LFS getstripe -c $file)
24508                 [ $stripe_count -eq 2 ] ||
24509                         error "wrong stripe $stripe_count for $file"
24510         done
24511
24512         rm -rf $DIR/$tdir
24513 }
24514 run_test 300d "check default stripe under striped directory"
24515
24516 test_300e() {
24517         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24518                 skip "Need MDS version at least 2.7.55"
24519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24521
24522         local stripe_count
24523         local file
24524
24525         mkdir -p $DIR/$tdir
24526
24527         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24528                 error "set striped dir error"
24529
24530         touch $DIR/$tdir/striped_dir/a
24531         touch $DIR/$tdir/striped_dir/b
24532         touch $DIR/$tdir/striped_dir/c
24533
24534         mkdir $DIR/$tdir/striped_dir/dir_a
24535         mkdir $DIR/$tdir/striped_dir/dir_b
24536         mkdir $DIR/$tdir/striped_dir/dir_c
24537
24538         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24539                 error "set striped adir under striped dir error"
24540
24541         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24542                 error "set striped bdir under striped dir error"
24543
24544         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24545                 error "set striped cdir under striped dir error"
24546
24547         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24548                 error "rename dir under striped dir fails"
24549
24550         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24551                 error "rename dir under different stripes fails"
24552
24553         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24554                 error "rename file under striped dir should succeed"
24555
24556         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24557                 error "rename dir under striped dir should succeed"
24558
24559         rm -rf $DIR/$tdir
24560 }
24561 run_test 300e "check rename under striped directory"
24562
24563 test_300f() {
24564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24565         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24566         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24567                 skip "Need MDS version at least 2.7.55"
24568
24569         local stripe_count
24570         local file
24571
24572         rm -rf $DIR/$tdir
24573         mkdir -p $DIR/$tdir
24574
24575         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24576                 error "set striped dir error"
24577
24578         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24579                 error "set striped dir error"
24580
24581         touch $DIR/$tdir/striped_dir/a
24582         mkdir $DIR/$tdir/striped_dir/dir_a
24583         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24584                 error "create striped dir under striped dir fails"
24585
24586         touch $DIR/$tdir/striped_dir1/b
24587         mkdir $DIR/$tdir/striped_dir1/dir_b
24588         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24589                 error "create striped dir under striped dir fails"
24590
24591         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24592                 error "rename dir under different striped dir should fail"
24593
24594         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24595                 error "rename striped dir under diff striped dir should fail"
24596
24597         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24598                 error "rename file under diff striped dirs fails"
24599
24600         rm -rf $DIR/$tdir
24601 }
24602 run_test 300f "check rename cross striped directory"
24603
24604 test_300_check_default_striped_dir()
24605 {
24606         local dirname=$1
24607         local default_count=$2
24608         local default_index=$3
24609         local stripe_count
24610         local stripe_index
24611         local dir_stripe_index
24612         local dir
24613
24614         echo "checking $dirname $default_count $default_index"
24615         $LFS setdirstripe -D -c $default_count -i $default_index \
24616                                 -H all_char $DIR/$tdir/$dirname ||
24617                 error "set default stripe on striped dir error"
24618         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24619         [ $stripe_count -eq $default_count ] ||
24620                 error "expect $default_count get $stripe_count for $dirname"
24621
24622         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24623         [ $stripe_index -eq $default_index ] ||
24624                 error "expect $default_index get $stripe_index for $dirname"
24625
24626         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24627                                                 error "create dirs failed"
24628
24629         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24630         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24631         for dir in $(find $DIR/$tdir/$dirname/*); do
24632                 stripe_count=$($LFS getdirstripe -c $dir)
24633                 (( $stripe_count == $default_count )) ||
24634                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24635                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24636                 error "stripe count $default_count != $stripe_count for $dir"
24637
24638                 stripe_index=$($LFS getdirstripe -i $dir)
24639                 [ $default_index -eq -1 ] ||
24640                         [ $stripe_index -eq $default_index ] ||
24641                         error "$stripe_index != $default_index for $dir"
24642
24643                 #check default stripe
24644                 stripe_count=$($LFS getdirstripe -D -c $dir)
24645                 [ $stripe_count -eq $default_count ] ||
24646                 error "default count $default_count != $stripe_count for $dir"
24647
24648                 stripe_index=$($LFS getdirstripe -D -i $dir)
24649                 [ $stripe_index -eq $default_index ] ||
24650                 error "default index $default_index != $stripe_index for $dir"
24651         done
24652         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24653 }
24654
24655 test_300g() {
24656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24657         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24658                 skip "Need MDS version at least 2.7.55"
24659
24660         local dir
24661         local stripe_count
24662         local stripe_index
24663
24664         mkdir_on_mdt0 $DIR/$tdir
24665         mkdir $DIR/$tdir/normal_dir
24666
24667         #Checking when client cache stripe index
24668         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24669         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24670                 error "create striped_dir failed"
24671
24672         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24673                 error "create dir0 fails"
24674         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24675         [ $stripe_index -eq 0 ] ||
24676                 error "dir0 expect index 0 got $stripe_index"
24677
24678         mkdir $DIR/$tdir/striped_dir/dir1 ||
24679                 error "create dir1 fails"
24680         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24681         [ $stripe_index -eq 1 ] ||
24682                 error "dir1 expect index 1 got $stripe_index"
24683
24684         #check default stripe count/stripe index
24685         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24686         test_300_check_default_striped_dir normal_dir 1 0
24687         test_300_check_default_striped_dir normal_dir -1 1
24688         test_300_check_default_striped_dir normal_dir 2 -1
24689
24690         #delete default stripe information
24691         echo "delete default stripeEA"
24692         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24693                 error "set default stripe on striped dir error"
24694
24695         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24696         for dir in $(find $DIR/$tdir/normal_dir/*); do
24697                 stripe_count=$($LFS getdirstripe -c $dir)
24698                 [ $stripe_count -eq 0 ] ||
24699                         error "expect 1 get $stripe_count for $dir"
24700         done
24701 }
24702 run_test 300g "check default striped directory for normal directory"
24703
24704 test_300h() {
24705         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24706         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24707                 skip "Need MDS version at least 2.7.55"
24708
24709         local dir
24710         local stripe_count
24711
24712         mkdir $DIR/$tdir
24713         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24714                 error "set striped dir error"
24715
24716         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24717         test_300_check_default_striped_dir striped_dir 1 0
24718         test_300_check_default_striped_dir striped_dir -1 1
24719         test_300_check_default_striped_dir striped_dir 2 -1
24720
24721         #delete default stripe information
24722         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24723                 error "set default stripe on striped dir error"
24724
24725         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24726         for dir in $(find $DIR/$tdir/striped_dir/*); do
24727                 stripe_count=$($LFS getdirstripe -c $dir)
24728                 [ $stripe_count -eq 0 ] ||
24729                         error "expect 1 get $stripe_count for $dir"
24730         done
24731 }
24732 run_test 300h "check default striped directory for striped directory"
24733
24734 test_300i() {
24735         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24736         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24737         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24738                 skip "Need MDS version at least 2.7.55"
24739
24740         local stripe_count
24741         local file
24742
24743         mkdir $DIR/$tdir
24744
24745         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24746                 error "set striped dir error"
24747
24748         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24749                 error "create files under striped dir failed"
24750
24751         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24752                 error "set striped hashdir error"
24753
24754         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24755                 error "create dir0 under hash dir failed"
24756         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24757                 error "create dir1 under hash dir failed"
24758         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24759                 error "create dir2 under hash dir failed"
24760
24761         # unfortunately, we need to umount to clear dir layout cache for now
24762         # once we fully implement dir layout, we can drop this
24763         umount_client $MOUNT || error "umount failed"
24764         mount_client $MOUNT || error "mount failed"
24765
24766         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24767         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24768         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24769
24770         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24771                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24772                         error "create crush2 dir $tdir/hashdir/d3 failed"
24773                 $LFS find -H crush2 $DIR/$tdir/hashdir
24774                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24775                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24776
24777                 # mkdir with an invalid hash type (hash=fail_val) from client
24778                 # should be replaced on MDS with a valid (default) hash type
24779                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24780                 $LCTL set_param fail_loc=0x1901 fail_val=99
24781                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24782
24783                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24784                 local expect=$(do_facet mds1 \
24785                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24786                 [[ $hash == $expect ]] ||
24787                         error "d99 hash '$hash' != expected hash '$expect'"
24788         fi
24789
24790         #set the stripe to be unknown hash type on read
24791         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24792         $LCTL set_param fail_loc=0x1901 fail_val=99
24793         for ((i = 0; i < 10; i++)); do
24794                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24795                         error "stat f-$i failed"
24796                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24797         done
24798
24799         touch $DIR/$tdir/striped_dir/f0 &&
24800                 error "create under striped dir with unknown hash should fail"
24801
24802         $LCTL set_param fail_loc=0
24803
24804         umount_client $MOUNT || error "umount failed"
24805         mount_client $MOUNT || error "mount failed"
24806
24807         return 0
24808 }
24809 run_test 300i "client handle unknown hash type striped directory"
24810
24811 test_300j() {
24812         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24814         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24815                 skip "Need MDS version at least 2.7.55"
24816
24817         local stripe_count
24818         local file
24819
24820         mkdir $DIR/$tdir
24821
24822         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24823         $LCTL set_param fail_loc=0x1702
24824         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24825                 error "set striped dir error"
24826
24827         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24828                 error "create files under striped dir failed"
24829
24830         $LCTL set_param fail_loc=0
24831
24832         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24833
24834         return 0
24835 }
24836 run_test 300j "test large update record"
24837
24838 test_300k() {
24839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24840         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24841         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24842                 skip "Need MDS version at least 2.7.55"
24843
24844         # this test needs a huge transaction
24845         local kb
24846         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24847              osd*.$FSNAME-MDT0000.kbytestotal")
24848         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24849
24850         local stripe_count
24851         local file
24852
24853         mkdir $DIR/$tdir
24854
24855         #define OBD_FAIL_LARGE_STRIPE   0x1703
24856         $LCTL set_param fail_loc=0x1703
24857         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24858                 error "set striped dir error"
24859         $LCTL set_param fail_loc=0
24860
24861         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24862                 error "getstripeddir fails"
24863         rm -rf $DIR/$tdir/striped_dir ||
24864                 error "unlink striped dir fails"
24865
24866         return 0
24867 }
24868 run_test 300k "test large striped directory"
24869
24870 test_300l() {
24871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24872         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24873         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24874                 skip "Need MDS version at least 2.7.55"
24875
24876         local stripe_index
24877
24878         test_mkdir -p $DIR/$tdir/striped_dir
24879         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24880                         error "chown $RUNAS_ID failed"
24881         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24882                 error "set default striped dir failed"
24883
24884         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24885         $LCTL set_param fail_loc=0x80000158
24886         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24887
24888         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24889         [ $stripe_index -eq 1 ] ||
24890                 error "expect 1 get $stripe_index for $dir"
24891 }
24892 run_test 300l "non-root user to create dir under striped dir with stale layout"
24893
24894 test_300m() {
24895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24896         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24897         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24898                 skip "Need MDS version at least 2.7.55"
24899
24900         mkdir -p $DIR/$tdir/striped_dir
24901         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24902                 error "set default stripes dir error"
24903
24904         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24905
24906         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24907         [ $stripe_count -eq 0 ] ||
24908                         error "expect 0 get $stripe_count for a"
24909
24910         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24911                 error "set default stripes dir error"
24912
24913         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24914
24915         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24916         [ $stripe_count -eq 0 ] ||
24917                         error "expect 0 get $stripe_count for b"
24918
24919         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24920                 error "set default stripes dir error"
24921
24922         mkdir $DIR/$tdir/striped_dir/c &&
24923                 error "default stripe_index is invalid, mkdir c should fails"
24924
24925         rm -rf $DIR/$tdir || error "rmdir fails"
24926 }
24927 run_test 300m "setstriped directory on single MDT FS"
24928
24929 cleanup_300n() {
24930         local list=$(comma_list $(mdts_nodes))
24931
24932         trap 0
24933         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24934 }
24935
24936 test_300n() {
24937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24938         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24939         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24940                 skip "Need MDS version at least 2.7.55"
24941         remote_mds_nodsh && skip "remote MDS with nodsh"
24942
24943         local stripe_index
24944         local list=$(comma_list $(mdts_nodes))
24945
24946         trap cleanup_300n RETURN EXIT
24947         mkdir -p $DIR/$tdir
24948         chmod 777 $DIR/$tdir
24949         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24950                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24951                 error "create striped dir succeeds with gid=0"
24952
24953         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24954         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24955                 error "create striped dir fails with gid=-1"
24956
24957         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24958         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24959                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24960                 error "set default striped dir succeeds with gid=0"
24961
24962
24963         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24964         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24965                 error "set default striped dir fails with gid=-1"
24966
24967
24968         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24969         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24970                                         error "create test_dir fails"
24971         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24972                                         error "create test_dir1 fails"
24973         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24974                                         error "create test_dir2 fails"
24975         cleanup_300n
24976 }
24977 run_test 300n "non-root user to create dir under striped dir with default EA"
24978
24979 test_300o() {
24980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24981         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24982         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24983                 skip "Need MDS version at least 2.7.55"
24984
24985         local numfree1
24986         local numfree2
24987
24988         mkdir -p $DIR/$tdir
24989
24990         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24991         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24992         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24993                 skip "not enough free inodes $numfree1 $numfree2"
24994         fi
24995
24996         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24997         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24998         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24999                 skip "not enough free space $numfree1 $numfree2"
25000         fi
25001
25002         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
25003                 error "setdirstripe fails"
25004
25005         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
25006                 error "create dirs fails"
25007
25008         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
25009         ls $DIR/$tdir/striped_dir > /dev/null ||
25010                 error "ls striped dir fails"
25011         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
25012                 error "unlink big striped dir fails"
25013 }
25014 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
25015
25016 test_300p() {
25017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25018         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25019         remote_mds_nodsh && skip "remote MDS with nodsh"
25020
25021         mkdir_on_mdt0 $DIR/$tdir
25022
25023         #define OBD_FAIL_OUT_ENOSPC     0x1704
25024         do_facet mds2 lctl set_param fail_loc=0x80001704
25025         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
25026                  && error "create striped directory should fail"
25027
25028         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
25029
25030         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
25031         true
25032 }
25033 run_test 300p "create striped directory without space"
25034
25035 test_300q() {
25036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25037         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
25038
25039         local fd=$(free_fd)
25040         local cmd="exec $fd<$tdir"
25041         cd $DIR
25042         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
25043         eval $cmd
25044         cmd="exec $fd<&-"
25045         trap "eval $cmd" EXIT
25046         cd $tdir || error "cd $tdir fails"
25047         rmdir  ../$tdir || error "rmdir $tdir fails"
25048         mkdir local_dir && error "create dir succeeds"
25049         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
25050         eval $cmd
25051         return 0
25052 }
25053 run_test 300q "create remote directory under orphan directory"
25054
25055 test_300r() {
25056         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25057                 skip "Need MDS version at least 2.7.55" && return
25058         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25059
25060         mkdir $DIR/$tdir
25061
25062         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
25063                 error "set striped dir error"
25064
25065         $LFS getdirstripe $DIR/$tdir/striped_dir ||
25066                 error "getstripeddir fails"
25067
25068         local stripe_count
25069         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
25070                       awk '/lmv_stripe_count:/ { print $2 }')
25071
25072         [ $MDSCOUNT -ne $stripe_count ] &&
25073                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
25074
25075         rm -rf $DIR/$tdir/striped_dir ||
25076                 error "unlink striped dir fails"
25077 }
25078 run_test 300r "test -1 striped directory"
25079
25080 test_300s_helper() {
25081         local count=$1
25082
25083         local stripe_dir=$DIR/$tdir/striped_dir.$count
25084
25085         $LFS mkdir -c $count $stripe_dir ||
25086                 error "lfs mkdir -c error"
25087
25088         $LFS getdirstripe $stripe_dir ||
25089                 error "lfs getdirstripe fails"
25090
25091         local stripe_count
25092         stripe_count=$($LFS getdirstripe $stripe_dir |
25093                       awk '/lmv_stripe_count:/ { print $2 }')
25094
25095         [ $count -ne $stripe_count ] &&
25096                 error_noexit "bad stripe count $stripe_count expected $count"
25097
25098         local dupe_stripes
25099         dupe_stripes=$($LFS getdirstripe $stripe_dir |
25100                 awk '/0x/ {count[$1] += 1}; END {
25101                         for (idx in count) {
25102                                 if (count[idx]>1) {
25103                                         print "index " idx " count " count[idx]
25104                                 }
25105                         }
25106                 }')
25107
25108         if [[ -n "$dupe_stripes" ]] ; then
25109                 lfs getdirstripe $stripe_dir
25110                 error_noexit "Dupe MDT above: $dupe_stripes "
25111         fi
25112
25113         rm -rf $stripe_dir ||
25114                 error_noexit "unlink $stripe_dir fails"
25115 }
25116
25117 test_300s() {
25118         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
25119                 skip "Need MDS version at least 2.7.55" && return
25120         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
25121
25122         mkdir $DIR/$tdir
25123         for count in $(seq 2 $MDSCOUNT); do
25124                 test_300s_helper $count
25125         done
25126 }
25127 run_test 300s "test lfs mkdir -c without -i"
25128
25129 test_300t() {
25130         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25131                 skip "need MDS 2.14.55 or later"
25132         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25133
25134         local testdir="$DIR/$tdir/striped_dir"
25135         local dir1=$testdir/dir1
25136         local dir2=$testdir/dir2
25137
25138         mkdir -p $testdir
25139
25140         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25141                 error "failed to set default stripe count for $testdir"
25142
25143         mkdir $dir1
25144         local stripe_count=$($LFS getdirstripe -c $dir1)
25145
25146         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25147
25148         local max_count=$((MDSCOUNT - 1))
25149         local mdts=$(comma_list $(mdts_nodes))
25150
25151         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25152         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25153
25154         mkdir $dir2
25155         stripe_count=$($LFS getdirstripe -c $dir2)
25156
25157         (( $stripe_count == $max_count )) || error "wrong stripe count"
25158 }
25159 run_test 300t "test max_mdt_stripecount"
25160
25161 prepare_remote_file() {
25162         mkdir $DIR/$tdir/src_dir ||
25163                 error "create remote source failed"
25164
25165         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25166                  error "cp to remote source failed"
25167         touch $DIR/$tdir/src_dir/a
25168
25169         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25170                 error "create remote target dir failed"
25171
25172         touch $DIR/$tdir/tgt_dir/b
25173
25174         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25175                 error "rename dir cross MDT failed!"
25176
25177         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25178                 error "src_child still exists after rename"
25179
25180         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25181                 error "missing file(a) after rename"
25182
25183         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25184                 error "diff after rename"
25185 }
25186
25187 test_310a() {
25188         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25190
25191         local remote_file=$DIR/$tdir/tgt_dir/b
25192
25193         mkdir -p $DIR/$tdir
25194
25195         prepare_remote_file || error "prepare remote file failed"
25196
25197         #open-unlink file
25198         $OPENUNLINK $remote_file $remote_file ||
25199                 error "openunlink $remote_file failed"
25200         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25201 }
25202 run_test 310a "open unlink remote file"
25203
25204 test_310b() {
25205         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25207
25208         local remote_file=$DIR/$tdir/tgt_dir/b
25209
25210         mkdir -p $DIR/$tdir
25211
25212         prepare_remote_file || error "prepare remote file failed"
25213
25214         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25215         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25216         $CHECKSTAT -t file $remote_file || error "check file failed"
25217 }
25218 run_test 310b "unlink remote file with multiple links while open"
25219
25220 test_310c() {
25221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25222         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25223
25224         local remote_file=$DIR/$tdir/tgt_dir/b
25225
25226         mkdir -p $DIR/$tdir
25227
25228         prepare_remote_file || error "prepare remote file failed"
25229
25230         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25231         multiop_bg_pause $remote_file O_uc ||
25232                         error "mulitop failed for remote file"
25233         MULTIPID=$!
25234         $MULTIOP $DIR/$tfile Ouc
25235         kill -USR1 $MULTIPID
25236         wait $MULTIPID
25237 }
25238 run_test 310c "open-unlink remote file with multiple links"
25239
25240 #LU-4825
25241 test_311() {
25242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25243         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25244         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25245                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25246         remote_mds_nodsh && skip "remote MDS with nodsh"
25247
25248         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25249         local mdts=$(comma_list $(mdts_nodes))
25250
25251         mkdir -p $DIR/$tdir
25252         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25253         createmany -o $DIR/$tdir/$tfile. 1000
25254
25255         # statfs data is not real time, let's just calculate it
25256         old_iused=$((old_iused + 1000))
25257
25258         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25259                         osp.*OST0000*MDT0000.create_count")
25260         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25261                                 osp.*OST0000*MDT0000.max_create_count")
25262         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25263
25264         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25265         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25266         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25267
25268         unlinkmany $DIR/$tdir/$tfile. 1000
25269
25270         do_nodes $mdts "$LCTL set_param -n \
25271                         osp.*OST0000*.max_create_count=$max_count"
25272         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25273                 do_nodes $mdts "$LCTL set_param -n \
25274                                 osp.*OST0000*.create_count=$count"
25275         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25276                         grep "=0" && error "create_count is zero"
25277
25278         local new_iused
25279         for i in $(seq 120); do
25280                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25281                 # system may be too busy to destroy all objs in time, use
25282                 # a somewhat small value to not fail autotest
25283                 [ $((old_iused - new_iused)) -gt 400 ] && break
25284                 sleep 1
25285         done
25286
25287         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25288         [ $((old_iused - new_iused)) -gt 400 ] ||
25289                 error "objs not destroyed after unlink"
25290 }
25291 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25292
25293 zfs_get_objid()
25294 {
25295         local ost=$1
25296         local tf=$2
25297         local fid=($($LFS getstripe $tf | grep 0x))
25298         local seq=${fid[3]#0x}
25299         local objid=${fid[1]}
25300
25301         local vdevdir=$(dirname $(facet_vdevice $ost))
25302         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25303         local zfs_zapid=$(do_facet $ost $cmd |
25304                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25305                           awk '/Object/{getline; print $1}')
25306         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25307                           awk "/$objid = /"'{printf $3}')
25308
25309         echo $zfs_objid
25310 }
25311
25312 zfs_object_blksz() {
25313         local ost=$1
25314         local objid=$2
25315
25316         local vdevdir=$(dirname $(facet_vdevice $ost))
25317         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25318         local blksz=$(do_facet $ost $cmd $objid |
25319                       awk '/dblk/{getline; printf $4}')
25320
25321         case "${blksz: -1}" in
25322                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25323                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25324                 *) ;;
25325         esac
25326
25327         echo $blksz
25328 }
25329
25330 test_312() { # LU-4856
25331         remote_ost_nodsh && skip "remote OST with nodsh"
25332         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25333
25334         local max_blksz=$(do_facet ost1 \
25335                           $ZFS get -p recordsize $(facet_device ost1) |
25336                           awk '!/VALUE/{print $3}')
25337         local tf=$DIR/$tfile
25338
25339         $LFS setstripe -c1 $tf
25340         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25341
25342         # Get ZFS object id
25343         local zfs_objid=$(zfs_get_objid $facet $tf)
25344         # block size change by sequential overwrite
25345         local bs
25346
25347         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25348                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25349
25350                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25351                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25352         done
25353         rm -f $tf
25354
25355         $LFS setstripe -c1 $tf
25356         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25357
25358         # block size change by sequential append write
25359         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25360         zfs_objid=$(zfs_get_objid $facet $tf)
25361         local count
25362
25363         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25364                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25365                         oflag=sync conv=notrunc
25366
25367                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25368                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25369                         error "blksz error, actual $blksz, " \
25370                                 "expected: 2 * $count * $PAGE_SIZE"
25371         done
25372         rm -f $tf
25373
25374         # random write
25375         $LFS setstripe -c1 $tf
25376         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25377         zfs_objid=$(zfs_get_objid $facet $tf)
25378
25379         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25380         blksz=$(zfs_object_blksz $facet $zfs_objid)
25381         (( blksz == PAGE_SIZE )) ||
25382                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25383
25384         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25385         blksz=$(zfs_object_blksz $facet $zfs_objid)
25386         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25387
25388         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25389         blksz=$(zfs_object_blksz $facet $zfs_objid)
25390         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25391 }
25392 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25393
25394 test_313() {
25395         remote_ost_nodsh && skip "remote OST with nodsh"
25396
25397         local file=$DIR/$tfile
25398
25399         rm -f $file
25400         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25401
25402         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25403         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25404         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25405                 error "write should failed"
25406         do_facet ost1 "$LCTL set_param fail_loc=0"
25407         rm -f $file
25408 }
25409 run_test 313 "io should fail after last_rcvd update fail"
25410
25411 test_314() {
25412         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25413
25414         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25415         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25416         rm -f $DIR/$tfile
25417         wait_delete_completed
25418         do_facet ost1 "$LCTL set_param fail_loc=0"
25419 }
25420 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25421
25422 test_315() { # LU-618
25423         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25424
25425         local file=$DIR/$tfile
25426         rm -f $file
25427
25428         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25429                 error "multiop file write failed"
25430         $MULTIOP $file oO_RDONLY:r4063232_c &
25431         PID=$!
25432
25433         sleep 2
25434
25435         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25436         kill -USR1 $PID
25437
25438         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25439         rm -f $file
25440 }
25441 run_test 315 "read should be accounted"
25442
25443 test_316() {
25444         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25445         large_xattr_enabled || skip "ea_inode feature disabled"
25446
25447         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25448         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25449         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25450         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25451
25452         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25453 }
25454 run_test 316 "lfs migrate of file with large_xattr enabled"
25455
25456 test_317() {
25457         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25458                 skip "Need MDS version at least 2.11.53"
25459         if [ "$ost1_FSTYPE" == "zfs" ]; then
25460                 skip "LU-10370: no implementation for ZFS"
25461         fi
25462
25463         local trunc_sz
25464         local grant_blk_size
25465
25466         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25467                         awk '/grant_block_size:/ { print $2; exit; }')
25468         #
25469         # Create File of size 5M. Truncate it to below size's and verify
25470         # blocks count.
25471         #
25472         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25473                 error "Create file $DIR/$tfile failed"
25474         stack_trap "rm -f $DIR/$tfile" EXIT
25475
25476         for trunc_sz in 2097152 4097 4000 509 0; do
25477                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25478                         error "truncate $tfile to $trunc_sz failed"
25479                 local sz=$(stat --format=%s $DIR/$tfile)
25480                 local blk=$(stat --format=%b $DIR/$tfile)
25481                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25482                                      grant_blk_size) * 8))
25483
25484                 if [[ $blk -ne $trunc_blk ]]; then
25485                         $(which stat) $DIR/$tfile
25486                         error "Expected Block $trunc_blk got $blk for $tfile"
25487                 fi
25488
25489                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25490                         error "Expected Size $trunc_sz got $sz for $tfile"
25491         done
25492
25493         #
25494         # sparse file test
25495         # Create file with a hole and write actual 65536 bytes which aligned
25496         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25497         #
25498         local bs=65536
25499         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25500                 error "Create file : $DIR/$tfile"
25501
25502         #
25503         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25504         # blocks. The block count must drop to 8.
25505         #
25506         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25507                 ((bs - grant_blk_size) + 1)))
25508         $TRUNCATE $DIR/$tfile $trunc_sz ||
25509                 error "truncate $tfile to $trunc_sz failed"
25510
25511         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25512         sz=$(stat --format=%s $DIR/$tfile)
25513         blk=$(stat --format=%b $DIR/$tfile)
25514
25515         if [[ $blk -ne $trunc_bsz ]]; then
25516                 $(which stat) $DIR/$tfile
25517                 error "Expected Block $trunc_bsz got $blk for $tfile"
25518         fi
25519
25520         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25521                 error "Expected Size $trunc_sz got $sz for $tfile"
25522 }
25523 run_test 317 "Verify blocks get correctly update after truncate"
25524
25525 test_318() {
25526         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25527         local old_max_active=$($LCTL get_param -n \
25528                             ${llite_name}.max_read_ahead_async_active \
25529                             2>/dev/null)
25530
25531         $LCTL set_param llite.*.max_read_ahead_async_active=256
25532         local max_active=$($LCTL get_param -n \
25533                            ${llite_name}.max_read_ahead_async_active \
25534                            2>/dev/null)
25535         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25536
25537         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25538                 error "set max_read_ahead_async_active should succeed"
25539
25540         $LCTL set_param llite.*.max_read_ahead_async_active=512
25541         max_active=$($LCTL get_param -n \
25542                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25543         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25544
25545         # restore @max_active
25546         [ $old_max_active -ne 0 ] && $LCTL set_param \
25547                 llite.*.max_read_ahead_async_active=$old_max_active
25548
25549         local old_threshold=$($LCTL get_param -n \
25550                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25551         local max_per_file_mb=$($LCTL get_param -n \
25552                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25553
25554         local invalid=$(($max_per_file_mb + 1))
25555         $LCTL set_param \
25556                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25557                         && error "set $invalid should fail"
25558
25559         local valid=$(($invalid - 1))
25560         $LCTL set_param \
25561                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25562                         error "set $valid should succeed"
25563         local threshold=$($LCTL get_param -n \
25564                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25565         [ $threshold -eq $valid ] || error \
25566                 "expect threshold $valid got $threshold"
25567         $LCTL set_param \
25568                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25569 }
25570 run_test 318 "Verify async readahead tunables"
25571
25572 test_319() {
25573         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25574
25575         local before=$(date +%s)
25576         local evict
25577         local mdir=$DIR/$tdir
25578         local file=$mdir/xxx
25579
25580         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25581         touch $file
25582
25583 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25584         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25585         $LFS migrate -m1 $mdir &
25586
25587         sleep 1
25588         dd if=$file of=/dev/null
25589         wait
25590         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25591           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25592
25593         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25594 }
25595 run_test 319 "lost lease lock on migrate error"
25596
25597 test_398a() { # LU-4198
25598         local ost1_imp=$(get_osc_import_name client ost1)
25599         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25600                          cut -d'.' -f2)
25601
25602         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25603         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25604
25605         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25606         # request a new lock on client
25607         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25608
25609         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25610         #local lock_count=$($LCTL get_param -n \
25611         #                  ldlm.namespaces.$imp_name.lru_size)
25612         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25613
25614         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25615
25616         # no lock cached, should use lockless DIO and not enqueue new lock
25617         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25618                 conv=notrunc ||
25619                 error "dio write failed"
25620         lock_count=$($LCTL get_param -n \
25621                      ldlm.namespaces.$imp_name.lru_size)
25622         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25623
25624         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25625
25626         # no lock cached, should use locked DIO append
25627         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25628                 conv=notrunc || error "DIO append failed"
25629         lock_count=$($LCTL get_param -n \
25630                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25631         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25632 }
25633 run_test 398a "direct IO should cancel lock otherwise lockless"
25634
25635 test_398b() { # LU-4198
25636         local before=$(date +%s)
25637         local njobs=4
25638         local size=48
25639
25640         which fio || skip_env "no fio installed"
25641         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25642         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25643
25644         # Single page, multiple pages, stripe size, 4*stripe size
25645         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25646                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25647                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25648                         --numjobs=$njobs --fallocate=none \
25649                         --iodepth=16 --allow_file_create=0 \
25650                         --size=$((size/njobs))M \
25651                         --filename=$DIR/$tfile &
25652                 bg_pid=$!
25653
25654                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25655                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25656                         --numjobs=$njobs --fallocate=none \
25657                         --iodepth=16 --allow_file_create=0 \
25658                         --size=$((size/njobs))M \
25659                         --filename=$DIR/$tfile || true
25660                 wait $bg_pid
25661         done
25662
25663         evict=$(do_facet client $LCTL get_param \
25664                 osc.$FSNAME-OST*-osc-*/state |
25665             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25666
25667         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25668                 (do_facet client $LCTL get_param \
25669                         osc.$FSNAME-OST*-osc-*/state;
25670                     error "eviction happened: $evict before:$before")
25671
25672         rm -f $DIR/$tfile
25673 }
25674 run_test 398b "DIO and buffer IO race"
25675
25676 test_398c() { # LU-4198
25677         local ost1_imp=$(get_osc_import_name client ost1)
25678         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25679                          cut -d'.' -f2)
25680
25681         which fio || skip_env "no fio installed"
25682
25683         saved_debug=$($LCTL get_param -n debug)
25684         $LCTL set_param debug=0
25685
25686         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25687         ((size /= 1024)) # by megabytes
25688         ((size /= 2)) # write half of the OST at most
25689         [ $size -gt 40 ] && size=40 #reduce test time anyway
25690
25691         $LFS setstripe -c 1 $DIR/$tfile
25692
25693         # it seems like ldiskfs reserves more space than necessary if the
25694         # writing blocks are not mapped, so it extends the file firstly
25695         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25696         cancel_lru_locks osc
25697
25698         # clear and verify rpc_stats later
25699         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25700
25701         local njobs=4
25702         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25703         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25704                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25705                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25706                 --filename=$DIR/$tfile
25707         [ $? -eq 0 ] || error "fio write error"
25708
25709         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25710                 error "Locks were requested while doing AIO"
25711
25712         # get the percentage of 1-page I/O
25713         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25714                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25715                 awk '{print $7}')
25716         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25717
25718         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25719         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25720                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25721                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25722                 --filename=$DIR/$tfile
25723         [ $? -eq 0 ] || error "fio mixed read write error"
25724
25725         echo "AIO with large block size ${size}M"
25726         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25727                 --numjobs=1 --fallocate=none --ioengine=libaio \
25728                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25729                 --filename=$DIR/$tfile
25730         [ $? -eq 0 ] || error "fio large block size failed"
25731
25732         rm -f $DIR/$tfile
25733         $LCTL set_param debug="$saved_debug"
25734 }
25735 run_test 398c "run fio to test AIO"
25736
25737 test_398d() { #  LU-13846
25738         which aiocp || skip_env "no aiocp installed"
25739         local aio_file=$DIR/$tfile.aio
25740
25741         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25742
25743         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25744         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25745         stack_trap "rm -f $DIR/$tfile $aio_file"
25746
25747         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25748
25749         # make sure we don't crash and fail properly
25750         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25751                 error "aio not aligned with PAGE SIZE should fail"
25752
25753         rm -f $DIR/$tfile $aio_file
25754 }
25755 run_test 398d "run aiocp to verify block size > stripe size"
25756
25757 test_398e() {
25758         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25759         touch $DIR/$tfile.new
25760         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25761 }
25762 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25763
25764 test_398f() { #  LU-14687
25765         which aiocp || skip_env "no aiocp installed"
25766         local aio_file=$DIR/$tfile.aio
25767
25768         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25769
25770         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25771         stack_trap "rm -f $DIR/$tfile $aio_file"
25772
25773         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25774         $LCTL set_param fail_loc=0x1418
25775         # make sure we don't crash and fail properly
25776         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25777                 error "aio with page allocation failure succeeded"
25778         $LCTL set_param fail_loc=0
25779         diff $DIR/$tfile $aio_file
25780         [[ $? != 0 ]] || error "no diff after failed aiocp"
25781 }
25782 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25783
25784 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25785 # stripe and i/o size must be > stripe size
25786 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25787 # single RPC in flight.  This test shows async DIO submission is working by
25788 # showing multiple RPCs in flight.
25789 test_398g() { #  LU-13798
25790         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25791
25792         # We need to do some i/o first to acquire enough grant to put our RPCs
25793         # in flight; otherwise a new connection may not have enough grant
25794         # available
25795         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25796                 error "parallel dio failed"
25797         stack_trap "rm -f $DIR/$tfile"
25798
25799         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25800         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25801         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25802         stack_trap "$LCTL set_param -n $pages_per_rpc"
25803
25804         # Recreate file so it's empty
25805         rm -f $DIR/$tfile
25806         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25807         #Pause rpc completion to guarantee we see multiple rpcs in flight
25808         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25809         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25810         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25811
25812         # Clear rpc stats
25813         $LCTL set_param osc.*.rpc_stats=c
25814
25815         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25816                 error "parallel dio failed"
25817         stack_trap "rm -f $DIR/$tfile"
25818
25819         $LCTL get_param osc.*-OST0000-*.rpc_stats
25820         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25821                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25822                 grep "8:" | awk '{print $8}')
25823         # We look at the "8 rpcs in flight" field, and verify A) it is present
25824         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25825         # as expected for an 8M DIO to a file with 1M stripes.
25826         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25827
25828         # Verify turning off parallel dio works as expected
25829         # Clear rpc stats
25830         $LCTL set_param osc.*.rpc_stats=c
25831         $LCTL set_param llite.*.parallel_dio=0
25832         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25833
25834         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25835                 error "dio with parallel dio disabled failed"
25836
25837         # Ideally, we would see only one RPC in flight here, but there is an
25838         # unavoidable race between i/o completion and RPC in flight counting,
25839         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25840         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25841         # So instead we just verify it's always < 8.
25842         $LCTL get_param osc.*-OST0000-*.rpc_stats
25843         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25844                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25845                 grep '^$' -B1 | grep . | awk '{print $1}')
25846         [ $ret != "8:" ] ||
25847                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25848 }
25849 run_test 398g "verify parallel dio async RPC submission"
25850
25851 test_398h() { #  LU-13798
25852         local dio_file=$DIR/$tfile.dio
25853
25854         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25855
25856         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25857         stack_trap "rm -f $DIR/$tfile $dio_file"
25858
25859         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25860                 error "parallel dio failed"
25861         diff $DIR/$tfile $dio_file
25862         [[ $? == 0 ]] || error "file diff after aiocp"
25863 }
25864 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25865
25866 test_398i() { #  LU-13798
25867         local dio_file=$DIR/$tfile.dio
25868
25869         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25870
25871         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25872         stack_trap "rm -f $DIR/$tfile $dio_file"
25873
25874         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25875         $LCTL set_param fail_loc=0x1418
25876         # make sure we don't crash and fail properly
25877         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25878                 error "parallel dio page allocation failure succeeded"
25879         diff $DIR/$tfile $dio_file
25880         [[ $? != 0 ]] || error "no diff after failed aiocp"
25881 }
25882 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25883
25884 test_398j() { #  LU-13798
25885         # Stripe size > RPC size but less than i/o size tests split across
25886         # stripes and RPCs for individual i/o op
25887         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25888
25889         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25890         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25891         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25892         stack_trap "$LCTL set_param -n $pages_per_rpc"
25893
25894         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25895                 error "parallel dio write failed"
25896         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25897
25898         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25899                 error "parallel dio read failed"
25900         diff $DIR/$tfile $DIR/$tfile.2
25901         [[ $? == 0 ]] || error "file diff after parallel dio read"
25902 }
25903 run_test 398j "test parallel dio where stripe size > rpc_size"
25904
25905 test_398k() { #  LU-13798
25906         wait_delete_completed
25907         wait_mds_ost_sync
25908
25909         # 4 stripe file; we will cause out of space on OST0
25910         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25911
25912         # Fill OST0 (if it's not too large)
25913         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25914                    head -n1)
25915         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25916                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25917         fi
25918         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25919         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25920                 error "dd should fill OST0"
25921         stack_trap "rm -f $DIR/$tfile.1"
25922
25923         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25924         err=$?
25925
25926         ls -la $DIR/$tfile
25927         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25928                 error "file is not 0 bytes in size"
25929
25930         # dd above should not succeed, but don't error until here so we can
25931         # get debug info above
25932         [[ $err != 0 ]] ||
25933                 error "parallel dio write with enospc succeeded"
25934         stack_trap "rm -f $DIR/$tfile"
25935 }
25936 run_test 398k "test enospc on first stripe"
25937
25938 test_398l() { #  LU-13798
25939         wait_delete_completed
25940         wait_mds_ost_sync
25941
25942         # 4 stripe file; we will cause out of space on OST0
25943         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25944         # happens on the second i/o chunk we issue
25945         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25946
25947         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25948         stack_trap "rm -f $DIR/$tfile"
25949
25950         # Fill OST0 (if it's not too large)
25951         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25952                    head -n1)
25953         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25954                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25955         fi
25956         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25957         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25958                 error "dd should fill OST0"
25959         stack_trap "rm -f $DIR/$tfile.1"
25960
25961         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25962         err=$?
25963         stack_trap "rm -f $DIR/$tfile.2"
25964
25965         # Check that short write completed as expected
25966         ls -la $DIR/$tfile.2
25967         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25968                 error "file is not 1M in size"
25969
25970         # dd above should not succeed, but don't error until here so we can
25971         # get debug info above
25972         [[ $err != 0 ]] ||
25973                 error "parallel dio write with enospc succeeded"
25974
25975         # Truncate source file to same length as output file and diff them
25976         $TRUNCATE $DIR/$tfile 1048576
25977         diff $DIR/$tfile $DIR/$tfile.2
25978         [[ $? == 0 ]] || error "data incorrect after short write"
25979 }
25980 run_test 398l "test enospc on intermediate stripe/RPC"
25981
25982 test_398m() { #  LU-13798
25983         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25984
25985         # Set up failure on OST0, the first stripe:
25986         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25987         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25988         # OST0 is on ost1, OST1 is on ost2.
25989         # So this fail_val specifies OST0
25990         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25991         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25992
25993         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25994                 error "parallel dio write with failure on first stripe succeeded"
25995         stack_trap "rm -f $DIR/$tfile"
25996         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25997
25998         # Place data in file for read
25999         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26000                 error "parallel dio write failed"
26001
26002         # Fail read on OST0, first stripe
26003         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26004         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
26005         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26006                 error "parallel dio read with error on first stripe succeeded"
26007         rm -f $DIR/$tfile.2
26008         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
26009
26010         # Switch to testing on OST1, second stripe
26011         # Clear file contents, maintain striping
26012         echo > $DIR/$tfile
26013         # Set up failure on OST1, second stripe:
26014         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
26015         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
26016
26017         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
26018                 error "parallel dio write with failure on second stripe succeeded"
26019         stack_trap "rm -f $DIR/$tfile"
26020         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26021
26022         # Place data in file for read
26023         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
26024                 error "parallel dio write failed"
26025
26026         # Fail read on OST1, second stripe
26027         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
26028         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
26029         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
26030                 error "parallel dio read with error on second stripe succeeded"
26031         rm -f $DIR/$tfile.2
26032         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
26033 }
26034 run_test 398m "test RPC failures with parallel dio"
26035
26036 # Parallel submission of DIO should not cause problems for append, but it's
26037 # important to verify.
26038 test_398n() { #  LU-13798
26039         $LFS setstripe -C 2 -S 1M $DIR/$tfile
26040
26041         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
26042                 error "dd to create source file failed"
26043         stack_trap "rm -f $DIR/$tfile"
26044
26045         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
26046                 error "parallel dio write with failure on second stripe succeeded"
26047         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
26048         diff $DIR/$tfile $DIR/$tfile.1
26049         [[ $? == 0 ]] || error "data incorrect after append"
26050
26051 }
26052 run_test 398n "test append with parallel DIO"
26053
26054 test_398o() {
26055         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
26056 }
26057 run_test 398o "right kms with DIO"
26058
26059 test_fake_rw() {
26060         local read_write=$1
26061         if [ "$read_write" = "write" ]; then
26062                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
26063         elif [ "$read_write" = "read" ]; then
26064                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
26065         else
26066                 error "argument error"
26067         fi
26068
26069         # turn off debug for performance testing
26070         local saved_debug=$($LCTL get_param -n debug)
26071         $LCTL set_param debug=0
26072
26073         $LFS setstripe -c 1 -i 0 $DIR/$tfile
26074
26075         # get ost1 size - $FSNAME-OST0000
26076         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
26077         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
26078         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
26079
26080         if [ "$read_write" = "read" ]; then
26081                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
26082         fi
26083
26084         local start_time=$(date +%s.%N)
26085         $dd_cmd bs=1M count=$blocks oflag=sync ||
26086                 error "real dd $read_write error"
26087         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
26088
26089         if [ "$read_write" = "write" ]; then
26090                 rm -f $DIR/$tfile
26091         fi
26092
26093         # define OBD_FAIL_OST_FAKE_RW           0x238
26094         do_facet ost1 $LCTL set_param fail_loc=0x238
26095
26096         local start_time=$(date +%s.%N)
26097         $dd_cmd bs=1M count=$blocks oflag=sync ||
26098                 error "fake dd $read_write error"
26099         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
26100
26101         if [ "$read_write" = "write" ]; then
26102                 # verify file size
26103                 cancel_lru_locks osc
26104                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
26105                         error "$tfile size not $blocks MB"
26106         fi
26107         do_facet ost1 $LCTL set_param fail_loc=0
26108
26109         echo "fake $read_write $duration_fake vs. normal $read_write" \
26110                 "$duration in seconds"
26111         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
26112                 error_not_in_vm "fake write is slower"
26113
26114         $LCTL set_param -n debug="$saved_debug"
26115         rm -f $DIR/$tfile
26116 }
26117 test_399a() { # LU-7655 for OST fake write
26118         remote_ost_nodsh && skip "remote OST with nodsh"
26119
26120         test_fake_rw write
26121 }
26122 run_test 399a "fake write should not be slower than normal write"
26123
26124 test_399b() { # LU-8726 for OST fake read
26125         remote_ost_nodsh && skip "remote OST with nodsh"
26126         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
26127                 skip_env "ldiskfs only test"
26128         fi
26129
26130         test_fake_rw read
26131 }
26132 run_test 399b "fake read should not be slower than normal read"
26133
26134 test_400a() { # LU-1606, was conf-sanity test_74
26135         if ! which $CC > /dev/null 2>&1; then
26136                 skip_env "$CC is not installed"
26137         fi
26138
26139         local extra_flags=''
26140         local out=$TMP/$tfile
26141         local prefix=/usr/include/lustre
26142         local prog
26143
26144         # Oleg removes .c files in his test rig so test if any c files exist
26145         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26146                 skip_env "Needed .c test files are missing"
26147
26148         if ! [[ -d $prefix ]]; then
26149                 # Assume we're running in tree and fixup the include path.
26150                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26151                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26152                 extra_flags+=" -L$LUSTRE/utils/.libs"
26153         fi
26154
26155         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26156                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26157                         error "client api broken"
26158         done
26159         rm -f $out
26160 }
26161 run_test 400a "Lustre client api program can compile and link"
26162
26163 test_400b() { # LU-1606, LU-5011
26164         local header
26165         local out=$TMP/$tfile
26166         local prefix=/usr/include/linux/lustre
26167
26168         # We use a hard coded prefix so that this test will not fail
26169         # when run in tree. There are headers in lustre/include/lustre/
26170         # that are not packaged (like lustre_idl.h) and have more
26171         # complicated include dependencies (like config.h and lnet/types.h).
26172         # Since this test about correct packaging we just skip them when
26173         # they don't exist (see below) rather than try to fixup cppflags.
26174
26175         if ! which $CC > /dev/null 2>&1; then
26176                 skip_env "$CC is not installed"
26177         fi
26178
26179         for header in $prefix/*.h; do
26180                 if ! [[ -f "$header" ]]; then
26181                         continue
26182                 fi
26183
26184                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26185                         continue # lustre_ioctl.h is internal header
26186                 fi
26187
26188                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26189                         error "cannot compile '$header'"
26190         done
26191         rm -f $out
26192 }
26193 run_test 400b "packaged headers can be compiled"
26194
26195 test_401a() { #LU-7437
26196         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26197         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26198
26199         #count the number of parameters by "list_param -R"
26200         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26201         #count the number of parameters by listing proc files
26202         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26203         echo "proc_dirs='$proc_dirs'"
26204         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26205         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26206                       sort -u | wc -l)
26207
26208         [ $params -eq $procs ] ||
26209                 error "found $params parameters vs. $procs proc files"
26210
26211         # test the list_param -D option only returns directories
26212         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26213         #count the number of parameters by listing proc directories
26214         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26215                 sort -u | wc -l)
26216
26217         [ $params -eq $procs ] ||
26218                 error "found $params parameters vs. $procs proc files"
26219 }
26220 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26221
26222 test_401b() {
26223         # jobid_var may not allow arbitrary values, so use jobid_name
26224         # if available
26225         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26226                 local testname=jobid_name tmp='testing%p'
26227         else
26228                 local testname=jobid_var tmp=testing
26229         fi
26230
26231         local save=$($LCTL get_param -n $testname)
26232
26233         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26234                 error "no error returned when setting bad parameters"
26235
26236         local jobid_new=$($LCTL get_param -n foe $testname baz)
26237         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26238
26239         $LCTL set_param -n fog=bam $testname=$save bat=fog
26240         local jobid_old=$($LCTL get_param -n foe $testname bag)
26241         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26242 }
26243 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26244
26245 test_401c() {
26246         # jobid_var may not allow arbitrary values, so use jobid_name
26247         # if available
26248         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26249                 local testname=jobid_name
26250         else
26251                 local testname=jobid_var
26252         fi
26253
26254         local jobid_var_old=$($LCTL get_param -n $testname)
26255         local jobid_var_new
26256
26257         $LCTL set_param $testname= &&
26258                 error "no error returned for 'set_param a='"
26259
26260         jobid_var_new=$($LCTL get_param -n $testname)
26261         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26262                 error "$testname was changed by setting without value"
26263
26264         $LCTL set_param $testname &&
26265                 error "no error returned for 'set_param a'"
26266
26267         jobid_var_new=$($LCTL get_param -n $testname)
26268         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26269                 error "$testname was changed by setting without value"
26270 }
26271 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26272
26273 test_401d() {
26274         # jobid_var may not allow arbitrary values, so use jobid_name
26275         # if available
26276         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26277                 local testname=jobid_name new_value='foo=bar%p'
26278         else
26279                 local testname=jobid_var new_valuie=foo=bar
26280         fi
26281
26282         local jobid_var_old=$($LCTL get_param -n $testname)
26283         local jobid_var_new
26284
26285         $LCTL set_param $testname=$new_value ||
26286                 error "'set_param a=b' did not accept a value containing '='"
26287
26288         jobid_var_new=$($LCTL get_param -n $testname)
26289         [[ "$jobid_var_new" == "$new_value" ]] ||
26290                 error "'set_param a=b' failed on a value containing '='"
26291
26292         # Reset the $testname to test the other format
26293         $LCTL set_param $testname=$jobid_var_old
26294         jobid_var_new=$($LCTL get_param -n $testname)
26295         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26296                 error "failed to reset $testname"
26297
26298         $LCTL set_param $testname $new_value ||
26299                 error "'set_param a b' did not accept a value containing '='"
26300
26301         jobid_var_new=$($LCTL get_param -n $testname)
26302         [[ "$jobid_var_new" == "$new_value" ]] ||
26303                 error "'set_param a b' failed on a value containing '='"
26304
26305         $LCTL set_param $testname $jobid_var_old
26306         jobid_var_new=$($LCTL get_param -n $testname)
26307         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26308                 error "failed to reset $testname"
26309 }
26310 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26311
26312 test_401e() { # LU-14779
26313         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26314                 error "lctl list_param MGC* failed"
26315         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26316         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26317                 error "lctl get_param lru_size failed"
26318 }
26319 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26320
26321 test_402() {
26322         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26323         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26324                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26325         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26326                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26327                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26328         remote_mds_nodsh && skip "remote MDS with nodsh"
26329
26330         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26331 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26332         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26333         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26334                 echo "Touch failed - OK"
26335 }
26336 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26337
26338 test_403() {
26339         local file1=$DIR/$tfile.1
26340         local file2=$DIR/$tfile.2
26341         local tfile=$TMP/$tfile
26342
26343         rm -f $file1 $file2 $tfile
26344
26345         touch $file1
26346         ln $file1 $file2
26347
26348         # 30 sec OBD_TIMEOUT in ll_getattr()
26349         # right before populating st_nlink
26350         $LCTL set_param fail_loc=0x80001409
26351         stat -c %h $file1 > $tfile &
26352
26353         # create an alias, drop all locks and reclaim the dentry
26354         < $file2
26355         cancel_lru_locks mdc
26356         cancel_lru_locks osc
26357         sysctl -w vm.drop_caches=2
26358
26359         wait
26360
26361         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26362
26363         rm -f $tfile $file1 $file2
26364 }
26365 run_test 403 "i_nlink should not drop to zero due to aliasing"
26366
26367 test_404() { # LU-6601
26368         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26369                 skip "Need server version newer than 2.8.52"
26370         remote_mds_nodsh && skip "remote MDS with nodsh"
26371
26372         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26373                 awk '/osp .*-osc-MDT/ { print $4}')
26374
26375         local osp
26376         for osp in $mosps; do
26377                 echo "Deactivate: " $osp
26378                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26379                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26380                         awk -vp=$osp '$4 == p { print $2 }')
26381                 [ $stat = IN ] || {
26382                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26383                         error "deactivate error"
26384                 }
26385                 echo "Activate: " $osp
26386                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26387                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26388                         awk -vp=$osp '$4 == p { print $2 }')
26389                 [ $stat = UP ] || {
26390                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26391                         error "activate error"
26392                 }
26393         done
26394 }
26395 run_test 404 "validate manual {de}activated works properly for OSPs"
26396
26397 test_405() {
26398         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26399         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26400                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26401                         skip "Layout swap lock is not supported"
26402
26403         check_swap_layouts_support
26404         check_swap_layout_no_dom $DIR
26405
26406         test_mkdir $DIR/$tdir
26407         swap_lock_test -d $DIR/$tdir ||
26408                 error "One layout swap locked test failed"
26409 }
26410 run_test 405 "Various layout swap lock tests"
26411
26412 test_406() {
26413         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26414         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26415         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26417         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26418                 skip "Need MDS version at least 2.8.50"
26419
26420         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26421         local test_pool=$TESTNAME
26422
26423         pool_add $test_pool || error "pool_add failed"
26424         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26425                 error "pool_add_targets failed"
26426
26427         save_layout_restore_at_exit $MOUNT
26428
26429         # parent set default stripe count only, child will stripe from both
26430         # parent and fs default
26431         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26432                 error "setstripe $MOUNT failed"
26433         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26434         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26435         for i in $(seq 10); do
26436                 local f=$DIR/$tdir/$tfile.$i
26437                 touch $f || error "touch failed"
26438                 local count=$($LFS getstripe -c $f)
26439                 [ $count -eq $OSTCOUNT ] ||
26440                         error "$f stripe count $count != $OSTCOUNT"
26441                 local offset=$($LFS getstripe -i $f)
26442                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26443                 local size=$($LFS getstripe -S $f)
26444                 [ $size -eq $((def_stripe_size * 2)) ] ||
26445                         error "$f stripe size $size != $((def_stripe_size * 2))"
26446                 local pool=$($LFS getstripe -p $f)
26447                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26448         done
26449
26450         # change fs default striping, delete parent default striping, now child
26451         # will stripe from new fs default striping only
26452         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26453                 error "change $MOUNT default stripe failed"
26454         $LFS setstripe -c 0 $DIR/$tdir ||
26455                 error "delete $tdir default stripe failed"
26456         for i in $(seq 11 20); do
26457                 local f=$DIR/$tdir/$tfile.$i
26458                 touch $f || error "touch $f failed"
26459                 local count=$($LFS getstripe -c $f)
26460                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26461                 local offset=$($LFS getstripe -i $f)
26462                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26463                 local size=$($LFS getstripe -S $f)
26464                 [ $size -eq $def_stripe_size ] ||
26465                         error "$f stripe size $size != $def_stripe_size"
26466                 local pool=$($LFS getstripe -p $f)
26467                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26468         done
26469
26470         unlinkmany $DIR/$tdir/$tfile. 1 20
26471
26472         local f=$DIR/$tdir/$tfile
26473         pool_remove_all_targets $test_pool $f
26474         pool_remove $test_pool $f
26475 }
26476 run_test 406 "DNE support fs default striping"
26477
26478 test_407() {
26479         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26480         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26481                 skip "Need MDS version at least 2.8.55"
26482         remote_mds_nodsh && skip "remote MDS with nodsh"
26483
26484         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26485                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26486         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26487                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26488         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26489
26490         #define OBD_FAIL_DT_TXN_STOP    0x2019
26491         for idx in $(seq $MDSCOUNT); do
26492                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26493         done
26494         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26495         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26496                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26497         true
26498 }
26499 run_test 407 "transaction fail should cause operation fail"
26500
26501 test_408() {
26502         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26503
26504         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26505         lctl set_param fail_loc=0x8000040a
26506         # let ll_prepare_partial_page() fail
26507         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26508
26509         rm -f $DIR/$tfile
26510
26511         # create at least 100 unused inodes so that
26512         # shrink_icache_memory(0) should not return 0
26513         touch $DIR/$tfile-{0..100}
26514         rm -f $DIR/$tfile-{0..100}
26515         sync
26516
26517         echo 2 > /proc/sys/vm/drop_caches
26518 }
26519 run_test 408 "drop_caches should not hang due to page leaks"
26520
26521 test_409()
26522 {
26523         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26524
26525         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26526         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26527         touch $DIR/$tdir/guard || error "(2) Fail to create"
26528
26529         local PREFIX=$(str_repeat 'A' 128)
26530         echo "Create 1K hard links start at $(date)"
26531         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26532                 error "(3) Fail to hard link"
26533
26534         echo "Links count should be right although linkEA overflow"
26535         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26536         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26537         [ $linkcount -eq 1001 ] ||
26538                 error "(5) Unexpected hard links count: $linkcount"
26539
26540         echo "List all links start at $(date)"
26541         ls -l $DIR/$tdir/foo > /dev/null ||
26542                 error "(6) Fail to list $DIR/$tdir/foo"
26543
26544         echo "Unlink hard links start at $(date)"
26545         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26546                 error "(7) Fail to unlink"
26547         echo "Unlink hard links finished at $(date)"
26548 }
26549 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26550
26551 test_410()
26552 {
26553         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26554                 skip "Need client version at least 2.9.59"
26555         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26556                 skip "Need MODULES build"
26557
26558         # Create a file, and stat it from the kernel
26559         local testfile=$DIR/$tfile
26560         touch $testfile
26561
26562         local run_id=$RANDOM
26563         local my_ino=$(stat --format "%i" $testfile)
26564
26565         # Try to insert the module. This will always fail as the
26566         # module is designed to not be inserted.
26567         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26568             &> /dev/null
26569
26570         # Anything but success is a test failure
26571         dmesg | grep -q \
26572             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26573             error "no inode match"
26574 }
26575 run_test 410 "Test inode number returned from kernel thread"
26576
26577 cleanup_test411_cgroup() {
26578         trap 0
26579         rmdir "$1"
26580 }
26581
26582 test_411() {
26583         local cg_basedir=/sys/fs/cgroup/memory
26584         # LU-9966
26585         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26586                 skip "no setup for cgroup"
26587
26588         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26589                 error "test file creation failed"
26590         cancel_lru_locks osc
26591
26592         # Create a very small memory cgroup to force a slab allocation error
26593         local cgdir=$cg_basedir/osc_slab_alloc
26594         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26595         trap "cleanup_test411_cgroup $cgdir" EXIT
26596         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26597         echo 1M > $cgdir/memory.limit_in_bytes
26598
26599         # Should not LBUG, just be killed by oom-killer
26600         # dd will return 0 even allocation failure in some environment.
26601         # So don't check return value
26602         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26603         cleanup_test411_cgroup $cgdir
26604
26605         return 0
26606 }
26607 run_test 411 "Slab allocation error with cgroup does not LBUG"
26608
26609 test_412() {
26610         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26611         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26612                 skip "Need server version at least 2.10.55"
26613
26614         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26615                 error "mkdir failed"
26616         $LFS getdirstripe $DIR/$tdir
26617         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26618         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26619                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26620         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26621         [ $stripe_count -eq 2 ] ||
26622                 error "expect 2 get $stripe_count"
26623
26624         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26625
26626         local index
26627         local index2
26628
26629         # subdirs should be on the same MDT as parent
26630         for i in $(seq 0 $((MDSCOUNT - 1))); do
26631                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26632                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26633                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26634                 (( index == i )) || error "mdt$i/sub on MDT$index"
26635         done
26636
26637         # stripe offset -1, ditto
26638         for i in {1..10}; do
26639                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26640                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26641                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26642                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26643                 (( index == index2 )) ||
26644                         error "qos$i on MDT$index, sub on MDT$index2"
26645         done
26646
26647         local testdir=$DIR/$tdir/inherit
26648
26649         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26650         # inherit 2 levels
26651         for i in 1 2; do
26652                 testdir=$testdir/s$i
26653                 mkdir $testdir || error "mkdir $testdir failed"
26654                 index=$($LFS getstripe -m $testdir)
26655                 (( index == 1 )) ||
26656                         error "$testdir on MDT$index"
26657         done
26658
26659         # not inherit any more
26660         testdir=$testdir/s3
26661         mkdir $testdir || error "mkdir $testdir failed"
26662         getfattr -d -m dmv $testdir | grep dmv &&
26663                 error "default LMV set on $testdir" || true
26664 }
26665 run_test 412 "mkdir on specific MDTs"
26666
26667 TEST413_COUNT=${TEST413_COUNT:-200}
26668
26669 #
26670 # set_maxage() is used by test_413 only.
26671 # This is a helper function to set maxage. Does not return any value.
26672 # Input: maxage to set
26673 #
26674 set_maxage() {
26675         local lmv_qos_maxage
26676         local lod_qos_maxage
26677         local new_maxage=$1
26678
26679         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26680         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26681         stack_trap "$LCTL set_param \
26682                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26683         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26684                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26685         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26686                 lod.*.mdt_qos_maxage=$new_maxage
26687         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26688                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26689 }
26690
26691 generate_uneven_mdts() {
26692         local threshold=$1
26693         local ffree
26694         local bavail
26695         local max
26696         local min
26697         local max_index
26698         local min_index
26699         local tmp
26700         local i
26701
26702         echo
26703         echo "Check for uneven MDTs: "
26704
26705         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26706         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26707         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26708
26709         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26710         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26711         max_index=0
26712         min_index=0
26713         for ((i = 1; i < ${#ffree[@]}; i++)); do
26714                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26715                 if [ $tmp -gt $max ]; then
26716                         max=$tmp
26717                         max_index=$i
26718                 fi
26719                 if [ $tmp -lt $min ]; then
26720                         min=$tmp
26721                         min_index=$i
26722                 fi
26723         done
26724
26725         (( min > 0 )) || skip "low space on MDT$min_index"
26726         (( ${ffree[min_index]} > 0 )) ||
26727                 skip "no free files on MDT$min_index"
26728         (( ${ffree[min_index]} < 10000000 )) ||
26729                 skip "too many free files on MDT$min_index"
26730
26731         # Check if we need to generate uneven MDTs
26732         local diff=$(((max - min) * 100 / min))
26733         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26734         local testdir # individual folder within $testdirp
26735         local start
26736         local cmd
26737
26738         # fallocate is faster to consume space on MDT, if available
26739         if check_fallocate_supported mds$((min_index + 1)); then
26740                 cmd="fallocate -l 128K "
26741         else
26742                 cmd="dd if=/dev/zero bs=128K count=1 of="
26743         fi
26744
26745         echo "using cmd $cmd"
26746         for (( i = 0; diff < threshold; i++ )); do
26747                 testdir=${testdirp}/$i
26748                 [ -d $testdir ] && continue
26749
26750                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26751
26752                 mkdir -p $testdirp
26753                 # generate uneven MDTs, create till $threshold% diff
26754                 echo -n "weight diff=$diff% must be > $threshold% ..."
26755                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26756                 $LFS mkdir -i $min_index $testdir ||
26757                         error "mkdir $testdir failed"
26758                 $LFS setstripe -E 1M -L mdt $testdir ||
26759                         error "setstripe $testdir failed"
26760                 start=$SECONDS
26761                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26762                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26763                 done
26764                 sync; sleep 1; sync
26765
26766                 # wait for QOS to update
26767                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26768
26769                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26770                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26771                 max=$(((${ffree[max_index]} >> 8) *
26772                         (${bavail[max_index]} * bsize >> 16)))
26773                 min=$(((${ffree[min_index]} >> 8) *
26774                         (${bavail[min_index]} * bsize >> 16)))
26775                 (( min > 0 )) || skip "low space on MDT$min_index"
26776                 diff=$(((max - min) * 100 / min))
26777         done
26778
26779         echo "MDT filesfree available: ${ffree[*]}"
26780         echo "MDT blocks available: ${bavail[*]}"
26781         echo "weight diff=$diff%"
26782 }
26783
26784 test_qos_mkdir() {
26785         local mkdir_cmd=$1
26786         local stripe_count=$2
26787         local mdts=$(comma_list $(mdts_nodes))
26788
26789         local testdir
26790         local lmv_qos_prio_free
26791         local lmv_qos_threshold_rr
26792         local lod_qos_prio_free
26793         local lod_qos_threshold_rr
26794         local total
26795         local count
26796         local i
26797
26798         # @total is total directories created if it's testing plain
26799         # directories, otherwise it's total stripe object count for
26800         # striped directories test.
26801         # remote/striped directory unlinking is slow on zfs and may
26802         # timeout, test with fewer directories
26803         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26804
26805         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26806         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26807         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26808                 head -n1)
26809         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26810         stack_trap "$LCTL set_param \
26811                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26812         stack_trap "$LCTL set_param \
26813                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26814
26815         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26816                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26817         lod_qos_prio_free=${lod_qos_prio_free%%%}
26818         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26819                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26820         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26821         stack_trap "do_nodes $mdts $LCTL set_param \
26822                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26823         stack_trap "do_nodes $mdts $LCTL set_param \
26824                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26825
26826         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26827         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26828
26829         testdir=$DIR/$tdir-s$stripe_count/rr
26830
26831         local stripe_index=$($LFS getstripe -m $testdir)
26832         local test_mkdir_rr=true
26833
26834         getfattr -d -m dmv -e hex $testdir | grep dmv
26835         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26836                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26837                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26838                         test_mkdir_rr=false
26839         fi
26840
26841         echo
26842         $test_mkdir_rr &&
26843                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26844                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26845
26846         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26847         for (( i = 0; i < total / stripe_count; i++ )); do
26848                 eval $mkdir_cmd $testdir/subdir$i ||
26849                         error "$mkdir_cmd subdir$i failed"
26850         done
26851
26852         for (( i = 0; i < $MDSCOUNT; i++ )); do
26853                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26854                 echo "$count directories created on MDT$i"
26855                 if $test_mkdir_rr; then
26856                         (( count == total / stripe_count / MDSCOUNT )) ||
26857                                 error "subdirs are not evenly distributed"
26858                 elif (( i == stripe_index )); then
26859                         (( count == total / stripe_count )) ||
26860                                 error "$count subdirs created on MDT$i"
26861                 else
26862                         (( count == 0 )) ||
26863                                 error "$count subdirs created on MDT$i"
26864                 fi
26865
26866                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26867                         count=$($LFS getdirstripe $testdir/* |
26868                                 grep -c -P "^\s+$i\t")
26869                         echo "$count stripes created on MDT$i"
26870                         # deviation should < 5% of average
26871                         delta=$((count - total / MDSCOUNT))
26872                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26873                                 error "stripes are not evenly distributed"
26874                 fi
26875         done
26876
26877         echo
26878         echo "Check for uneven MDTs: "
26879
26880         local ffree
26881         local bavail
26882         local max
26883         local min
26884         local max_index
26885         local min_index
26886         local tmp
26887
26888         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26889         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26890         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26891
26892         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26893         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26894         max_index=0
26895         min_index=0
26896         for ((i = 1; i < ${#ffree[@]}; i++)); do
26897                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26898                 if [ $tmp -gt $max ]; then
26899                         max=$tmp
26900                         max_index=$i
26901                 fi
26902                 if [ $tmp -lt $min ]; then
26903                         min=$tmp
26904                         min_index=$i
26905                 fi
26906         done
26907         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26908
26909         (( min > 0 )) || skip "low space on MDT$min_index"
26910         (( ${ffree[min_index]} < 10000000 )) ||
26911                 skip "too many free files on MDT$min_index"
26912
26913         generate_uneven_mdts 120
26914
26915         echo "MDT filesfree available: ${ffree[*]}"
26916         echo "MDT blocks available: ${bavail[*]}"
26917         echo "weight diff=$(((max - min) * 100 / min))%"
26918         echo
26919         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26920
26921         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26922         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26923         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26924         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26925         # decrease statfs age, so that it can be updated in time
26926         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26927         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26928
26929         sleep 1
26930
26931         testdir=$DIR/$tdir-s$stripe_count/qos
26932
26933         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26934         for (( i = 0; i < total / stripe_count; i++ )); do
26935                 eval $mkdir_cmd $testdir/subdir$i ||
26936                         error "$mkdir_cmd subdir$i failed"
26937         done
26938
26939         max=0
26940         for (( i = 0; i < $MDSCOUNT; i++ )); do
26941                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26942                 (( count > max )) && max=$count
26943                 echo "$count directories created on MDT$i : curmax=$max"
26944         done
26945
26946         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26947
26948         # D-value should > 10% of average
26949         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
26950                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
26951
26952         # ditto for stripes
26953         if (( stripe_count > 1 )); then
26954                 max=0
26955                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26956                         count=$($LFS getdirstripe $testdir/* |
26957                                 grep -c -P "^\s+$i\t")
26958                         (( count > max )) && max=$count
26959                         echo "$count stripes created on MDT$i"
26960                 done
26961
26962                 min=$($LFS getdirstripe $testdir/* |
26963                         grep -c -P "^\s+$min_index\t")
26964                 (( max - min > total / MDSCOUNT / 10 )) ||
26965                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
26966         fi
26967 }
26968
26969 most_full_mdt() {
26970         local ffree
26971         local bavail
26972         local bsize
26973         local min
26974         local min_index
26975         local tmp
26976
26977         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26978         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26979         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26980
26981         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26982         min_index=0
26983         for ((i = 1; i < ${#ffree[@]}; i++)); do
26984                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26985                 (( tmp < min )) && min=$tmp && min_index=$i
26986         done
26987
26988         echo -n $min_index
26989 }
26990
26991 test_413a() {
26992         [ $MDSCOUNT -lt 2 ] &&
26993                 skip "We need at least 2 MDTs for this test"
26994
26995         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26996                 skip "Need server version at least 2.12.52"
26997
26998         local stripe_max=$((MDSCOUNT - 1))
26999         local stripe_count
27000
27001         # let caller set maxage for latest result
27002         set_maxage 1
27003
27004         # fill MDT unevenly
27005         generate_uneven_mdts 120
27006
27007         # test 4-stripe directory at most, otherwise it's too slow
27008         # We are being very defensive. Although Autotest uses 4 MDTs.
27009         # We make sure stripe_max does not go over 4.
27010         (( stripe_max > 4 )) && stripe_max=4
27011         # unlinking striped directory is slow on zfs, and may timeout, only test
27012         # plain directory
27013         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27014         for stripe_count in $(seq 1 $stripe_max); do
27015                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
27016                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
27017                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
27018                         error "mkdir failed"
27019                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
27020         done
27021 }
27022 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
27023
27024 test_413b() {
27025         [ $MDSCOUNT -lt 2 ] &&
27026                 skip "We need at least 2 MDTs for this test"
27027
27028         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
27029                 skip "Need server version at least 2.12.52"
27030
27031         local stripe_max=$((MDSCOUNT - 1))
27032         local testdir
27033         local stripe_count
27034
27035         # let caller set maxage for latest result
27036         set_maxage 1
27037
27038         # fill MDT unevenly
27039         generate_uneven_mdts 120
27040
27041         # test 4-stripe directory at most, otherwise it's too slow
27042         # We are being very defensive. Although Autotest uses 4 MDTs.
27043         # We make sure stripe_max does not go over 4.
27044         (( stripe_max > 4 )) && stripe_max=4
27045         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
27046         for stripe_count in $(seq 1 $stripe_max); do
27047                 testdir=$DIR/$tdir-s$stripe_count
27048                 mkdir $testdir || error "mkdir $testdir failed"
27049                 mkdir $testdir/rr || error "mkdir rr failed"
27050                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
27051                         error "mkdir qos failed"
27052                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
27053                         $testdir/rr || error "setdirstripe rr failed"
27054                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
27055                         error "setdirstripe failed"
27056                 test_qos_mkdir "mkdir" $stripe_count
27057         done
27058 }
27059 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
27060
27061 test_413c() {
27062         (( $MDSCOUNT >= 2 )) ||
27063                 skip "We need at least 2 MDTs for this test"
27064
27065         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
27066                 skip "Need server version at least 2.14.51"
27067
27068         local testdir
27069         local inherit
27070         local inherit_rr
27071         local lmv_qos_maxage
27072         local lod_qos_maxage
27073
27074         # let caller set maxage for latest result
27075         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27076         $LCTL set_param lmv.*.qos_maxage=1
27077         stack_trap "$LCTL set_param \
27078                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
27079         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
27080                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
27081         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27082                 lod.*.mdt_qos_maxage=1
27083         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
27084                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
27085
27086         # fill MDT unevenly
27087         generate_uneven_mdts 120
27088
27089         testdir=$DIR/${tdir}-s1
27090         mkdir $testdir || error "mkdir $testdir failed"
27091         mkdir $testdir/rr || error "mkdir rr failed"
27092         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
27093         # default max_inherit is -1, default max_inherit_rr is 0
27094         $LFS setdirstripe -D -c 1 $testdir/rr ||
27095                 error "setdirstripe rr failed"
27096         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
27097                 error "setdirstripe qos failed"
27098         test_qos_mkdir "mkdir" 1
27099
27100         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
27101         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
27102         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
27103         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
27104         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
27105
27106         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
27107         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
27108         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
27109         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
27110         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
27111         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
27112         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
27113                 error "level2 shouldn't have default LMV" || true
27114 }
27115 run_test 413c "mkdir with default LMV max inherit rr"
27116
27117 test_413d() {
27118         (( MDSCOUNT >= 2 )) ||
27119                 skip "We need at least 2 MDTs for this test"
27120
27121         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
27122                 skip "Need server version at least 2.14.51"
27123
27124         local lmv_qos_threshold_rr
27125
27126         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
27127                 head -n1)
27128         stack_trap "$LCTL set_param \
27129                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27130
27131         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27132         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27133         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27134                 error "$tdir shouldn't have default LMV"
27135         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27136                 error "mkdir sub failed"
27137
27138         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27139
27140         (( count == 100 )) || error "$count subdirs on MDT0"
27141 }
27142 run_test 413d "inherit ROOT default LMV"
27143
27144 test_413e() {
27145         (( MDSCOUNT >= 2 )) ||
27146                 skip "We need at least 2 MDTs for this test"
27147         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27148                 skip "Need server version at least 2.14.55"
27149
27150         local testdir=$DIR/$tdir
27151         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27152         local max_inherit
27153         local sub_max_inherit
27154
27155         mkdir -p $testdir || error "failed to create $testdir"
27156
27157         # set default max-inherit to -1 if stripe count is 0 or 1
27158         $LFS setdirstripe -D -c 1 $testdir ||
27159                 error "failed to set default LMV"
27160         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27161         (( max_inherit == -1 )) ||
27162                 error "wrong max_inherit value $max_inherit"
27163
27164         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27165         $LFS setdirstripe -D -c -1 $testdir ||
27166                 error "failed to set default LMV"
27167         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27168         (( max_inherit > 0 )) ||
27169                 error "wrong max_inherit value $max_inherit"
27170
27171         # and the subdir will decrease the max_inherit by 1
27172         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27173         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27174         (( sub_max_inherit == max_inherit - 1)) ||
27175                 error "wrong max-inherit of subdir $sub_max_inherit"
27176
27177         # check specified --max-inherit and warning message
27178         stack_trap "rm -f $tmpfile"
27179         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27180                 error "failed to set default LMV"
27181         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27182         (( max_inherit == -1 )) ||
27183                 error "wrong max_inherit value $max_inherit"
27184
27185         # check the warning messages
27186         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27187                 error "failed to detect warning string"
27188         fi
27189 }
27190 run_test 413e "check default max-inherit value"
27191
27192 test_fs_dmv_inherit()
27193 {
27194         local testdir=$DIR/$tdir
27195
27196         local count
27197         local inherit
27198         local inherit_rr
27199
27200         for i in 1 2; do
27201                 mkdir $testdir || error "mkdir $testdir failed"
27202                 count=$($LFS getdirstripe -D -c $testdir)
27203                 (( count == 1 )) ||
27204                         error "$testdir default LMV count mismatch $count != 1"
27205                 inherit=$($LFS getdirstripe -D -X $testdir)
27206                 (( inherit == 3 - i )) ||
27207                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27208                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27209                 (( inherit_rr == 3 - i )) ||
27210                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27211                 testdir=$testdir/sub
27212         done
27213
27214         mkdir $testdir || error "mkdir $testdir failed"
27215         count=$($LFS getdirstripe -D -c $testdir)
27216         (( count == 0 )) ||
27217                 error "$testdir default LMV count not zero: $count"
27218 }
27219
27220 test_413f() {
27221         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27222
27223         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27224                 skip "Need server version at least 2.14.55"
27225
27226         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27227                 error "dump $DIR default LMV failed"
27228         stack_trap "setfattr --restore=$TMP/dmv.ea"
27229
27230         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27231                 error "set $DIR default LMV failed"
27232
27233         test_fs_dmv_inherit
27234 }
27235 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27236
27237 test_413g() {
27238         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27239
27240         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27241         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27242                 error "dump $DIR default LMV failed"
27243         stack_trap "setfattr --restore=$TMP/dmv.ea"
27244
27245         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27246                 error "set $DIR default LMV failed"
27247
27248         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27249                 error "mount $MOUNT2 failed"
27250         stack_trap "umount_client $MOUNT2"
27251
27252         local saved_DIR=$DIR
27253
27254         export DIR=$MOUNT2
27255
27256         stack_trap "export DIR=$saved_DIR"
27257
27258         # first check filesystem-wide default LMV inheritance
27259         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27260
27261         # then check subdirs are spread to all MDTs
27262         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27263
27264         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27265
27266         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27267 }
27268 run_test 413g "enforce ROOT default LMV on subdir mount"
27269
27270 test_413h() {
27271         (( MDSCOUNT >= 2 )) ||
27272                 skip "We need at least 2 MDTs for this test"
27273
27274         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27275                 skip "Need server version at least 2.15.50.6"
27276
27277         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27278
27279         stack_trap "$LCTL set_param \
27280                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27281         $LCTL set_param lmv.*.qos_maxage=1
27282
27283         local depth=5
27284         local rr_depth=4
27285         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27286         local count=$((MDSCOUNT * 20))
27287
27288         generate_uneven_mdts 50
27289
27290         mkdir -p $dir || error "mkdir $dir failed"
27291         stack_trap "rm -rf $dir"
27292         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27293                 --max-inherit-rr=$rr_depth $dir
27294
27295         for ((d=0; d < depth + 2; d++)); do
27296                 log "dir=$dir:"
27297                 for ((sub=0; sub < count; sub++)); do
27298                         mkdir $dir/d$sub
27299                 done
27300                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27301                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27302                 # subdirs within $rr_depth should be created round-robin
27303                 if (( d < rr_depth )); then
27304                         (( ${num[0]} != count )) ||
27305                                 error "all objects created on MDT ${num[1]}"
27306                 fi
27307
27308                 dir=$dir/d0
27309         done
27310 }
27311 run_test 413h "don't stick to parent for round-robin dirs"
27312
27313 test_413i() {
27314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27315
27316         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27317                 skip "Need server version at least 2.14.55"
27318
27319         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27320                 error "dump $DIR default LMV failed"
27321         stack_trap "setfattr --restore=$TMP/dmv.ea"
27322
27323         local testdir=$DIR/$tdir
27324         local def_max_rr=1
27325         local def_max=3
27326         local count
27327
27328         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27329                 --max-inherit-rr=$def_max_rr $DIR ||
27330                 error "set $DIR default LMV failed"
27331
27332         for i in $(seq 2 3); do
27333                 def_max=$((def_max - 1))
27334                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27335
27336                 mkdir $testdir
27337                 # RR is decremented and keeps zeroed once exhausted
27338                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27339                 (( count == def_max_rr )) ||
27340                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27341
27342                 # max-inherit is decremented
27343                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27344                 (( count == def_max )) ||
27345                         error_noexit "$testdir: max-inherit $count != $def_max"
27346
27347                 testdir=$testdir/d$i
27348         done
27349
27350         # d3 is the last inherited from ROOT, no inheritance anymore
27351         # i.e. no the default layout anymore
27352         mkdir -p $testdir/d4/d5
27353         count=$($LFS getdirstripe -D --max-inherit $testdir)
27354         (( count == -1 )) ||
27355                 error_noexit "$testdir: max-inherit $count != -1"
27356
27357         local p_count=$($LFS getdirstripe -i $testdir)
27358
27359         for i in $(seq 4 5); do
27360                 testdir=$testdir/d$i
27361
27362                 # the root default layout is not applied once exhausted
27363                 count=$($LFS getdirstripe -i $testdir)
27364                 (( count == p_count )) ||
27365                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27366         done
27367
27368         $LFS setdirstripe -i 0 $DIR/d2
27369         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27370         (( count == -1 )) ||
27371                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27372 }
27373 run_test 413i "check default layout inheritance"
27374
27375 test_413z() {
27376         local pids=""
27377         local subdir
27378         local pid
27379
27380         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27381                 unlinkmany $subdir/f. $TEST413_COUNT &
27382                 pids="$pids $!"
27383         done
27384
27385         for pid in $pids; do
27386                 wait $pid
27387         done
27388
27389         true
27390 }
27391 run_test 413z "413 test cleanup"
27392
27393 test_414() {
27394 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27395         $LCTL set_param fail_loc=0x80000521
27396         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27397         rm -f $DIR/$tfile
27398 }
27399 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27400
27401 test_415() {
27402         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27403         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27404                 skip "Need server version at least 2.11.52"
27405
27406         # LU-11102
27407         local total=500
27408         local max=120
27409
27410         # this test may be slow on ZFS
27411         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27412
27413         # though this test is designed for striped directory, let's test normal
27414         # directory too since lock is always saved as CoS lock.
27415         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27416         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27417         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27418         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27419         wait_delete_completed_mds
27420
27421         # run a loop without concurrent touch to measure rename duration.
27422         # only for test debug/robustness, NOT part of COS functional test.
27423         local start_time=$SECONDS
27424         for ((i = 0; i < total; i++)); do
27425                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27426                         > /dev/null
27427         done
27428         local baseline=$((SECONDS - start_time))
27429         echo "rename $total files without 'touch' took $baseline sec"
27430
27431         (
27432                 while true; do
27433                         touch $DIR/$tdir
27434                 done
27435         ) &
27436         local setattr_pid=$!
27437
27438         # rename files back to original name so unlinkmany works
27439         start_time=$SECONDS
27440         for ((i = 0; i < total; i++)); do
27441                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27442                         > /dev/null
27443         done
27444         local duration=$((SECONDS - start_time))
27445
27446         kill -9 $setattr_pid
27447
27448         echo "rename $total files with 'touch' took $duration sec"
27449         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27450         (( duration <= max )) ||
27451                 error_not_in_vm "rename took $duration > $max sec"
27452 }
27453 run_test 415 "lock revoke is not missing"
27454
27455 test_416() {
27456         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27457                 skip "Need server version at least 2.11.55"
27458
27459         # define OBD_FAIL_OSD_TXN_START    0x19a
27460         do_facet mds1 lctl set_param fail_loc=0x19a
27461
27462         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27463
27464         true
27465 }
27466 run_test 416 "transaction start failure won't cause system hung"
27467
27468 cleanup_417() {
27469         trap 0
27470         do_nodes $(comma_list $(mdts_nodes)) \
27471                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27472         do_nodes $(comma_list $(mdts_nodes)) \
27473                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27474         do_nodes $(comma_list $(mdts_nodes)) \
27475                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27476 }
27477
27478 test_417() {
27479         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27480         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27481                 skip "Need MDS version at least 2.11.56"
27482
27483         trap cleanup_417 RETURN EXIT
27484
27485         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27486         do_nodes $(comma_list $(mdts_nodes)) \
27487                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27488         $LFS migrate -m 0 $DIR/$tdir.1 &&
27489                 error "migrate dir $tdir.1 should fail"
27490
27491         do_nodes $(comma_list $(mdts_nodes)) \
27492                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27493         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27494                 error "create remote dir $tdir.2 should fail"
27495
27496         do_nodes $(comma_list $(mdts_nodes)) \
27497                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27498         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27499                 error "create striped dir $tdir.3 should fail"
27500         true
27501 }
27502 run_test 417 "disable remote dir, striped dir and dir migration"
27503
27504 # Checks that the outputs of df [-i] and lfs df [-i] match
27505 #
27506 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27507 check_lfs_df() {
27508         local dir=$2
27509         local inodes
27510         local df_out
27511         local lfs_df_out
27512         local count
27513         local passed=false
27514
27515         # blocks or inodes
27516         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27517
27518         for count in {1..100}; do
27519                 do_nodes "$CLIENTS" \
27520                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27521                 sync; sleep 0.2
27522
27523                 # read the lines of interest
27524                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27525                         error "df $inodes $dir | tail -n +2 failed"
27526                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27527                         error "lfs df $inodes $dir | grep summary: failed"
27528
27529                 # skip first substrings of each output as they are different
27530                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27531                 # compare the two outputs
27532                 passed=true
27533                 #  skip "available" on MDT until LU-13997 is fixed.
27534                 #for i in {1..5}; do
27535                 for i in 1 2 4 5; do
27536                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27537                 done
27538                 $passed && break
27539         done
27540
27541         if ! $passed; then
27542                 df -P $inodes $dir
27543                 echo
27544                 lfs df $inodes $dir
27545                 error "df and lfs df $1 output mismatch: "      \
27546                       "df ${inodes}: ${df_out[*]}, "            \
27547                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27548         fi
27549 }
27550
27551 test_418() {
27552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27553
27554         local dir=$DIR/$tdir
27555         local numfiles=$((RANDOM % 4096 + 2))
27556         local numblocks=$((RANDOM % 256 + 1))
27557
27558         wait_delete_completed
27559         test_mkdir $dir
27560
27561         # check block output
27562         check_lfs_df blocks $dir
27563         # check inode output
27564         check_lfs_df inodes $dir
27565
27566         # create a single file and retest
27567         echo "Creating a single file and testing"
27568         createmany -o $dir/$tfile- 1 &>/dev/null ||
27569                 error "creating 1 file in $dir failed"
27570         check_lfs_df blocks $dir
27571         check_lfs_df inodes $dir
27572
27573         # create a random number of files
27574         echo "Creating $((numfiles - 1)) files and testing"
27575         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27576                 error "creating $((numfiles - 1)) files in $dir failed"
27577
27578         # write a random number of blocks to the first test file
27579         echo "Writing $numblocks 4K blocks and testing"
27580         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27581                 count=$numblocks &>/dev/null ||
27582                 error "dd to $dir/${tfile}-0 failed"
27583
27584         # retest
27585         check_lfs_df blocks $dir
27586         check_lfs_df inodes $dir
27587
27588         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27589                 error "unlinking $numfiles files in $dir failed"
27590 }
27591 run_test 418 "df and lfs df outputs match"
27592
27593 test_419()
27594 {
27595         local dir=$DIR/$tdir
27596
27597         mkdir -p $dir
27598         touch $dir/file
27599
27600         cancel_lru_locks mdc
27601
27602         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27603         $LCTL set_param fail_loc=0x1410
27604         cat $dir/file
27605         $LCTL set_param fail_loc=0
27606         rm -rf $dir
27607 }
27608 run_test 419 "Verify open file by name doesn't crash kernel"
27609
27610 test_420()
27611 {
27612         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27613                 skip "Need MDS version at least 2.12.53"
27614
27615         local SAVE_UMASK=$(umask)
27616         local dir=$DIR/$tdir
27617         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27618
27619         mkdir -p $dir
27620         umask 0000
27621         mkdir -m03777 $dir/testdir
27622         ls -dn $dir/testdir
27623         # Need to remove trailing '.' when SELinux is enabled
27624         local dirperms=$(ls -dn $dir/testdir |
27625                          awk '{ sub(/\.$/, "", $1); print $1}')
27626         [ $dirperms == "drwxrwsrwt" ] ||
27627                 error "incorrect perms on $dir/testdir"
27628
27629         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27630                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27631         ls -n $dir/testdir/testfile
27632         local fileperms=$(ls -n $dir/testdir/testfile |
27633                           awk '{ sub(/\.$/, "", $1); print $1}')
27634         [ $fileperms == "-rwxr-xr-x" ] ||
27635                 error "incorrect perms on $dir/testdir/testfile"
27636
27637         umask $SAVE_UMASK
27638 }
27639 run_test 420 "clear SGID bit on non-directories for non-members"
27640
27641 test_421a() {
27642         local cnt
27643         local fid1
27644         local fid2
27645
27646         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27647                 skip "Need MDS version at least 2.12.54"
27648
27649         test_mkdir $DIR/$tdir
27650         createmany -o $DIR/$tdir/f 3
27651         cnt=$(ls -1 $DIR/$tdir | wc -l)
27652         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27653
27654         fid1=$(lfs path2fid $DIR/$tdir/f1)
27655         fid2=$(lfs path2fid $DIR/$tdir/f2)
27656         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27657
27658         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27659         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27660
27661         cnt=$(ls -1 $DIR/$tdir | wc -l)
27662         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27663
27664         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27665         createmany -o $DIR/$tdir/f 3
27666         cnt=$(ls -1 $DIR/$tdir | wc -l)
27667         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27668
27669         fid1=$(lfs path2fid $DIR/$tdir/f1)
27670         fid2=$(lfs path2fid $DIR/$tdir/f2)
27671         echo "remove using fsname $FSNAME"
27672         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27673
27674         cnt=$(ls -1 $DIR/$tdir | wc -l)
27675         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27676 }
27677 run_test 421a "simple rm by fid"
27678
27679 test_421b() {
27680         local cnt
27681         local FID1
27682         local FID2
27683
27684         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27685                 skip "Need MDS version at least 2.12.54"
27686
27687         test_mkdir $DIR/$tdir
27688         createmany -o $DIR/$tdir/f 3
27689         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27690         MULTIPID=$!
27691
27692         FID1=$(lfs path2fid $DIR/$tdir/f1)
27693         FID2=$(lfs path2fid $DIR/$tdir/f2)
27694         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27695
27696         kill -USR1 $MULTIPID
27697         wait
27698
27699         cnt=$(ls $DIR/$tdir | wc -l)
27700         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27701 }
27702 run_test 421b "rm by fid on open file"
27703
27704 test_421c() {
27705         local cnt
27706         local FIDS
27707
27708         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27709                 skip "Need MDS version at least 2.12.54"
27710
27711         test_mkdir $DIR/$tdir
27712         createmany -o $DIR/$tdir/f 3
27713         touch $DIR/$tdir/$tfile
27714         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27715         cnt=$(ls -1 $DIR/$tdir | wc -l)
27716         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27717
27718         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27719         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27720
27721         cnt=$(ls $DIR/$tdir | wc -l)
27722         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27723 }
27724 run_test 421c "rm by fid against hardlinked files"
27725
27726 test_421d() {
27727         local cnt
27728         local FIDS
27729
27730         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27731                 skip "Need MDS version at least 2.12.54"
27732
27733         test_mkdir $DIR/$tdir
27734         createmany -o $DIR/$tdir/f 4097
27735         cnt=$(ls -1 $DIR/$tdir | wc -l)
27736         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27737
27738         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27739         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27740
27741         cnt=$(ls $DIR/$tdir | wc -l)
27742         rm -rf $DIR/$tdir
27743         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27744 }
27745 run_test 421d "rmfid en masse"
27746
27747 test_421e() {
27748         local cnt
27749         local FID
27750
27751         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27752         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27753                 skip "Need MDS version at least 2.12.54"
27754
27755         mkdir -p $DIR/$tdir
27756         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27757         createmany -o $DIR/$tdir/striped_dir/f 512
27758         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27759         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27760
27761         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27762                 sed "s/[/][^:]*://g")
27763         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27764
27765         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27766         rm -rf $DIR/$tdir
27767         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27768 }
27769 run_test 421e "rmfid in DNE"
27770
27771 test_421f() {
27772         local cnt
27773         local FID
27774
27775         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27776                 skip "Need MDS version at least 2.12.54"
27777
27778         test_mkdir $DIR/$tdir
27779         touch $DIR/$tdir/f
27780         cnt=$(ls -1 $DIR/$tdir | wc -l)
27781         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27782
27783         FID=$(lfs path2fid $DIR/$tdir/f)
27784         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27785         # rmfid should fail
27786         cnt=$(ls -1 $DIR/$tdir | wc -l)
27787         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27788
27789         chmod a+rw $DIR/$tdir
27790         ls -la $DIR/$tdir
27791         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27792         # rmfid should fail
27793         cnt=$(ls -1 $DIR/$tdir | wc -l)
27794         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27795
27796         rm -f $DIR/$tdir/f
27797         $RUNAS touch $DIR/$tdir/f
27798         FID=$(lfs path2fid $DIR/$tdir/f)
27799         echo "rmfid as root"
27800         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27801         cnt=$(ls -1 $DIR/$tdir | wc -l)
27802         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27803
27804         rm -f $DIR/$tdir/f
27805         $RUNAS touch $DIR/$tdir/f
27806         cnt=$(ls -1 $DIR/$tdir | wc -l)
27807         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27808         FID=$(lfs path2fid $DIR/$tdir/f)
27809         # rmfid w/o user_fid2path mount option should fail
27810         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27811         cnt=$(ls -1 $DIR/$tdir | wc -l)
27812         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27813
27814         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27815         stack_trap "rmdir $tmpdir"
27816         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27817                 error "failed to mount client'"
27818         stack_trap "umount_client $tmpdir"
27819
27820         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27821         # rmfid should succeed
27822         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27823         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27824
27825         # rmfid shouldn't allow to remove files due to dir's permission
27826         chmod a+rwx $tmpdir/$tdir
27827         touch $tmpdir/$tdir/f
27828         ls -la $tmpdir/$tdir
27829         FID=$(lfs path2fid $tmpdir/$tdir/f)
27830         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27831         return 0
27832 }
27833 run_test 421f "rmfid checks permissions"
27834
27835 test_421g() {
27836         local cnt
27837         local FIDS
27838
27839         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27840         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27841                 skip "Need MDS version at least 2.12.54"
27842
27843         mkdir -p $DIR/$tdir
27844         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27845         createmany -o $DIR/$tdir/striped_dir/f 512
27846         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27847         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27848
27849         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27850                 sed "s/[/][^:]*://g")
27851
27852         rm -f $DIR/$tdir/striped_dir/f1*
27853         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27854         removed=$((512 - cnt))
27855
27856         # few files have been just removed, so we expect
27857         # rmfid to fail on their fids
27858         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27859         [ $removed != $errors ] && error "$errors != $removed"
27860
27861         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27862         rm -rf $DIR/$tdir
27863         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27864 }
27865 run_test 421g "rmfid to return errors properly"
27866
27867 test_421h() {
27868         local mount_other
27869         local mount_ret
27870         local rmfid_ret
27871         local old_fid
27872         local fidA
27873         local fidB
27874         local fidC
27875         local fidD
27876
27877         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27878                 skip "Need MDS version at least 2.15.53"
27879
27880         test_mkdir $DIR/$tdir
27881         test_mkdir $DIR/$tdir/subdir
27882         touch $DIR/$tdir/subdir/file0
27883         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27884         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27885         rm -f $DIR/$tdir/subdir/file0
27886         touch $DIR/$tdir/subdir/fileA
27887         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27888         echo File $DIR/$tdir/subdir/fileA FID $fidA
27889         touch $DIR/$tdir/subdir/fileB
27890         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27891         echo File $DIR/$tdir/subdir/fileB FID $fidB
27892         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27893         touch $DIR/$tdir/subdir/fileC
27894         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27895         echo File $DIR/$tdir/subdir/fileC FID $fidC
27896         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27897         touch $DIR/$tdir/fileD
27898         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27899         echo File $DIR/$tdir/fileD FID $fidD
27900
27901         # mount another client mount point with subdirectory mount
27902         export FILESET=/$tdir/subdir
27903         mount_other=${MOUNT}_other
27904         mount_client $mount_other ${MOUNT_OPTS}
27905         mount_ret=$?
27906         export FILESET=""
27907         (( mount_ret == 0 )) || error "mount $mount_other failed"
27908
27909         echo Removing FIDs:
27910         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27911         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27912         rmfid_ret=$?
27913
27914         umount_client $mount_other || error "umount $mount_other failed"
27915
27916         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27917
27918         # fileA should have been deleted
27919         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27920
27921         # fileB should have been deleted
27922         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27923
27924         # fileC should not have been deleted, fid also exists outside of fileset
27925         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27926
27927         # fileD should not have been deleted, it exists outside of fileset
27928         stat $DIR/$tdir/fileD || error "fileD deleted"
27929 }
27930 run_test 421h "rmfid with fileset mount"
27931
27932 test_422() {
27933         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27934         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27935         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27936         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27937         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27938
27939         local amc=$(at_max_get client)
27940         local amo=$(at_max_get mds1)
27941         local timeout=`lctl get_param -n timeout`
27942
27943         at_max_set 0 client
27944         at_max_set 0 mds1
27945
27946 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27947         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27948                         fail_val=$(((2*timeout + 10)*1000))
27949         touch $DIR/$tdir/d3/file &
27950         sleep 2
27951 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27952         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27953                         fail_val=$((2*timeout + 5))
27954         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27955         local pid=$!
27956         sleep 1
27957         kill -9 $pid
27958         sleep $((2 * timeout))
27959         echo kill $pid
27960         kill -9 $pid
27961         lctl mark touch
27962         touch $DIR/$tdir/d2/file3
27963         touch $DIR/$tdir/d2/file4
27964         touch $DIR/$tdir/d2/file5
27965
27966         wait
27967         at_max_set $amc client
27968         at_max_set $amo mds1
27969
27970         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27971         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27972                 error "Watchdog is always throttled"
27973 }
27974 run_test 422 "kill a process with RPC in progress"
27975
27976 stat_test() {
27977     df -h $MOUNT &
27978     df -h $MOUNT &
27979     df -h $MOUNT &
27980     df -h $MOUNT &
27981     df -h $MOUNT &
27982     df -h $MOUNT &
27983 }
27984
27985 test_423() {
27986     local _stats
27987     # ensure statfs cache is expired
27988     sleep 2;
27989
27990     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27991     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27992
27993     return 0
27994 }
27995 run_test 423 "statfs should return a right data"
27996
27997 test_424() {
27998 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27999         $LCTL set_param fail_loc=0x80000522
28000         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
28001         rm -f $DIR/$tfile
28002 }
28003 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
28004
28005 test_425() {
28006         test_mkdir -c -1 $DIR/$tdir
28007         $LFS setstripe -c -1 $DIR/$tdir
28008
28009         lru_resize_disable "" 100
28010         stack_trap "lru_resize_enable" EXIT
28011
28012         sleep 5
28013
28014         for i in $(seq $((MDSCOUNT * 125))); do
28015                 local t=$DIR/$tdir/$tfile_$i
28016
28017                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
28018                         error_noexit "Create file $t"
28019         done
28020         stack_trap "rm -rf $DIR/$tdir" EXIT
28021
28022         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
28023                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
28024                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
28025
28026                 [ $lock_count -le $lru_size ] ||
28027                         error "osc lock count $lock_count > lru size $lru_size"
28028         done
28029
28030         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
28031                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
28032                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
28033
28034                 [ $lock_count -le $lru_size ] ||
28035                         error "mdc lock count $lock_count > lru size $lru_size"
28036         done
28037 }
28038 run_test 425 "lock count should not exceed lru size"
28039
28040 test_426() {
28041         splice-test -r $DIR/$tfile
28042         splice-test -rd $DIR/$tfile
28043         splice-test $DIR/$tfile
28044         splice-test -d $DIR/$tfile
28045 }
28046 run_test 426 "splice test on Lustre"
28047
28048 test_427() {
28049         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
28050         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
28051                 skip "Need MDS version at least 2.12.4"
28052         local log
28053
28054         mkdir $DIR/$tdir
28055         mkdir $DIR/$tdir/1
28056         mkdir $DIR/$tdir/2
28057         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
28058         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
28059
28060         $LFS getdirstripe $DIR/$tdir/1/dir
28061
28062         #first setfattr for creating updatelog
28063         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
28064
28065 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
28066         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
28067         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
28068         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
28069
28070         sleep 2
28071         fail mds2
28072         wait_recovery_complete mds2 $((2*TIMEOUT))
28073
28074         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
28075         echo $log | grep "get update log failed" &&
28076                 error "update log corruption is detected" || true
28077 }
28078 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
28079
28080 test_428() {
28081         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28082         local cache_limit=$CACHE_MAX
28083
28084         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
28085         $LCTL set_param -n llite.*.max_cached_mb=64
28086
28087         mkdir $DIR/$tdir
28088         $LFS setstripe -c 1 $DIR/$tdir
28089         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
28090         stack_trap "rm -f $DIR/$tdir/$tfile.*"
28091         #test write
28092         for f in $(seq 4); do
28093                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
28094         done
28095         wait
28096
28097         cancel_lru_locks osc
28098         # Test read
28099         for f in $(seq 4); do
28100                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
28101         done
28102         wait
28103 }
28104 run_test 428 "large block size IO should not hang"
28105
28106 test_429() { # LU-7915 / LU-10948
28107         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
28108         local testfile=$DIR/$tfile
28109         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
28110         local new_flag=1
28111         local first_rpc
28112         local second_rpc
28113         local third_rpc
28114
28115         $LCTL get_param $ll_opencache_threshold_count ||
28116                 skip "client does not have opencache parameter"
28117
28118         set_opencache $new_flag
28119         stack_trap "restore_opencache"
28120         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
28121                 error "enable opencache failed"
28122         touch $testfile
28123         # drop MDC DLM locks
28124         cancel_lru_locks mdc
28125         # clear MDC RPC stats counters
28126         $LCTL set_param $mdc_rpcstats=clear
28127
28128         # According to the current implementation, we need to run 3 times
28129         # open & close file to verify if opencache is enabled correctly.
28130         # 1st, RPCs are sent for lookup/open and open handle is released on
28131         #      close finally.
28132         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28133         #      so open handle won't be released thereafter.
28134         # 3rd, No RPC is sent out.
28135         $MULTIOP $testfile oc || error "multiop failed"
28136         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28137         echo "1st: $first_rpc RPCs in flight"
28138
28139         $MULTIOP $testfile oc || error "multiop failed"
28140         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28141         echo "2nd: $second_rpc RPCs in flight"
28142
28143         $MULTIOP $testfile oc || error "multiop failed"
28144         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28145         echo "3rd: $third_rpc RPCs in flight"
28146
28147         #verify no MDC RPC is sent
28148         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28149 }
28150 run_test 429 "verify if opencache flag on client side does work"
28151
28152 lseek_test_430() {
28153         local offset
28154         local file=$1
28155
28156         # data at [200K, 400K)
28157         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28158                 error "256K->512K dd fails"
28159         # data at [2M, 3M)
28160         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28161                 error "2M->3M dd fails"
28162         # data at [4M, 5M)
28163         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28164                 error "4M->5M dd fails"
28165         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28166         # start at first component hole #1
28167         printf "Seeking hole from 1000 ... "
28168         offset=$(lseek_test -l 1000 $file)
28169         echo $offset
28170         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28171         printf "Seeking data from 1000 ... "
28172         offset=$(lseek_test -d 1000 $file)
28173         echo $offset
28174         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28175
28176         # start at first component data block
28177         printf "Seeking hole from 300000 ... "
28178         offset=$(lseek_test -l 300000 $file)
28179         echo $offset
28180         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28181         printf "Seeking data from 300000 ... "
28182         offset=$(lseek_test -d 300000 $file)
28183         echo $offset
28184         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28185
28186         # start at the first component but beyond end of object size
28187         printf "Seeking hole from 1000000 ... "
28188         offset=$(lseek_test -l 1000000 $file)
28189         echo $offset
28190         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28191         printf "Seeking data from 1000000 ... "
28192         offset=$(lseek_test -d 1000000 $file)
28193         echo $offset
28194         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28195
28196         # start at second component stripe 2 (empty file)
28197         printf "Seeking hole from 1500000 ... "
28198         offset=$(lseek_test -l 1500000 $file)
28199         echo $offset
28200         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28201         printf "Seeking data from 1500000 ... "
28202         offset=$(lseek_test -d 1500000 $file)
28203         echo $offset
28204         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28205
28206         # start at second component stripe 1 (all data)
28207         printf "Seeking hole from 3000000 ... "
28208         offset=$(lseek_test -l 3000000 $file)
28209         echo $offset
28210         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28211         printf "Seeking data from 3000000 ... "
28212         offset=$(lseek_test -d 3000000 $file)
28213         echo $offset
28214         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28215
28216         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28217                 error "2nd dd fails"
28218         echo "Add data block at 640K...1280K"
28219
28220         # start at before new data block, in hole
28221         printf "Seeking hole from 600000 ... "
28222         offset=$(lseek_test -l 600000 $file)
28223         echo $offset
28224         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28225         printf "Seeking data from 600000 ... "
28226         offset=$(lseek_test -d 600000 $file)
28227         echo $offset
28228         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28229
28230         # start at the first component new data block
28231         printf "Seeking hole from 1000000 ... "
28232         offset=$(lseek_test -l 1000000 $file)
28233         echo $offset
28234         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28235         printf "Seeking data from 1000000 ... "
28236         offset=$(lseek_test -d 1000000 $file)
28237         echo $offset
28238         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28239
28240         # start at second component stripe 2, new data
28241         printf "Seeking hole from 1200000 ... "
28242         offset=$(lseek_test -l 1200000 $file)
28243         echo $offset
28244         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28245         printf "Seeking data from 1200000 ... "
28246         offset=$(lseek_test -d 1200000 $file)
28247         echo $offset
28248         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28249
28250         # start beyond file end
28251         printf "Using offset > filesize ... "
28252         lseek_test -l 4000000 $file && error "lseek should fail"
28253         printf "Using offset > filesize ... "
28254         lseek_test -d 4000000 $file && error "lseek should fail"
28255
28256         printf "Done\n\n"
28257 }
28258
28259 test_430a() {
28260         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28261                 skip "MDT does not support SEEK_HOLE"
28262
28263         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28264                 skip "OST does not support SEEK_HOLE"
28265
28266         local file=$DIR/$tdir/$tfile
28267
28268         mkdir -p $DIR/$tdir
28269
28270         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28271         # OST stripe #1 will have continuous data at [1M, 3M)
28272         # OST stripe #2 is empty
28273         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28274         lseek_test_430 $file
28275         rm $file
28276         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28277         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28278         lseek_test_430 $file
28279         rm $file
28280         $LFS setstripe -c2 -S 512K $file
28281         echo "Two stripes, stripe size 512K"
28282         lseek_test_430 $file
28283         rm $file
28284         # FLR with stale mirror
28285         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28286                        -N -c2 -S 1M $file
28287         echo "Mirrored file:"
28288         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28289         echo "Plain 2 stripes 1M"
28290         lseek_test_430 $file
28291         rm $file
28292 }
28293 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28294
28295 test_430b() {
28296         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28297                 skip "OST does not support SEEK_HOLE"
28298
28299         local offset
28300         local file=$DIR/$tdir/$tfile
28301
28302         mkdir -p $DIR/$tdir
28303         # Empty layout lseek should fail
28304         $MCREATE $file
28305         # seek from 0
28306         printf "Seeking hole from 0 ... "
28307         lseek_test -l 0 $file && error "lseek should fail"
28308         printf "Seeking data from 0 ... "
28309         lseek_test -d 0 $file && error "lseek should fail"
28310         rm $file
28311
28312         # 1M-hole file
28313         $LFS setstripe -E 1M -c2 -E eof $file
28314         $TRUNCATE $file 1048576
28315         printf "Seeking hole from 1000000 ... "
28316         offset=$(lseek_test -l 1000000 $file)
28317         echo $offset
28318         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28319         printf "Seeking data from 1000000 ... "
28320         lseek_test -d 1000000 $file && error "lseek should fail"
28321         rm $file
28322
28323         # full component followed by non-inited one
28324         $LFS setstripe -E 1M -c2 -E eof $file
28325         dd if=/dev/urandom of=$file bs=1M count=1
28326         printf "Seeking hole from 1000000 ... "
28327         offset=$(lseek_test -l 1000000 $file)
28328         echo $offset
28329         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28330         printf "Seeking hole from 1048576 ... "
28331         lseek_test -l 1048576 $file && error "lseek should fail"
28332         # init second component and truncate back
28333         echo "123" >> $file
28334         $TRUNCATE $file 1048576
28335         printf "Seeking hole from 1000000 ... "
28336         offset=$(lseek_test -l 1000000 $file)
28337         echo $offset
28338         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28339         printf "Seeking hole from 1048576 ... "
28340         lseek_test -l 1048576 $file && error "lseek should fail"
28341         # boundary checks for big values
28342         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28343         offset=$(lseek_test -d 0 $file.10g)
28344         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28345         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28346         offset=$(lseek_test -d 0 $file.100g)
28347         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28348         return 0
28349 }
28350 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28351
28352 test_430c() {
28353         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28354                 skip "OST does not support SEEK_HOLE"
28355
28356         local file=$DIR/$tdir/$tfile
28357         local start
28358
28359         mkdir -p $DIR/$tdir
28360         stack_trap "rm -f $file $file.tmp"
28361         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M || error "dd failed"
28362
28363         # cp version 8.33+ prefers lseek over fiemap
28364         local ver=$(cp --version | awk '{ print $4; exit; }')
28365
28366         echo "cp $ver installed"
28367         if (( $(version_code $ver) >= $(version_code 8.33) )); then
28368                 start=$SECONDS
28369                 time cp -v $file $file.tmp || error "cp $file failed"
28370                 (( SECONDS - start < 5 )) || {
28371                         strace cp $file $file.tmp |&
28372                                 grep -E "open|read|seek|FIEMAP" |
28373                                 grep -A 100 $file
28374                         error "cp: too long runtime $((SECONDS - start))"
28375                 }
28376         else
28377                 echo "cp test skipped due to $ver < 8.33"
28378         fi
28379
28380         # tar version 1.29+ supports SEEK_HOLE/DATA
28381         ver=$(tar --version | awk '{ print $4; exit; }')
28382         echo "tar $ver installed"
28383         if (( $(version_code $ver) >= $(version_code 1.29) )); then
28384                 start=$SECONDS
28385                 time tar cvf $file.tmp --sparse $file || error "tar $file error"
28386                 (( SECONDS - start < 5 )) || {
28387                         strace tar cf $file.tmp --sparse $file |&
28388                                 grep -E "open|read|seek|FIEMAP" |
28389                                 grep -A 100 $file
28390                         error "tar: too long runtime $((SECONDS - start))"
28391                 }
28392         else
28393                 echo "tar test skipped due to $ver < 1.29"
28394         fi
28395 }
28396 run_test 430c "lseek: external tools check"
28397
28398 test_431() { # LU-14187
28399         local file=$DIR/$tdir/$tfile
28400
28401         mkdir -p $DIR/$tdir
28402         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28403         dd if=/dev/urandom of=$file bs=4k count=1
28404         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28405         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28406         #define OBD_FAIL_OST_RESTART_IO 0x251
28407         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28408         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28409         cp $file $file.0
28410         cancel_lru_locks
28411         sync_all_data
28412         echo 3 > /proc/sys/vm/drop_caches
28413         diff  $file $file.0 || error "data diff"
28414 }
28415 run_test 431 "Restart transaction for IO"
28416
28417 cleanup_test_432() {
28418         do_facet mgs $LCTL nodemap_activate 0
28419         wait_nm_sync active
28420 }
28421
28422 test_432() {
28423         local tmpdir=$TMP/dir432
28424
28425         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28426                 skip "Need MDS version at least 2.14.52"
28427
28428         stack_trap cleanup_test_432 EXIT
28429         mkdir $DIR/$tdir
28430         mkdir $tmpdir
28431
28432         do_facet mgs $LCTL nodemap_activate 1
28433         wait_nm_sync active
28434         do_facet mgs $LCTL nodemap_modify --name default \
28435                 --property admin --value 1
28436         do_facet mgs $LCTL nodemap_modify --name default \
28437                 --property trusted --value 1
28438         cancel_lru_locks mdc
28439         wait_nm_sync default admin_nodemap
28440         wait_nm_sync default trusted_nodemap
28441
28442         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28443                grep -ci "Operation not permitted") -ne 0 ]; then
28444                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28445         fi
28446 }
28447 run_test 432 "mv dir from outside Lustre"
28448
28449 test_433() {
28450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28451
28452         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28453                 skip "inode cache not supported"
28454
28455         $LCTL set_param llite.*.inode_cache=0
28456         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28457
28458         local count=256
28459         local before
28460         local after
28461
28462         cancel_lru_locks mdc
28463         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28464         createmany -m $DIR/$tdir/f $count
28465         createmany -d $DIR/$tdir/d $count
28466         ls -l $DIR/$tdir > /dev/null
28467         stack_trap "rm -rf $DIR/$tdir"
28468
28469         before=$(num_objects)
28470         cancel_lru_locks mdc
28471         after=$(num_objects)
28472
28473         # sometimes even @before is less than 2 * count
28474         while (( before - after < count )); do
28475                 sleep 1
28476                 after=$(num_objects)
28477                 wait=$((wait + 1))
28478                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28479                 if (( wait > 60 )); then
28480                         error "inode slab grew from $before to $after"
28481                 fi
28482         done
28483
28484         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28485 }
28486 run_test 433 "ldlm lock cancel releases dentries and inodes"
28487
28488 test_434() {
28489         local file
28490         local getxattr_count
28491         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28492         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28493
28494         [[ $(getenforce) == "Disabled" ]] ||
28495                 skip "lsm selinux module have to be disabled for this test"
28496
28497         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28498                 error "fail to create $DIR/$tdir/ on MDT0000"
28499
28500         touch $DIR/$tdir/$tfile-{001..100}
28501
28502         # disable the xattr cache
28503         save_lustre_params client "llite.*.xattr_cache" > $p
28504         lctl set_param llite.*.xattr_cache=0
28505         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28506
28507         # clear clients mdc stats
28508         clear_stats $mdc_stat_param ||
28509                 error "fail to clear stats on mdc MDT0000"
28510
28511         for file in $DIR/$tdir/$tfile-{001..100}; do
28512                 getfattr -n security.selinux $file |&
28513                         grep -q "Operation not supported" ||
28514                         error "getxattr on security.selinux should return EOPNOTSUPP"
28515         done
28516
28517         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28518         (( getxattr_count < 100 )) ||
28519                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28520 }
28521 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28522
28523 test_440() {
28524         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28525                 source $LUSTRE/scripts/bash-completion/lustre
28526         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28527                 source /usr/share/bash-completion/completions/lustre
28528         else
28529                 skip "bash completion scripts not found"
28530         fi
28531
28532         local lctl_completions
28533         local lfs_completions
28534
28535         lctl_completions=$(_lustre_cmds lctl)
28536         if [[ ! $lctl_completions =~ "get_param" ]]; then
28537                 error "lctl bash completion failed"
28538         fi
28539
28540         lfs_completions=$(_lustre_cmds lfs)
28541         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28542                 error "lfs bash completion failed"
28543         fi
28544 }
28545 run_test 440 "bash completion for lfs, lctl"
28546
28547 prep_801() {
28548         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28549         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28550                 skip "Need server version at least 2.9.55"
28551
28552         start_full_debug_logging
28553 }
28554
28555 post_801() {
28556         stop_full_debug_logging
28557 }
28558
28559 barrier_stat() {
28560         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28561                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28562                            awk '/The barrier for/ { print $7 }')
28563                 echo $st
28564         else
28565                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28566                 echo \'$st\'
28567         fi
28568 }
28569
28570 barrier_expired() {
28571         local expired
28572
28573         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28574                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28575                           awk '/will be expired/ { print $7 }')
28576         else
28577                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28578         fi
28579
28580         echo $expired
28581 }
28582
28583 test_801a() {
28584         prep_801
28585
28586         echo "Start barrier_freeze at: $(date)"
28587         #define OBD_FAIL_BARRIER_DELAY          0x2202
28588         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28589         # Do not reduce barrier time - See LU-11873
28590         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28591
28592         sleep 2
28593         local b_status=$(barrier_stat)
28594         echo "Got barrier status at: $(date)"
28595         [ "$b_status" = "'freezing_p1'" ] ||
28596                 error "(1) unexpected barrier status $b_status"
28597
28598         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28599         wait
28600         b_status=$(barrier_stat)
28601         [ "$b_status" = "'frozen'" ] ||
28602                 error "(2) unexpected barrier status $b_status"
28603
28604         local expired=$(barrier_expired)
28605         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28606         sleep $((expired + 3))
28607
28608         b_status=$(barrier_stat)
28609         [ "$b_status" = "'expired'" ] ||
28610                 error "(3) unexpected barrier status $b_status"
28611
28612         # Do not reduce barrier time - See LU-11873
28613         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28614                 error "(4) fail to freeze barrier"
28615
28616         b_status=$(barrier_stat)
28617         [ "$b_status" = "'frozen'" ] ||
28618                 error "(5) unexpected barrier status $b_status"
28619
28620         echo "Start barrier_thaw at: $(date)"
28621         #define OBD_FAIL_BARRIER_DELAY          0x2202
28622         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28623         do_facet mgs $LCTL barrier_thaw $FSNAME &
28624
28625         sleep 2
28626         b_status=$(barrier_stat)
28627         echo "Got barrier status at: $(date)"
28628         [ "$b_status" = "'thawing'" ] ||
28629                 error "(6) unexpected barrier status $b_status"
28630
28631         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28632         wait
28633         b_status=$(barrier_stat)
28634         [ "$b_status" = "'thawed'" ] ||
28635                 error "(7) unexpected barrier status $b_status"
28636
28637         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28638         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28639         do_facet mgs $LCTL barrier_freeze $FSNAME
28640
28641         b_status=$(barrier_stat)
28642         [ "$b_status" = "'failed'" ] ||
28643                 error "(8) unexpected barrier status $b_status"
28644
28645         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28646         do_facet mgs $LCTL barrier_thaw $FSNAME
28647
28648         post_801
28649 }
28650 run_test 801a "write barrier user interfaces and stat machine"
28651
28652 test_801b() {
28653         prep_801
28654
28655         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28656         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28657         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28658         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28659         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28660
28661         cancel_lru_locks mdc
28662
28663         # 180 seconds should be long enough
28664         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28665
28666         local b_status=$(barrier_stat)
28667         [ "$b_status" = "'frozen'" ] ||
28668                 error "(6) unexpected barrier status $b_status"
28669
28670         mkdir $DIR/$tdir/d0/d10 &
28671         mkdir_pid=$!
28672
28673         touch $DIR/$tdir/d1/f13 &
28674         touch_pid=$!
28675
28676         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28677         ln_pid=$!
28678
28679         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28680         mv_pid=$!
28681
28682         rm -f $DIR/$tdir/d4/f12 &
28683         rm_pid=$!
28684
28685         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28686
28687         # To guarantee taht the 'stat' is not blocked
28688         b_status=$(barrier_stat)
28689         [ "$b_status" = "'frozen'" ] ||
28690                 error "(8) unexpected barrier status $b_status"
28691
28692         # let above commands to run at background
28693         sleep 5
28694
28695         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28696         ps -p $touch_pid || error "(10) touch should be blocked"
28697         ps -p $ln_pid || error "(11) link should be blocked"
28698         ps -p $mv_pid || error "(12) rename should be blocked"
28699         ps -p $rm_pid || error "(13) unlink should be blocked"
28700
28701         b_status=$(barrier_stat)
28702         [ "$b_status" = "'frozen'" ] ||
28703                 error "(14) unexpected barrier status $b_status"
28704
28705         do_facet mgs $LCTL barrier_thaw $FSNAME
28706         b_status=$(barrier_stat)
28707         [ "$b_status" = "'thawed'" ] ||
28708                 error "(15) unexpected barrier status $b_status"
28709
28710         wait $mkdir_pid || error "(16) mkdir should succeed"
28711         wait $touch_pid || error "(17) touch should succeed"
28712         wait $ln_pid || error "(18) link should succeed"
28713         wait $mv_pid || error "(19) rename should succeed"
28714         wait $rm_pid || error "(20) unlink should succeed"
28715
28716         post_801
28717 }
28718 run_test 801b "modification will be blocked by write barrier"
28719
28720 test_801c() {
28721         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28722
28723         prep_801
28724
28725         stop mds2 || error "(1) Fail to stop mds2"
28726
28727         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28728
28729         local b_status=$(barrier_stat)
28730         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28731                 do_facet mgs $LCTL barrier_thaw $FSNAME
28732                 error "(2) unexpected barrier status $b_status"
28733         }
28734
28735         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28736                 error "(3) Fail to rescan barrier bitmap"
28737
28738         # Do not reduce barrier time - See LU-11873
28739         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28740
28741         b_status=$(barrier_stat)
28742         [ "$b_status" = "'frozen'" ] ||
28743                 error "(4) unexpected barrier status $b_status"
28744
28745         do_facet mgs $LCTL barrier_thaw $FSNAME
28746         b_status=$(barrier_stat)
28747         [ "$b_status" = "'thawed'" ] ||
28748                 error "(5) unexpected barrier status $b_status"
28749
28750         local devname=$(mdsdevname 2)
28751
28752         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28753
28754         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28755                 error "(7) Fail to rescan barrier bitmap"
28756
28757         post_801
28758 }
28759 run_test 801c "rescan barrier bitmap"
28760
28761 test_802b() {
28762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28763         remote_mds_nodsh && skip "remote MDS with nodsh"
28764
28765         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28766                 skip "readonly option not available"
28767
28768         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28769
28770         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28771                 error "(2) Fail to copy"
28772
28773         # write back all cached data before setting MDT to readonly
28774         cancel_lru_locks
28775         sync_all_data
28776
28777         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28778         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28779
28780         echo "Modify should be refused"
28781         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28782
28783         echo "Read should be allowed"
28784         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28785                 error "(7) Read should succeed under ro mode"
28786
28787         # disable readonly
28788         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28789 }
28790 run_test 802b "be able to set MDTs to readonly"
28791
28792 test_803a() {
28793         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28794         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28795                 skip "MDS needs to be newer than 2.10.54"
28796
28797         mkdir_on_mdt0 $DIR/$tdir
28798         # Create some objects on all MDTs to trigger related logs objects
28799         for idx in $(seq $MDSCOUNT); do
28800                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28801                         $DIR/$tdir/dir${idx} ||
28802                         error "Fail to create $DIR/$tdir/dir${idx}"
28803         done
28804
28805         wait_delete_completed # ensure old test cleanups are finished
28806         sleep 3
28807         echo "before create:"
28808         $LFS df -i $MOUNT
28809         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28810
28811         for i in {1..10}; do
28812                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28813                         error "Fail to create $DIR/$tdir/foo$i"
28814         done
28815
28816         # sync ZFS-on-MDS to refresh statfs data
28817         wait_zfs_commit mds1
28818         sleep 3
28819         echo "after create:"
28820         $LFS df -i $MOUNT
28821         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28822
28823         # allow for an llog to be cleaned up during the test
28824         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28825                 error "before ($before_used) + 10 > after ($after_used)"
28826
28827         for i in {1..10}; do
28828                 rm -rf $DIR/$tdir/foo$i ||
28829                         error "Fail to remove $DIR/$tdir/foo$i"
28830         done
28831
28832         # sync ZFS-on-MDS to refresh statfs data
28833         wait_zfs_commit mds1
28834         wait_delete_completed
28835         sleep 3 # avoid MDT return cached statfs
28836         echo "after unlink:"
28837         $LFS df -i $MOUNT
28838         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28839
28840         # allow for an llog to be created during the test
28841         [ $after_used -le $((before_used + 1)) ] ||
28842                 error "after ($after_used) > before ($before_used) + 1"
28843 }
28844 run_test 803a "verify agent object for remote object"
28845
28846 test_803b() {
28847         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28848         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28849                 skip "MDS needs to be newer than 2.13.56"
28850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28851
28852         for i in $(seq 0 $((MDSCOUNT - 1))); do
28853                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28854         done
28855
28856         local before=0
28857         local after=0
28858
28859         local tmp
28860
28861         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28862         for i in $(seq 0 $((MDSCOUNT - 1))); do
28863                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28864                         awk '/getattr/ { print $2 }')
28865                 before=$((before + tmp))
28866         done
28867         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28868         for i in $(seq 0 $((MDSCOUNT - 1))); do
28869                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28870                         awk '/getattr/ { print $2 }')
28871                 after=$((after + tmp))
28872         done
28873
28874         [ $before -eq $after ] || error "getattr count $before != $after"
28875 }
28876 run_test 803b "remote object can getattr from cache"
28877
28878 test_804() {
28879         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28880         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28881                 skip "MDS needs to be newer than 2.10.54"
28882         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28883
28884         mkdir -p $DIR/$tdir
28885         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28886                 error "Fail to create $DIR/$tdir/dir0"
28887
28888         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28889         local dev=$(mdsdevname 2)
28890
28891         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28892                 grep ${fid} || error "NOT found agent entry for dir0"
28893
28894         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28895                 error "Fail to create $DIR/$tdir/dir1"
28896
28897         touch $DIR/$tdir/dir1/foo0 ||
28898                 error "Fail to create $DIR/$tdir/dir1/foo0"
28899         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28900         local rc=0
28901
28902         for idx in $(seq $MDSCOUNT); do
28903                 dev=$(mdsdevname $idx)
28904                 do_facet mds${idx} \
28905                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28906                         grep ${fid} && rc=$idx
28907         done
28908
28909         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28910                 error "Fail to rename foo0 to foo1"
28911         if [ $rc -eq 0 ]; then
28912                 for idx in $(seq $MDSCOUNT); do
28913                         dev=$(mdsdevname $idx)
28914                         do_facet mds${idx} \
28915                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28916                         grep ${fid} && rc=$idx
28917                 done
28918         fi
28919
28920         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28921                 error "Fail to rename foo1 to foo2"
28922         if [ $rc -eq 0 ]; then
28923                 for idx in $(seq $MDSCOUNT); do
28924                         dev=$(mdsdevname $idx)
28925                         do_facet mds${idx} \
28926                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28927                         grep ${fid} && rc=$idx
28928                 done
28929         fi
28930
28931         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28932
28933         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28934                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28935         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28936                 error "Fail to rename foo2 to foo0"
28937         unlink $DIR/$tdir/dir1/foo0 ||
28938                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28939         rm -rf $DIR/$tdir/dir0 ||
28940                 error "Fail to rm $DIR/$tdir/dir0"
28941
28942         for idx in $(seq $MDSCOUNT); do
28943                 rc=0
28944
28945                 stop mds${idx}
28946                 dev=$(mdsdevname $idx)
28947                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28948                         rc=$?
28949                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28950                         error "mount mds$idx failed"
28951                 df $MOUNT > /dev/null 2>&1
28952
28953                 # e2fsck should not return error
28954                 [ $rc -eq 0 ] ||
28955                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28956         done
28957 }
28958 run_test 804 "verify agent entry for remote entry"
28959
28960 cleanup_805() {
28961         do_facet $SINGLEMDS zfs set quota=$old $fsset
28962         unlinkmany $DIR/$tdir/f- 1000000
28963         trap 0
28964 }
28965
28966 test_805() {
28967         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28968         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28969         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28970                 skip "netfree not implemented before 0.7"
28971         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28972                 skip "Need MDS version at least 2.10.57"
28973
28974         local fsset
28975         local freekb
28976         local usedkb
28977         local old
28978         local quota
28979         local pref="osd-zfs.$FSNAME-MDT0000."
28980
28981         # limit available space on MDS dataset to meet nospace issue
28982         # quickly. then ZFS 0.7.2 can use reserved space if asked
28983         # properly (using netfree flag in osd_declare_destroy()
28984         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28985         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28986                 gawk '{print $3}')
28987         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28988         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28989         let "usedkb=usedkb-freekb"
28990         let "freekb=freekb/2"
28991         if let "freekb > 5000"; then
28992                 let "freekb=5000"
28993         fi
28994         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28995         trap cleanup_805 EXIT
28996         mkdir_on_mdt0 $DIR/$tdir
28997         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28998                 error "Can't set PFL layout"
28999         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
29000         rm -rf $DIR/$tdir || error "not able to remove"
29001         do_facet $SINGLEMDS zfs set quota=$old $fsset
29002         trap 0
29003 }
29004 run_test 805 "ZFS can remove from full fs"
29005
29006 # Size-on-MDS test
29007 check_lsom_data()
29008 {
29009         local file=$1
29010         local expect=$(stat -c %s $file)
29011
29012         check_lsom_size $1 $expect
29013
29014         local blocks=$($LFS getsom -b $file)
29015         expect=$(stat -c %b $file)
29016         [[ $blocks == $expect ]] ||
29017                 error "$file expected blocks: $expect, got: $blocks"
29018 }
29019
29020 check_lsom_size()
29021 {
29022         local size
29023         local expect=$2
29024
29025         cancel_lru_locks mdc
29026
29027         size=$($LFS getsom -s $1)
29028         [[ $size == $expect ]] ||
29029                 error "$file expected size: $expect, got: $size"
29030 }
29031
29032 test_806() {
29033         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29034                 skip "Need MDS version at least 2.11.52"
29035
29036         local bs=1048576
29037
29038         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
29039
29040         disable_opencache
29041         stack_trap "restore_opencache"
29042
29043         # single-threaded write
29044         echo "Test SOM for single-threaded write"
29045         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
29046                 error "write $tfile failed"
29047         check_lsom_size $DIR/$tfile $bs
29048
29049         local num=32
29050         local size=$(($num * $bs))
29051         local offset=0
29052         local i
29053
29054         echo "Test SOM for single client multi-threaded($num) write"
29055         $TRUNCATE $DIR/$tfile 0
29056         for ((i = 0; i < $num; i++)); do
29057                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29058                 local pids[$i]=$!
29059                 offset=$((offset + $bs))
29060         done
29061         for (( i=0; i < $num; i++ )); do
29062                 wait ${pids[$i]}
29063         done
29064         check_lsom_size $DIR/$tfile $size
29065
29066         $TRUNCATE $DIR/$tfile 0
29067         for ((i = 0; i < $num; i++)); do
29068                 offset=$((offset - $bs))
29069                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29070                 local pids[$i]=$!
29071         done
29072         for (( i=0; i < $num; i++ )); do
29073                 wait ${pids[$i]}
29074         done
29075         check_lsom_size $DIR/$tfile $size
29076
29077         # multi-client writes
29078         num=$(get_node_count ${CLIENTS//,/ })
29079         size=$(($num * $bs))
29080         offset=0
29081         i=0
29082
29083         echo "Test SOM for multi-client ($num) writes"
29084         $TRUNCATE $DIR/$tfile 0
29085         for client in ${CLIENTS//,/ }; do
29086                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29087                 local pids[$i]=$!
29088                 i=$((i + 1))
29089                 offset=$((offset + $bs))
29090         done
29091         for (( i=0; i < $num; i++ )); do
29092                 wait ${pids[$i]}
29093         done
29094         check_lsom_size $DIR/$tfile $offset
29095
29096         i=0
29097         $TRUNCATE $DIR/$tfile 0
29098         for client in ${CLIENTS//,/ }; do
29099                 offset=$((offset - $bs))
29100                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29101                 local pids[$i]=$!
29102                 i=$((i + 1))
29103         done
29104         for (( i=0; i < $num; i++ )); do
29105                 wait ${pids[$i]}
29106         done
29107         check_lsom_size $DIR/$tfile $size
29108
29109         # verify SOM blocks count
29110         echo "Verify SOM block count"
29111         $TRUNCATE $DIR/$tfile 0
29112         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
29113                 error "failed to write file $tfile with fdatasync and fstat"
29114         check_lsom_data $DIR/$tfile
29115
29116         $TRUNCATE $DIR/$tfile 0
29117         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
29118                 error "failed to write file $tfile with fdatasync"
29119         check_lsom_data $DIR/$tfile
29120
29121         $TRUNCATE $DIR/$tfile 0
29122         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
29123                 error "failed to write file $tfile with sync IO"
29124         check_lsom_data $DIR/$tfile
29125
29126         # verify truncate
29127         echo "Test SOM for truncate"
29128         # use ftruncate to sync blocks on close request
29129         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
29130         check_lsom_size $DIR/$tfile 16384
29131         check_lsom_data $DIR/$tfile
29132
29133         $TRUNCATE $DIR/$tfile 1234
29134         check_lsom_size $DIR/$tfile 1234
29135         # sync blocks on the MDT
29136         $MULTIOP $DIR/$tfile oc
29137         check_lsom_data $DIR/$tfile
29138 }
29139 run_test 806 "Verify Lazy Size on MDS"
29140
29141 test_807() {
29142         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
29143         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
29144                 skip "Need MDS version at least 2.11.52"
29145
29146         # Registration step
29147         changelog_register || error "changelog_register failed"
29148         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29149         changelog_users $SINGLEMDS | grep -q $cl_user ||
29150                 error "User $cl_user not found in changelog_users"
29151
29152         rm -rf $DIR/$tdir || error "rm $tdir failed"
29153         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29154         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29155         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29156         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29157                 error "truncate $tdir/trunc failed"
29158
29159         local bs=1048576
29160         echo "Test SOM for single-threaded write with fsync"
29161         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29162                 error "write $tfile failed"
29163         sync;sync;sync
29164
29165         # multi-client wirtes
29166         local num=$(get_node_count ${CLIENTS//,/ })
29167         local offset=0
29168         local i=0
29169
29170         echo "Test SOM for multi-client ($num) writes"
29171         touch $DIR/$tfile || error "touch $tfile failed"
29172         $TRUNCATE $DIR/$tfile 0
29173         for client in ${CLIENTS//,/ }; do
29174                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29175                 local pids[$i]=$!
29176                 i=$((i + 1))
29177                 offset=$((offset + $bs))
29178         done
29179         for (( i=0; i < $num; i++ )); do
29180                 wait ${pids[$i]}
29181         done
29182
29183         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29184         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29185         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29186         check_lsom_data $DIR/$tdir/trunc
29187         check_lsom_data $DIR/$tdir/single_dd
29188         check_lsom_data $DIR/$tfile
29189
29190         rm -rf $DIR/$tdir
29191         # Deregistration step
29192         changelog_deregister || error "changelog_deregister failed"
29193 }
29194 run_test 807 "verify LSOM syncing tool"
29195
29196 check_som_nologged()
29197 {
29198         local lines=$($LFS changelog $FSNAME-MDT0000 |
29199                 grep 'x=trusted.som' | wc -l)
29200         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29201 }
29202
29203 test_808() {
29204         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29205                 skip "Need MDS version at least 2.11.55"
29206
29207         # Registration step
29208         changelog_register || error "changelog_register failed"
29209
29210         touch $DIR/$tfile || error "touch $tfile failed"
29211         check_som_nologged
29212
29213         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29214                 error "write $tfile failed"
29215         check_som_nologged
29216
29217         $TRUNCATE $DIR/$tfile 1234
29218         check_som_nologged
29219
29220         $TRUNCATE $DIR/$tfile 1048576
29221         check_som_nologged
29222
29223         # Deregistration step
29224         changelog_deregister || error "changelog_deregister failed"
29225 }
29226 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29227
29228 check_som_nodata()
29229 {
29230         $LFS getsom $1
29231         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29232 }
29233
29234 test_809() {
29235         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29236                 skip "Need MDS version at least 2.11.56"
29237
29238         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29239                 error "failed to create DoM-only file $DIR/$tfile"
29240         touch $DIR/$tfile || error "touch $tfile failed"
29241         check_som_nodata $DIR/$tfile
29242
29243         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29244                 error "write $tfile failed"
29245         check_som_nodata $DIR/$tfile
29246
29247         $TRUNCATE $DIR/$tfile 1234
29248         check_som_nodata $DIR/$tfile
29249
29250         $TRUNCATE $DIR/$tfile 4097
29251         check_som_nodata $DIR/$file
29252 }
29253 run_test 809 "Verify no SOM xattr store for DoM-only files"
29254
29255 test_810() {
29256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29257         $GSS && skip_env "could not run with gss"
29258         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29259                 skip "OST < 2.12.58 doesn't align checksum"
29260
29261         set_checksums 1
29262         stack_trap "set_checksums $ORIG_CSUM" EXIT
29263         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29264
29265         local csum
29266         local before
29267         local after
29268         for csum in $CKSUM_TYPES; do
29269                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29270                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29271                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29272                         eval set -- $i
29273                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29274                         before=$(md5sum $DIR/$tfile)
29275                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29276                         after=$(md5sum $DIR/$tfile)
29277                         [ "$before" == "$after" ] ||
29278                                 error "$csum: $before != $after bs=$1 seek=$2"
29279                 done
29280         done
29281 }
29282 run_test 810 "partial page writes on ZFS (LU-11663)"
29283
29284 test_812a() {
29285         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29286                 skip "OST < 2.12.51 doesn't support this fail_loc"
29287
29288         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29289         # ensure ost1 is connected
29290         stat $DIR/$tfile >/dev/null || error "can't stat"
29291         wait_osc_import_state client ost1 FULL
29292         # no locks, no reqs to let the connection idle
29293         cancel_lru_locks osc
29294
29295         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29296 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29297         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29298         wait_osc_import_state client ost1 CONNECTING
29299         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29300
29301         stat $DIR/$tfile >/dev/null || error "can't stat file"
29302 }
29303 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29304
29305 test_812b() { # LU-12378
29306         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29307                 skip "OST < 2.12.51 doesn't support this fail_loc"
29308
29309         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29310         # ensure ost1 is connected
29311         stat $DIR/$tfile >/dev/null || error "can't stat"
29312         wait_osc_import_state client ost1 FULL
29313         # no locks, no reqs to let the connection idle
29314         cancel_lru_locks osc
29315
29316         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29317 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29318         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29319         wait_osc_import_state client ost1 CONNECTING
29320         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29321
29322         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29323         wait_osc_import_state client ost1 IDLE
29324 }
29325 run_test 812b "do not drop no resend request for idle connect"
29326
29327 test_812c() {
29328         local old
29329
29330         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29331
29332         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29333         $LFS getstripe $DIR/$tfile
29334         $LCTL set_param osc.*.idle_timeout=10
29335         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29336         # ensure ost1 is connected
29337         stat $DIR/$tfile >/dev/null || error "can't stat"
29338         wait_osc_import_state client ost1 FULL
29339         # no locks, no reqs to let the connection idle
29340         cancel_lru_locks osc
29341
29342 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29343         $LCTL set_param fail_loc=0x80000533
29344         sleep 15
29345         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29346 }
29347 run_test 812c "idle import vs lock enqueue race"
29348
29349 test_813() {
29350         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29351         [ -z "$file_heat_sav" ] && skip "no file heat support"
29352
29353         local readsample
29354         local writesample
29355         local readbyte
29356         local writebyte
29357         local readsample1
29358         local writesample1
29359         local readbyte1
29360         local writebyte1
29361
29362         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29363         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29364
29365         $LCTL set_param -n llite.*.file_heat=1
29366         echo "Turn on file heat"
29367         echo "Period second: $period_second, Decay percentage: $decay_pct"
29368
29369         echo "QQQQ" > $DIR/$tfile
29370         echo "QQQQ" > $DIR/$tfile
29371         echo "QQQQ" > $DIR/$tfile
29372         cat $DIR/$tfile > /dev/null
29373         cat $DIR/$tfile > /dev/null
29374         cat $DIR/$tfile > /dev/null
29375         cat $DIR/$tfile > /dev/null
29376
29377         local out=$($LFS heat_get $DIR/$tfile)
29378
29379         $LFS heat_get $DIR/$tfile
29380         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29381         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29382         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29383         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29384
29385         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29386         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29387         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29388         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29389
29390         sleep $((period_second + 3))
29391         echo "Sleep $((period_second + 3)) seconds..."
29392         # The recursion formula to calculate the heat of the file f is as
29393         # follow:
29394         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29395         # Where Hi is the heat value in the period between time points i*I and
29396         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29397         # to the weight of Ci.
29398         out=$($LFS heat_get $DIR/$tfile)
29399         $LFS heat_get $DIR/$tfile
29400         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29401         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29402         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29403         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29404
29405         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29406                 error "read sample ($readsample) is wrong"
29407         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29408                 error "write sample ($writesample) is wrong"
29409         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29410                 error "read bytes ($readbyte) is wrong"
29411         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29412                 error "write bytes ($writebyte) is wrong"
29413
29414         echo "QQQQ" > $DIR/$tfile
29415         echo "QQQQ" > $DIR/$tfile
29416         echo "QQQQ" > $DIR/$tfile
29417         cat $DIR/$tfile > /dev/null
29418         cat $DIR/$tfile > /dev/null
29419         cat $DIR/$tfile > /dev/null
29420         cat $DIR/$tfile > /dev/null
29421
29422         sleep $((period_second + 3))
29423         echo "Sleep $((period_second + 3)) seconds..."
29424
29425         out=$($LFS heat_get $DIR/$tfile)
29426         $LFS heat_get $DIR/$tfile
29427         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29428         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29429         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29430         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29431
29432         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29433                 4 * $decay_pct) / 100") -eq 1 ] ||
29434                 error "read sample ($readsample1) is wrong"
29435         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29436                 3 * $decay_pct) / 100") -eq 1 ] ||
29437                 error "write sample ($writesample1) is wrong"
29438         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29439                 20 * $decay_pct) / 100") -eq 1 ] ||
29440                 error "read bytes ($readbyte1) is wrong"
29441         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29442                 15 * $decay_pct) / 100") -eq 1 ] ||
29443                 error "write bytes ($writebyte1) is wrong"
29444
29445         echo "Turn off file heat for the file $DIR/$tfile"
29446         $LFS heat_set -o $DIR/$tfile
29447
29448         echo "QQQQ" > $DIR/$tfile
29449         echo "QQQQ" > $DIR/$tfile
29450         echo "QQQQ" > $DIR/$tfile
29451         cat $DIR/$tfile > /dev/null
29452         cat $DIR/$tfile > /dev/null
29453         cat $DIR/$tfile > /dev/null
29454         cat $DIR/$tfile > /dev/null
29455
29456         out=$($LFS heat_get $DIR/$tfile)
29457         $LFS heat_get $DIR/$tfile
29458         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29459         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29460         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29461         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29462
29463         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29464         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29465         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29466         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29467
29468         echo "Trun on file heat for the file $DIR/$tfile"
29469         $LFS heat_set -O $DIR/$tfile
29470
29471         echo "QQQQ" > $DIR/$tfile
29472         echo "QQQQ" > $DIR/$tfile
29473         echo "QQQQ" > $DIR/$tfile
29474         cat $DIR/$tfile > /dev/null
29475         cat $DIR/$tfile > /dev/null
29476         cat $DIR/$tfile > /dev/null
29477         cat $DIR/$tfile > /dev/null
29478
29479         out=$($LFS heat_get $DIR/$tfile)
29480         $LFS heat_get $DIR/$tfile
29481         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29482         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29483         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29484         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29485
29486         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29487         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29488         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29489         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29490
29491         $LFS heat_set -c $DIR/$tfile
29492         $LCTL set_param -n llite.*.file_heat=0
29493         echo "Turn off file heat support for the Lustre filesystem"
29494
29495         echo "QQQQ" > $DIR/$tfile
29496         echo "QQQQ" > $DIR/$tfile
29497         echo "QQQQ" > $DIR/$tfile
29498         cat $DIR/$tfile > /dev/null
29499         cat $DIR/$tfile > /dev/null
29500         cat $DIR/$tfile > /dev/null
29501         cat $DIR/$tfile > /dev/null
29502
29503         out=$($LFS heat_get $DIR/$tfile)
29504         $LFS heat_get $DIR/$tfile
29505         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29506         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29507         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29508         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29509
29510         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29511         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29512         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29513         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29514
29515         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29516         rm -f $DIR/$tfile
29517 }
29518 run_test 813 "File heat verfication"
29519
29520 test_814()
29521 {
29522         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29523         echo -n y >> $DIR/$tfile
29524         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29525         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29526 }
29527 run_test 814 "sparse cp works as expected (LU-12361)"
29528
29529 test_815()
29530 {
29531         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29532         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29533 }
29534 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29535
29536 test_816() {
29537         local ost1_imp=$(get_osc_import_name client ost1)
29538         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29539                          cut -d'.' -f2)
29540
29541         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29542         # ensure ost1 is connected
29543
29544         stat $DIR/$tfile >/dev/null || error "can't stat"
29545         wait_osc_import_state client ost1 FULL
29546         # no locks, no reqs to let the connection idle
29547         cancel_lru_locks osc
29548         lru_resize_disable osc
29549         local before
29550         local now
29551         before=$($LCTL get_param -n \
29552                  ldlm.namespaces.$imp_name.lru_size)
29553
29554         wait_osc_import_state client ost1 IDLE
29555         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29556         now=$($LCTL get_param -n \
29557               ldlm.namespaces.$imp_name.lru_size)
29558         [ $before == $now ] || error "lru_size changed $before != $now"
29559 }
29560 run_test 816 "do not reset lru_resize on idle reconnect"
29561
29562 cleanup_817() {
29563         umount $tmpdir
29564         exportfs -u localhost:$DIR/nfsexp
29565         rm -rf $DIR/nfsexp
29566 }
29567
29568 test_817() {
29569         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29570
29571         mkdir -p $DIR/nfsexp
29572         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29573                 error "failed to export nfs"
29574
29575         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29576         stack_trap cleanup_817 EXIT
29577
29578         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29579                 error "failed to mount nfs to $tmpdir"
29580
29581         cp /bin/true $tmpdir
29582         $DIR/nfsexp/true || error "failed to execute 'true' command"
29583 }
29584 run_test 817 "nfsd won't cache write lock for exec file"
29585
29586 test_818() {
29587         test_mkdir -i0 -c1 $DIR/$tdir
29588         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29589         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29590         stop $SINGLEMDS
29591
29592         # restore osp-syn threads
29593         stack_trap "fail $SINGLEMDS"
29594
29595         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29596         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29597         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29598                 error "start $SINGLEMDS failed"
29599         rm -rf $DIR/$tdir
29600
29601         local testid=$(echo $TESTNAME | tr '_' ' ')
29602
29603         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29604                 grep "run LFSCK" || error "run LFSCK is not suggested"
29605 }
29606 run_test 818 "unlink with failed llog"
29607
29608 test_819a() {
29609         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29610         cancel_lru_locks osc
29611         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29612         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29613         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29614         rm -f $TDIR/$tfile
29615 }
29616 run_test 819a "too big niobuf in read"
29617
29618 test_819b() {
29619         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29620         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29621         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29622         cancel_lru_locks osc
29623         sleep 1
29624         rm -f $TDIR/$tfile
29625 }
29626 run_test 819b "too big niobuf in write"
29627
29628
29629 function test_820_start_ost() {
29630         sleep 5
29631
29632         for num in $(seq $OSTCOUNT); do
29633                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29634         done
29635 }
29636
29637 test_820() {
29638         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29639
29640         mkdir $DIR/$tdir
29641         umount_client $MOUNT || error "umount failed"
29642         for num in $(seq $OSTCOUNT); do
29643                 stop ost$num
29644         done
29645
29646         # mount client with no active OSTs
29647         # so that the client can't initialize max LOV EA size
29648         # from OSC notifications
29649         mount_client $MOUNT || error "mount failed"
29650         # delay OST starting to keep this 0 max EA size for a while
29651         test_820_start_ost &
29652
29653         # create a directory on MDS2
29654         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29655                 error "Failed to create directory"
29656         # open intent should update default EA size
29657         # see mdc_update_max_ea_from_body()
29658         # notice this is the very first RPC to MDS2
29659         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29660         ret=$?
29661         echo $out
29662         # With SSK, this situation can lead to -EPERM being returned.
29663         # In that case, simply retry.
29664         if [ $ret -ne 0 ] && $SHARED_KEY; then
29665                 if echo "$out" | grep -q "not permitted"; then
29666                         cp /etc/services $DIR/$tdir/mds2
29667                         ret=$?
29668                 fi
29669         fi
29670         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29671 }
29672 run_test 820 "update max EA from open intent"
29673
29674 test_823() {
29675         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29676         local OST_MAX_PRECREATE=20000
29677
29678         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29679                 skip "Need MDS version at least 2.14.56"
29680
29681         save_lustre_params mds1 \
29682                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29683         do_facet $SINGLEMDS "$LCTL set_param -n \
29684                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29685         do_facet $SINGLEMDS "$LCTL set_param -n \
29686                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29687
29688         stack_trap "restore_lustre_params < $p; rm $p"
29689
29690         do_facet $SINGLEMDS "$LCTL set_param -n \
29691                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29692
29693         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29694                       osp.$FSNAME-OST0000*MDT0000.create_count")
29695         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29696                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29697         local expect_count=$(((($max/2)/256) * 256))
29698
29699         log "setting create_count to 100200:"
29700         log " -result- count: $count with max: $max, expecting: $expect_count"
29701
29702         [[ $count -eq expect_count ]] ||
29703                 error "Create count not set to max precreate."
29704 }
29705 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29706
29707 test_831() {
29708         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29709                 skip "Need MDS version 2.14.56"
29710
29711         local sync_changes=$(do_facet $SINGLEMDS \
29712                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29713
29714         [ "$sync_changes" -gt 100 ] &&
29715                 skip "Sync changes $sync_changes > 100 already"
29716
29717         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29718
29719         $LFS mkdir -i 0 $DIR/$tdir
29720         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29721
29722         save_lustre_params mds1 \
29723                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29724         save_lustre_params mds1 \
29725                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29726
29727         do_facet mds1 "$LCTL set_param -n \
29728                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29729                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29730         stack_trap "restore_lustre_params < $p" EXIT
29731
29732         createmany -o $DIR/$tdir/f- 1000
29733         unlinkmany $DIR/$tdir/f- 1000 &
29734         local UNLINK_PID=$!
29735
29736         while sleep 1; do
29737                 sync_changes=$(do_facet mds1 \
29738                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29739                 # the check in the code is racy, fail the test
29740                 # if the value above the limit by 10.
29741                 [ $sync_changes -gt 110 ] && {
29742                         kill -2 $UNLINK_PID
29743                         wait
29744                         error "osp changes throttling failed, $sync_changes>110"
29745                 }
29746                 kill -0 $UNLINK_PID 2> /dev/null || break
29747         done
29748         wait
29749 }
29750 run_test 831 "throttling unlink/setattr queuing on OSP"
29751
29752 test_832() {
29753         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29754         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29755                 skip "Need MDS version 2.15.52+"
29756         is_rmentry_supported || skip "rm_entry not supported"
29757
29758         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29759         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29760         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29761                 error "mkdir remote_dir failed"
29762         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29763                 error "mkdir striped_dir failed"
29764         touch $DIR/$tdir/file || error "touch file failed"
29765         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29766         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29767 }
29768 run_test 832 "lfs rm_entry"
29769
29770 #
29771 # tests that do cleanup/setup should be run at the end
29772 #
29773
29774 test_900() {
29775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29776         local ls
29777
29778         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29779         $LCTL set_param fail_loc=0x903
29780
29781         cancel_lru_locks MGC
29782
29783         FAIL_ON_ERROR=true cleanup
29784         FAIL_ON_ERROR=true setup
29785 }
29786 run_test 900 "umount should not race with any mgc requeue thread"
29787
29788 # LUS-6253/LU-11185
29789 test_901() {
29790         local old
29791         local count
29792         local oldc
29793         local newc
29794         local olds
29795         local news
29796         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29797
29798         # some get_param have a bug to handle dot in param name
29799         cancel_lru_locks MGC
29800         old=$(mount -t lustre | wc -l)
29801         # 1 config+sptlrpc
29802         # 2 params
29803         # 3 nodemap
29804         # 4 IR
29805         old=$((old * 4))
29806         oldc=0
29807         count=0
29808         while [ $old -ne $oldc ]; do
29809                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29810                 sleep 1
29811                 ((count++))
29812                 if [ $count -ge $TIMEOUT ]; then
29813                         error "too large timeout"
29814                 fi
29815         done
29816         umount_client $MOUNT || error "umount failed"
29817         mount_client $MOUNT || error "mount failed"
29818         cancel_lru_locks MGC
29819         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29820
29821         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29822
29823         return 0
29824 }
29825 run_test 901 "don't leak a mgc lock on client umount"
29826
29827 # LU-13377
29828 test_902() {
29829         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29830                 skip "client does not have LU-13377 fix"
29831         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29832         $LCTL set_param fail_loc=0x1415
29833         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29834         cancel_lru_locks osc
29835         rm -f $DIR/$tfile
29836 }
29837 run_test 902 "test short write doesn't hang lustre"
29838
29839 # LU-14711
29840 test_903() {
29841         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29842         echo "blah" > $DIR/${tfile}-2
29843         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29844         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29845         $LCTL set_param fail_loc=0x417 fail_val=20
29846
29847         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29848         sleep 1 # To start the destroy
29849         wait_destroy_complete 150 || error "Destroy taking too long"
29850         cat $DIR/$tfile > /dev/null || error "Evicted"
29851 }
29852 run_test 903 "Test long page discard does not cause evictions"
29853
29854 test_904() {
29855         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29856         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29857                 grep -q project || skip "skip project quota not supported"
29858
29859         local testfile="$DIR/$tdir/$tfile"
29860         local xattr="trusted.projid"
29861         local projid
29862         local mdts=$(comma_list $(mdts_nodes))
29863         local saved=$(do_facet mds1 $LCTL get_param -n \
29864                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29865
29866         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29867         stack_trap "do_nodes $mdts $LCTL set_param \
29868                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29869
29870         mkdir -p $DIR/$tdir
29871         touch $testfile
29872         #hide projid xattr on server
29873         $LFS project -p 1 $testfile ||
29874                 error "set $testfile project id failed"
29875         getfattr -m - $testfile | grep $xattr &&
29876                 error "do not show trusted.projid when disabled on server"
29877         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29878         #should be hidden when projid is 0
29879         $LFS project -p 0 $testfile ||
29880                 error "set $testfile project id failed"
29881         getfattr -m - $testfile | grep $xattr &&
29882                 error "do not show trusted.projid with project ID 0"
29883
29884         #still can getxattr explicitly
29885         projid=$(getfattr -n $xattr $testfile |
29886                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29887         [ $projid == "0" ] ||
29888                 error "projid expected 0 not $projid"
29889
29890         #set the projid via setxattr
29891         setfattr -n $xattr -v "1000" $testfile ||
29892                 error "setattr failed with $?"
29893         projid=($($LFS project $testfile))
29894         [ ${projid[0]} == "1000" ] ||
29895                 error "projid expected 1000 not $projid"
29896
29897         #check the new projid via getxattr
29898         $LFS project -p 1001 $testfile ||
29899                 error "set $testfile project id failed"
29900         getfattr -m - $testfile | grep $xattr ||
29901                 error "should show trusted.projid when project ID != 0"
29902         projid=$(getfattr -n $xattr $testfile |
29903                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29904         [ $projid == "1001" ] ||
29905                 error "projid expected 1001 not $projid"
29906
29907         #try to set invalid projid
29908         setfattr -n $xattr -v "4294967295" $testfile &&
29909                 error "set invalid projid should fail"
29910
29911         #remove the xattr means setting projid to 0
29912         setfattr -x $xattr $testfile ||
29913                 error "setfattr failed with $?"
29914         projid=($($LFS project $testfile))
29915         [ ${projid[0]} == "0" ] ||
29916                 error "projid expected 0 not $projid"
29917
29918         #should be hidden when parent has inherit flag and same projid
29919         $LFS project -srp 1002 $DIR/$tdir ||
29920                 error "set $tdir project id failed"
29921         getfattr -m - $testfile | grep $xattr &&
29922                 error "do not show trusted.projid with inherit flag"
29923
29924         #still can getxattr explicitly
29925         projid=$(getfattr -n $xattr $testfile |
29926                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29927         [ $projid == "1002" ] ||
29928                 error "projid expected 1002 not $projid"
29929 }
29930 run_test 904 "virtual project ID xattr"
29931
29932 # LU-8582
29933 test_905() {
29934         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29935                 skip "lustre < 2.8.54 does not support ladvise"
29936
29937         remote_ost_nodsh && skip "remote OST with nodsh"
29938         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29939
29940         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29941
29942         #define OBD_FAIL_OST_OPCODE 0x253
29943         # OST_LADVISE = 21
29944         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29945         $LFS ladvise -a willread $DIR/$tfile &&
29946                 error "unexpected success of ladvise with fault injection"
29947         $LFS ladvise -a willread $DIR/$tfile |&
29948                 grep -q "Operation not supported"
29949         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29950 }
29951 run_test 905 "bad or new opcode should not stuck client"
29952
29953 test_906() {
29954         grep -q io_uring_setup /proc/kallsyms ||
29955                 skip "Client OS does not support io_uring I/O engine"
29956         io_uring_probe || skip "kernel does not support io_uring fully"
29957         which fio || skip_env "no fio installed"
29958         fio --enghelp | grep -q io_uring ||
29959                 skip_env "fio does not support io_uring I/O engine"
29960
29961         local file=$DIR/$tfile
29962         local ioengine="io_uring"
29963         local numjobs=2
29964         local size=50M
29965
29966         fio --name=seqwrite --ioengine=$ioengine        \
29967                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29968                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29969                 error "fio seqwrite $file failed"
29970
29971         fio --name=seqread --ioengine=$ioengine \
29972                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29973                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29974                 error "fio seqread $file failed"
29975
29976         rm -f $file || error "rm -f $file failed"
29977 }
29978 run_test 906 "Simple test for io_uring I/O engine via fio"
29979
29980 complete $SECONDS
29981 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29982 check_and_cleanup_lustre
29983 if [ "$I_MOUNTED" != "yes" ]; then
29984         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29985 fi
29986 exit_status