Whamcloud - gitweb
77b706acf669012519dd6058fdec1ae674262b9f
[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         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
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_27D() {
2601         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2602         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2603         remote_mds_nodsh && skip "remote MDS with nodsh"
2604
2605         local POOL=${POOL:-testpool}
2606         local first_ost=0
2607         local last_ost=$(($OSTCOUNT - 1))
2608         local ost_step=1
2609         local ost_list=$(seq $first_ost $ost_step $last_ost)
2610         local ost_range="$first_ost $last_ost $ost_step"
2611
2612         test_mkdir $DIR/$tdir
2613         pool_add $POOL || error "pool_add failed"
2614         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2615
2616         local skip27D
2617         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2618                 skip27D+="-s 29"
2619         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2620                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2621                         skip27D+=" -s 30,31"
2622         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2623           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2624                 skip27D+=" -s 32,33"
2625         [[ $MDS_VERSION -lt $(version_code $SEL_VER) ]] &&
2626                 skip27D+=" -s 34"
2627         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2628                 error "llapi_layout_test failed"
2629
2630         destroy_test_pools || error "destroy test pools failed"
2631 }
2632 run_test 27D "validate llapi_layout API"
2633
2634 # Verify that default_easize is increased from its initial value after
2635 # accessing a widely striped file.
2636 test_27E() {
2637         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2638         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2639                 skip "client does not have LU-3338 fix"
2640
2641         # 72 bytes is the minimum space required to store striping
2642         # information for a file striped across one OST:
2643         # (sizeof(struct lov_user_md_v3) +
2644         #  sizeof(struct lov_user_ost_data_v1))
2645         local min_easize=72
2646         $LCTL set_param -n llite.*.default_easize $min_easize ||
2647                 error "lctl set_param failed"
2648         local easize=$($LCTL get_param -n llite.*.default_easize)
2649
2650         [ $easize -eq $min_easize ] ||
2651                 error "failed to set default_easize"
2652
2653         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2654                 error "setstripe failed"
2655         # In order to ensure stat() call actually talks to MDS we need to
2656         # do something drastic to this file to shake off all lock, e.g.
2657         # rename it (kills lookup lock forcing cache cleaning)
2658         mv $DIR/$tfile $DIR/${tfile}-1
2659         ls -l $DIR/${tfile}-1
2660         rm $DIR/${tfile}-1
2661
2662         easize=$($LCTL get_param -n llite.*.default_easize)
2663
2664         [ $easize -gt $min_easize ] ||
2665                 error "default_easize not updated"
2666 }
2667 run_test 27E "check that default extended attribute size properly increases"
2668
2669 test_27F() { # LU-5346/LU-7975
2670         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2671         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2672         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2673                 skip "Need MDS version at least 2.8.51"
2674         remote_ost_nodsh && skip "remote OST with nodsh"
2675
2676         test_mkdir $DIR/$tdir
2677         rm -f $DIR/$tdir/f0
2678         $LFS setstripe -c 2 $DIR/$tdir
2679
2680         # stop all OSTs to reproduce situation for LU-7975 ticket
2681         for num in $(seq $OSTCOUNT); do
2682                 stop ost$num
2683         done
2684
2685         # open/create f0 with O_LOV_DELAY_CREATE
2686         # truncate f0 to a non-0 size
2687         # close
2688         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2689
2690         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2691         # open/write it again to force delayed layout creation
2692         cat /etc/hosts > $DIR/$tdir/f0 &
2693         catpid=$!
2694
2695         # restart OSTs
2696         for num in $(seq $OSTCOUNT); do
2697                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2698                         error "ost$num failed to start"
2699         done
2700
2701         wait $catpid || error "cat failed"
2702
2703         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2704         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2705                 error "wrong stripecount"
2706
2707 }
2708 run_test 27F "Client resend delayed layout creation with non-zero size"
2709
2710 test_27G() { #LU-10629
2711         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2712                 skip "Need MDS version at least 2.11.51"
2713         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2714         remote_mds_nodsh && skip "remote MDS with nodsh"
2715         local POOL=${POOL:-testpool}
2716         local ostrange="0 0 1"
2717
2718         test_mkdir $DIR/$tdir
2719         touch $DIR/$tdir/$tfile.nopool
2720         pool_add $POOL || error "pool_add failed"
2721         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2722         $LFS setstripe -p $POOL $DIR/$tdir
2723
2724         local pool=$($LFS getstripe -p $DIR/$tdir)
2725
2726         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2727         touch $DIR/$tdir/$tfile.default
2728         $LFS setstripe -E 1M --pool $POOL -c 1 -E eof -c 1 $DIR/$tdir/$tfile.pfl
2729         $LFS find $DIR/$tdir -type f --pool $POOL
2730         local found=$($LFS find $DIR/$tdir -type f --pool $POOL | wc -l)
2731         [[ "$found" == "2" ]] ||
2732                 error "found $found != 2 files in '$DIR/$tdir' in '$POOL'"
2733
2734         $LFS setstripe -d $DIR/$tdir
2735
2736         pool=$($LFS getstripe -p -d $DIR/$tdir)
2737
2738         [[ "$pool" != "$POOL" ]] || error "$DIR/$tdir is still '$pool'"
2739 }
2740 run_test 27G "Clear OST pool from stripe"
2741
2742 test_27H() {
2743         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2744                 skip "Need MDS version newer than 2.11.54"
2745         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2746         test_mkdir $DIR/$tdir
2747         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2748         touch $DIR/$tdir/$tfile
2749         $LFS getstripe -c $DIR/$tdir/$tfile
2750         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2751                 error "two-stripe file doesn't have two stripes"
2752
2753         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2754         $LFS getstripe -y $DIR/$tdir/$tfile
2755         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2756              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2757                 error "expected l_ost_idx: [02]$ not matched"
2758
2759         # make sure ost list has been cleared
2760         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2761         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2762                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2763         touch $DIR/$tdir/f3
2764         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2765 }
2766 run_test 27H "Set specific OSTs stripe"
2767
2768 test_27I() {
2769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2770         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2771         [[ $MDS1_VERSION -gt $(version_code 2.12.52) ]] ||
2772                 skip "Need MDS version newer than 2.12.52"
2773         local pool=$TESTNAME
2774         local ostrange="1 1 1"
2775
2776         save_layout_restore_at_exit $MOUNT
2777         $LFS setstripe -c 2 -i 0 $MOUNT
2778         pool_add $pool || error "pool_add failed"
2779         pool_add_targets $pool $ostrange ||
2780                 error "pool_add_targets failed"
2781         test_mkdir $DIR/$tdir
2782         $LFS setstripe -p $pool $DIR/$tdir
2783         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2784         $LFS getstripe $DIR/$tdir/$tfile
2785 }
2786 run_test 27I "check that root dir striping does not break parent dir one"
2787
2788 test_27J() {
2789         [[ $MDS1_VERSION -le $(version_code 2.12.51) ]] &&
2790                 skip "Need MDS version newer than 2.12.51"
2791
2792         test_mkdir $DIR/$tdir
2793         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2794         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2795
2796         # create foreign file (raw way)
2797         ! $LFS setstripe --flags 0xda08 $DIR/$tdir/$tfile ||
2798                 error "creating $tfile w/ hex flags w/o --foreign should fail"
2799
2800         ! $LFS setstripe --foreign --flags foo \
2801                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2802                         error "creating $tfile with '--flags foo' should fail"
2803
2804         ! $LFS setstripe --foreign --flags 0xffffffff \
2805                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tfile ||
2806                         error "creating $tfile w/ 0xffffffff flags should fail"
2807
2808         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2809                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2810
2811         # verify foreign file (raw way)
2812         parse_foreign_file -f $DIR/$tdir/$tfile |
2813                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2814                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2815         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2816                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2817         parse_foreign_file -f $DIR/$tdir/$tfile |
2818                 grep "lov_foreign_size: 73" ||
2819                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2820         parse_foreign_file -f $DIR/$tdir/$tfile |
2821                 grep "lov_foreign_type: 1" ||
2822                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2823         parse_foreign_file -f $DIR/$tdir/$tfile |
2824                 grep "lov_foreign_flags: 0x0000DA08" ||
2825                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2826         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2827                 grep "lov_foreign_value: 0x" |
2828                 sed -e 's/lov_foreign_value: 0x//')
2829         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2830         [[ $lov = ${lov2// /} ]] ||
2831                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2832
2833         # create foreign file (lfs + API)
2834         $LFS setstripe --foreign=none --flags 0xda08 \
2835                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2836                 error "$DIR/$tdir/${tfile}2: create failed"
2837
2838         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2839                 grep "lfm_magic:.*0x0BD70BD0" ||
2840                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2841         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2842         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2843                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2844         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*none" ||
2845                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2846         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2847                 grep "lfm_flags:.*0x0000DA08" ||
2848                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2849         $LFS getstripe $DIR/$tdir/${tfile}2 |
2850                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2851                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2852
2853         # modify striping should fail
2854         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2855                 error "$DIR/$tdir/$tfile: setstripe should fail"
2856         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2857                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2858
2859         # R/W should fail
2860         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2861         cat $DIR/$tdir/${tfile}2 &&
2862                 error "$DIR/$tdir/${tfile}2: read should fail"
2863         cat /etc/passwd > $DIR/$tdir/$tfile &&
2864                 error "$DIR/$tdir/$tfile: write should fail"
2865         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2866                 error "$DIR/$tdir/${tfile}2: write should fail"
2867
2868         # chmod should work
2869         chmod 222 $DIR/$tdir/$tfile ||
2870                 error "$DIR/$tdir/$tfile: chmod failed"
2871         chmod 222 $DIR/$tdir/${tfile}2 ||
2872                 error "$DIR/$tdir/${tfile}2: chmod failed"
2873
2874         # chown should work
2875         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2876                 error "$DIR/$tdir/$tfile: chown failed"
2877         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2878                 error "$DIR/$tdir/${tfile}2: chown failed"
2879
2880         # rename should work
2881         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2882                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2883         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2884                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2885
2886         #remove foreign file
2887         rm $DIR/$tdir/${tfile}.new ||
2888                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2889         rm $DIR/$tdir/${tfile}2.new ||
2890                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2891 }
2892 run_test 27J "basic ops on file with foreign LOV"
2893
2894 test_27K() {
2895         [[ $MDS1_VERSION -le $(version_code 2.12.49) ]] &&
2896                 skip "Need MDS version newer than 2.12.49"
2897
2898         test_mkdir $DIR/$tdir
2899         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2900         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2901
2902         # create foreign dir (raw way)
2903         ! $LFS setdirstripe --flags 0xda08 $DIR/$tdir/$tdir ||
2904                 error "creating $tdir w/ hex flags w/o --foreign should fail"
2905
2906         ! $LFS setdirstripe --foreign --flags foo \
2907                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2908                         error "creating $tdir with '--flags foo' should fail"
2909
2910         ! $LFS setdirstripe --foreign --flags 0xffffffff \
2911                 --xattr ${uuid1}@${uuid2} $DIR/$tdir/$tdir ||
2912                         error "creating $tdir w/ 0xffffffff flags should fail"
2913
2914         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2915                 error "create_foreign_dir FAILED"
2916
2917         # verify foreign dir (raw way)
2918         parse_foreign_dir -d $DIR/$tdir/$tdir |
2919                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2920                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2921         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2922                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2923         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2924                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2925         parse_foreign_dir -d $DIR/$tdir/$tdir |
2926                 grep "lmv_foreign_flags: 55813$" ||
2927                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2928         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2929                 grep "lmv_foreign_value: 0x" |
2930                 sed 's/lmv_foreign_value: 0x//')
2931         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2932                 sed 's/ //g')
2933         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2934
2935         # create foreign dir (lfs + API)
2936         $LFS mkdir --foreign=none --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2937                 $DIR/$tdir/${tdir}2 ||
2938                 error "$DIR/$tdir/${tdir}2: create failed"
2939
2940         $LFS getdirstripe -v $DIR/$tdir/${tdir}2
2941
2942         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2943                 grep "lfm_magic:.*0x0CD50CD0" ||
2944                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2945         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2946         # - sizeof(lfm_type) - sizeof(lfm_flags)
2947         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2948                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2949         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*none" ||
2950                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2951         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2952                 grep "lfm_flags:.*0x0000DA05" ||
2953                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2954         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2955                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2956                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2957
2958         # file create in dir should fail
2959         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
2960         touch $DIR/$tdir/${tdir}2/$tfile &&
2961                 error "$DIR/${tdir}2: file create should fail"
2962
2963         # chmod should work
2964         chmod 777 $DIR/$tdir/$tdir ||
2965                 error "$DIR/$tdir: chmod failed"
2966         chmod 777 $DIR/$tdir/${tdir}2 ||
2967                 error "$DIR/${tdir}2: chmod failed"
2968
2969         # chown should work
2970         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2971                 error "$DIR/$tdir: chown failed"
2972         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2973                 error "$DIR/${tdir}2: chown failed"
2974
2975         # rename should work
2976         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2977                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2978         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2979                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2980
2981         #remove foreign dir
2982         rmdir $DIR/$tdir/${tdir}.new ||
2983                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2984         rmdir $DIR/$tdir/${tdir}2.new ||
2985                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2986 }
2987 run_test 27K "basic ops on dir with foreign LMV"
2988
2989 test_27L() {
2990         remote_mds_nodsh && skip "remote MDS with nodsh"
2991
2992         local POOL=${POOL:-$TESTNAME}
2993
2994         pool_add $POOL || error "pool_add failed"
2995
2996         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2997                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2998                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2999 }
3000 run_test 27L "lfs pool_list gives correct pool name"
3001
3002 test_27M() {
3003         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
3004                 skip "Need MDS version >= than 2.12.57"
3005         remote_mds_nodsh && skip "remote MDS with nodsh"
3006         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
3007
3008         # Set default striping on directory
3009         local setcount=4
3010         local stripe_opt
3011         local mdts=$(comma_list $(mdts_nodes))
3012
3013         # if we run against a 2.12 server which lacks overstring support
3014         # then the connect_flag will not report overstriping, even if client
3015         # is 2.14+
3016         if [[ $($LCTL get_param mdc.*.connect_flags) =~ overstriping ]]; then
3017                 stripe_opt="-C $setcount"
3018         elif (( $OSTCOUNT >= $setcount )); then
3019                 stripe_opt="-c $setcount"
3020         else
3021                 skip "server does not support overstriping"
3022         fi
3023
3024         test_mkdir $DIR/$tdir
3025
3026         # Validate existing append_* params and ensure restore
3027         local pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3028         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3029         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3030
3031         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3032         ((orig_count == 1)) || error "expected append_stripe_count == 1, got $orig_count"
3033         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1"
3034
3035         $LFS setstripe $stripe_opt $DIR/$tdir
3036
3037         echo 1 > $DIR/$tdir/${tfile}.1
3038         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
3039         [ $count -eq $setcount ] ||
3040                 error "(1) stripe count $count, should be $setcount"
3041
3042         local appendcount=$orig_count
3043         echo 1 >> $DIR/$tdir/${tfile}.2_append
3044         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
3045         [ $count -eq $appendcount ] ||
3046                 error "(2)stripe count $count, should be $appendcount for append"
3047
3048         # Disable O_APPEND striping, verify it works
3049         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3050
3051         # Should now get the default striping, which is 4
3052         setcount=4
3053         echo 1 >> $DIR/$tdir/${tfile}.3_append
3054         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
3055         [ $count -eq $setcount ] ||
3056                 error "(3) stripe count $count, should be $setcount"
3057
3058         # Try changing the stripe count for append files
3059         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3060
3061         # Append striping is now 2 (directory default is still 4)
3062         appendcount=2
3063         echo 1 >> $DIR/$tdir/${tfile}.4_append
3064         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
3065         [ $count -eq $appendcount ] ||
3066                 error "(4) stripe count $count, should be $appendcount for append"
3067
3068         # Test append stripe count of -1
3069         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
3070         appendcount=$OSTCOUNT
3071         echo 1 >> $DIR/$tdir/${tfile}.5
3072         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
3073         [ $count -eq $appendcount ] ||
3074                 error "(5) stripe count $count, should be $appendcount for append"
3075
3076         # Set append striping back to default of 1
3077         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
3078
3079         # Try a new default striping, PFL + DOM
3080         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
3081
3082         # Create normal DOM file, DOM returns stripe count == 0
3083         setcount=0
3084         touch $DIR/$tdir/${tfile}.6
3085         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
3086         [ $count -eq $setcount ] ||
3087                 error "(6) stripe count $count, should be $setcount"
3088
3089         # Show
3090         appendcount=1
3091         echo 1 >> $DIR/$tdir/${tfile}.7_append
3092         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
3093         [ $count -eq $appendcount ] ||
3094                 error "(7) stripe count $count, should be $appendcount for append"
3095
3096         # Clean up DOM layout
3097         $LFS setstripe -d $DIR/$tdir
3098
3099         save_layout_restore_at_exit $MOUNT
3100         # Now test that append striping works when layout is from root
3101         $LFS setstripe -c 2 $MOUNT
3102         # Make a special directory for this
3103         mkdir $DIR/${tdir}/${tdir}.2
3104
3105         # Verify for normal file
3106         setcount=2
3107         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
3108         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
3109         [ $count -eq $setcount ] ||
3110                 error "(8) stripe count $count, should be $setcount"
3111
3112         appendcount=1
3113         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
3114         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
3115         [ $count -eq $appendcount ] ||
3116                 error "(9) stripe count $count, should be $appendcount for append"
3117
3118         # Now test O_APPEND striping with pools
3119         pool_add $TESTNAME || error "pool creation failed"
3120         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
3121         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
3122
3123         echo 1 >> $DIR/$tdir/${tfile}.10_append
3124
3125         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
3126         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
3127
3128         # Check that count is still correct
3129         appendcount=1
3130         echo 1 >> $DIR/$tdir/${tfile}.11_append
3131         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
3132         [ $count -eq $appendcount ] ||
3133                 error "(11) stripe count $count, should be $appendcount for append"
3134
3135         # Disable O_APPEND stripe count, verify pool works separately
3136         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
3137
3138         echo 1 >> $DIR/$tdir/${tfile}.12_append
3139
3140         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
3141         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
3142
3143         # Remove pool setting, verify it's not applied
3144         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
3145
3146         echo 1 >> $DIR/$tdir/${tfile}.13_append
3147
3148         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
3149         [ "$pool" = "" ] || error "(13) pool found: $pool"
3150 }
3151 run_test 27M "test O_APPEND striping"
3152
3153 test_27N() {
3154         combined_mgs_mds && skip "needs separate MGS/MDT"
3155
3156         pool_add $TESTNAME || error "pool_add failed"
3157         do_facet mgs "$LCTL pool_list $FSNAME" |
3158                 grep -Fx "${FSNAME}.${TESTNAME}" ||
3159                 error "lctl pool_list on MGS failed"
3160 }
3161 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
3162
3163 clean_foreign_symlink() {
3164         trap 0
3165         lctl set_param llite/$FSNAME-*/foreign_symlink_enable=0
3166         for i in $DIR/$tdir/* ; do
3167                 $LFS unlink_foreign $i || true
3168         done
3169 }
3170
3171 test_27O() {
3172         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
3173                 skip "Need MDS version newer than 2.12.51"
3174
3175         test_mkdir $DIR/$tdir
3176         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3177         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3178
3179         trap clean_foreign_symlink EXIT
3180
3181         # enable foreign_symlink behaviour
3182         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3183
3184         # foreign symlink LOV format is a partial path by default
3185
3186         # create foreign file (lfs + API)
3187         $LFS setstripe --foreign=symlink --flags 0xda05 \
3188                 -x "${uuid1}/${uuid2}" --mode 0600 $DIR/$tdir/${tfile} ||
3189                 error "$DIR/$tdir/${tfile}: create failed"
3190
3191         $LFS getstripe -v $DIR/$tdir/${tfile} |
3192                 grep "lfm_magic:.*0x0BD70BD0" ||
3193                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign magic"
3194         $LFS getstripe -v $DIR/$tdir/${tfile} | grep "lfm_type:.*symlink" ||
3195                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign type"
3196         $LFS getstripe -v $DIR/$tdir/${tfile} |
3197                 grep "lfm_flags:.*0x0000DA05" ||
3198                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign flags"
3199         $LFS getstripe $DIR/$tdir/${tfile} |
3200                 grep "lfm_value:.*${uuid1}/${uuid2}" ||
3201                 error "$DIR/$tdir/${tfile}: invalid LOV EA foreign value"
3202
3203         # modify striping should fail
3204         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
3205                 error "$DIR/$tdir/$tfile: setstripe should fail"
3206
3207         # R/W should fail ("/{foreign_symlink_prefix}/${uuid1}/" missing)
3208         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
3209         cat /etc/passwd > $DIR/$tdir/$tfile &&
3210                 error "$DIR/$tdir/$tfile: write should fail"
3211
3212         # rename should succeed
3213         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
3214                 error "$DIR/$tdir/$tfile: rename has failed"
3215
3216         #remove foreign_symlink file should fail
3217         rm $DIR/$tdir/${tfile}.new &&
3218                 error "$DIR/$tdir/${tfile}.new: remove of foreign_symlink file should fail"
3219
3220         #test fake symlink
3221         mkdir /tmp/${uuid1} ||
3222                 error "/tmp/${uuid1}: mkdir has failed"
3223         echo FOOFOO > /tmp/${uuid1}/${uuid2} ||
3224                 error "/tmp/${uuid1}/${uuid2}: echo has failed"
3225         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3226         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tfile}.new ||
3227                 error "$DIR/$tdir/${tfile}.new: not seen as a symlink"
3228         #read should succeed now
3229         cat $DIR/$tdir/${tfile}.new | grep FOOFOO ||
3230                 error "$DIR/$tdir/${tfile}.new: symlink resolution has failed"
3231         #write should succeed now
3232         cat /etc/passwd > $DIR/$tdir/${tfile}.new ||
3233                 error "$DIR/$tdir/${tfile}.new: write should succeed"
3234         diff /etc/passwd $DIR/$tdir/${tfile}.new ||
3235                 error "$DIR/$tdir/${tfile}.new: diff has failed"
3236         diff /etc/passwd /tmp/${uuid1}/${uuid2} ||
3237                 error "/tmp/${uuid1}/${uuid2}: diff has failed"
3238
3239         #check that getstripe still works
3240         $LFS getstripe $DIR/$tdir/${tfile}.new ||
3241                 error "$DIR/$tdir/${tfile}.new: getstripe should still work with foreign_symlink enabled"
3242
3243         # chmod should still succeed
3244         chmod 644 $DIR/$tdir/${tfile}.new ||
3245                 error "$DIR/$tdir/${tfile}.new: chmod has failed"
3246
3247         # chown should still succeed
3248         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}.new ||
3249                 error "$DIR/$tdir/${tfile}.new: chown has failed"
3250
3251         # rename should still succeed
3252         mv $DIR/$tdir/${tfile}.new $DIR/$tdir/${tfile} ||
3253                 error "$DIR/$tdir/${tfile}.new: rename has failed"
3254
3255         #remove foreign_symlink file should still fail
3256         rm $DIR/$tdir/${tfile} &&
3257                 error "$DIR/$tdir/${tfile}: remove of foreign_symlink file should fail"
3258
3259         #use special ioctl() to unlink foreign_symlink file
3260         $LFS unlink_foreign $DIR/$tdir/${tfile} ||
3261                 error "$DIR/$tdir/$tfile: unlink/ioctl failed"
3262
3263 }
3264 run_test 27O "basic ops on foreign file of symlink type"
3265
3266 test_27P() {
3267         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
3268                 skip "Need MDS version newer than 2.12.49"
3269
3270         test_mkdir $DIR/$tdir
3271         local uuid1=$(cat /proc/sys/kernel/random/uuid)
3272         local uuid2=$(cat /proc/sys/kernel/random/uuid)
3273
3274         trap clean_foreign_symlink EXIT
3275
3276         # enable foreign_symlink behaviour
3277         $LCTL set_param llite/$FSNAME-*/foreign_symlink_enable=1
3278
3279         # foreign symlink LMV format is a partial path by default
3280
3281         # create foreign dir (lfs + API)
3282         $LFS mkdir --foreign=symlink --xattr="${uuid1}/${uuid2}" \
3283                 --flags=0xda05 --mode 0750 $DIR/$tdir/${tdir} ||
3284                 error "$DIR/$tdir/${tdir}: create failed"
3285
3286         $LFS getdirstripe -v $DIR/$tdir/${tdir}
3287
3288         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3289                 grep "lfm_magic:.*0x0CD50CD0" ||
3290                 error "$DIR/$tdir/${tdir}: invalid LMV EA magic"
3291         $LFS getdirstripe -v $DIR/$tdir/${tdir} | grep "lfm_type:.*symlink" ||
3292                 error "$DIR/$tdir/${tdir}: invalid LMV EA type"
3293         $LFS getdirstripe -v $DIR/$tdir/${tdir} |
3294                 grep "lfm_flags:.*0x0000DA05" ||
3295                 error "$DIR/$tdir/${tdir}: invalid LMV EA flags"
3296         $LFS getdirstripe $DIR/$tdir/${tdir} |
3297                 grep "lfm_value.*${uuid1}/${uuid2}" ||
3298                 error "$DIR/$tdir/${tdir}: invalid LMV EA value"
3299
3300         # file create in dir should fail
3301         # ("/{foreign_symlink_prefix}/${uuid1}/${uuid2}/" missing)
3302         touch $DIR/$tdir/$tdir/$tfile && error "$DIR/$tdir: file create should fail"
3303
3304         # rename should succeed
3305         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
3306                 error "$DIR/$tdir/$tdir: rename of foreign_symlink dir has failed"
3307
3308         #remove foreign_symlink dir should fail
3309         rmdir $DIR/$tdir/${tdir}.new &&
3310                 error "$DIR/$tdir/${tdir}.new: remove of foreign_symlink dir should fail"
3311
3312         #test fake symlink
3313         mkdir -p /tmp/${uuid1}/${uuid2} ||
3314                 error "/tmp/${uuid1}/${uuid2}: mkdir has failed"
3315         echo FOOFOO > /tmp/${uuid1}/${uuid2}/foo ||
3316                 error "/tmp/${uuid1}/${uuid2}/foo: echo has failed"
3317         $LCTL set_param llite/$FSNAME-*/foreign_symlink_prefix=/tmp/
3318         $CHECKSTAT -t link -l /tmp/${uuid1}/${uuid2} $DIR/$tdir/${tdir}.new ||
3319                 error "$DIR/$tdir/${tdir}.new: not seen as a symlink"
3320         cat $DIR/$tdir/${tdir}.new/foo | grep FOOFOO ||
3321                 error "$DIR/$tdir/${tdir}.new: symlink resolution has failed"
3322
3323         #check that getstripe fails now that foreign_symlink enabled
3324         $LFS getdirstripe $DIR/$tdir/${tdir}.new ||
3325                 error "$DIR/$tdir/${tdir}.new: getdirstripe should still work with foreign_symlink enabled"
3326
3327         # file create in dir should work now
3328         cp /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3329                 error "$DIR/$tdir/${tdir}.new/$tfile: file create should fail"
3330         diff /etc/passwd $DIR/$tdir/${tdir}.new/$tfile ||
3331                 error "$DIR/$tdir/${tdir}.new/$tfile: diff has failed"
3332         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3333                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3334
3335         # chmod should still succeed
3336         chmod 755 $DIR/$tdir/${tdir}.new ||
3337                 error "$DIR/$tdir/${tdir}.new: chmod has failed"
3338
3339         # chown should still succeed
3340         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}.new ||
3341                 error "$DIR/$tdir/${tdir}.new: chown has failed"
3342
3343         # rename should still succeed
3344         mv $DIR/$tdir/${tdir}.new $DIR/$tdir/${tdir} ||
3345                 error "$DIR/$tdir/${tdir}.new: rename of foreign_symlink dir has failed"
3346
3347         #remove foreign_symlink dir should still fail
3348         rmdir $DIR/$tdir/${tdir} &&
3349                 error "$DIR/$tdir/${tdir}: remove of foreign_symlink dir should fail"
3350
3351         #use special ioctl() to unlink foreign_symlink file
3352         $LFS unlink_foreign $DIR/$tdir/${tdir} ||
3353                 error "$DIR/$tdir/$tdir: unlink/ioctl failed"
3354
3355         #created file should still exist
3356         [[ -f /tmp/${uuid1}/${uuid2}/$tfile ]] ||
3357                 error "/tmp/${uuid1}/${uuid2}/$tfile has been removed"
3358         diff /etc/passwd /tmp/${uuid1}/${uuid2}/$tfile ||
3359                 error "/tmp/${uuid1}/${uuid2}/$tfile: diff has failed"
3360 }
3361 run_test 27P "basic ops on foreign dir of foreign_symlink type"
3362
3363 test_27Q() {
3364         rm -f $TMP/$tfile $TMP/$tfile.loop $TMP/$tfile.none $TMP/$tfile.broken
3365         stack_trap "rm -f $TMP/$tfile*"
3366
3367         test_mkdir $DIR/$tdir-1
3368         test_mkdir $DIR/$tdir-2
3369
3370         echo 'It is what it is' > $DIR/$tdir-1/$tfile
3371         lov_getstripe_old $DIR/$tdir-1/$tfile || error "$DIR/$tdir-1/$tfile: rc = $?"
3372
3373         ln -s $DIR/$tdir-1/$tfile $DIR/$tdir-2/$tfile
3374         lov_getstripe_old $DIR/$tdir-2/$tfile || error "$DIR/$tdir-2/$tfile: rc = $?"
3375
3376         ln -s $DIR/$tdir-1/$tfile $TMP/$tfile
3377         lov_getstripe_old $TMP/$tfile || error "$TMP/$tfile: rc = $?"
3378
3379         # Create some bad symlinks and ensure that we don't loop
3380         # forever or something. These should return ELOOP (40) and
3381         # ENOENT (2) but I don't want to test for that because there's
3382         # always some weirdo architecture that needs to ruin
3383         # everything by defining these error numbers differently.
3384
3385         ln -s $TMP/$tfile.loop $TMP/$tfile.loop
3386         lov_getstripe_old $TMP/$tfile.loop && error "$TMP/$tfile.loop: rc = $?"
3387
3388         ln -s $TMP/$tfile.none $TMP/$tfile.broken
3389         lov_getstripe_old $TMP/$tfile.broken && error "$TMP/$tfile.broken: rc = $?"
3390
3391         return 0
3392 }
3393 run_test 27Q "llapi_file_get_stripe() works on symlinks"
3394
3395 test_27R() {
3396         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
3397                 skip "need MDS 2.14.55 or later"
3398         (( $OSTCOUNT >= 2 )) || skip_env "needs at least 2 OSTs"
3399
3400         local testdir="$DIR/$tdir"
3401         test_mkdir -p $testdir
3402         stack_trap "rm -rf $testdir"
3403         $LFS setstripe -c -1 $testdir || error "setstripe failed"
3404
3405         local f1="$testdir/f1"
3406         touch $f1 || error "failed to touch $f1"
3407         local count=$($LFS getstripe -c $f1)
3408         (( $count == $OSTCOUNT )) || error "wrong stripe count"
3409
3410         do_facet $SINGLEMDS $LCTL set_param lod.*.max_stripecount=-1
3411         (( $? == 34 )) || error "setting max_stripecount to -1 should fail and return ERANGE"
3412
3413         local maxcount=$(($OSTCOUNT - 1))
3414         local mdts=$(comma_list $(mdts_nodes))
3415         do_nodes $mdts $LCTL set_param lod.*.max_stripecount=$maxcount
3416         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_stripecount=0"
3417
3418         local f2="$testdir/f2"
3419         touch $f2 || error "failed to touch $f2"
3420         local count=$($LFS getstripe -c $f2)
3421         (( $count == $maxcount )) || error "wrong stripe count"
3422 }
3423 run_test 27R "test max_stripecount limitation when stripe count is set to -1"
3424
3425 test_27T() {
3426         [ $(facet_host client) == $(facet_host ost1) ] &&
3427                 skip "need ost1 and client on different nodes"
3428
3429 #define OBD_FAIL_OSC_NO_GRANT            0x411
3430         $LCTL set_param fail_loc=0x20000411 fail_val=1
3431 #define OBD_FAIL_OST_ENOSPC              0x215
3432         do_facet ost1 "$LCTL set_param fail_loc=0x80000215"
3433         $LFS setstripe -i 0 -c 1 $DIR/$tfile
3434         $MULTIOP $DIR/$tfile oO_WRONLY:P$((4 * 1024 * 1024 + 10 * 4096))c ||
3435                 error "multiop failed"
3436 }
3437 run_test 27T "no eio on close on partial write due to enosp"
3438
3439 test_27U() {
3440         local dir=$DIR/$tdir
3441         local file=$dir/$tfile
3442         local append_pool=${TESTNAME}-append
3443         local normal_pool=${TESTNAME}-normal
3444         local pool
3445         local stripe_count
3446         local stripe_count2
3447         local mdts=$(comma_list $(mdts_nodes))
3448
3449         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
3450                 skip "Need MDS version at least 2.15.51 for append pool feature"
3451
3452         # Validate existing append_* params and ensure restore
3453         pool=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_pool)
3454         [[ "$pool" == "" ]] || error "expected append_pool == '', got '$pool'"
3455         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool=none"
3456
3457         stripe_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
3458         ((stripe_count == 1)) || error "expected append_stripe_count != 0, got $stripe_count"
3459         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$stripe_count"
3460
3461         pool_add $append_pool || error "pool creation failed"
3462         pool_add_targets $append_pool 0 1 || error "Pool add targets failed"
3463
3464         pool_add $normal_pool || error "pool creation failed"
3465         pool_add_targets $normal_pool 0 1 || error "Pool add targets failed"
3466
3467         test_mkdir $dir
3468         $LFS setstripe -E 1M -c 1 -p $normal_pool -E 2M -c 2 -p $normal_pool -E eof -c -1 $dir
3469
3470         echo XXX >> $file.1
3471         $LFS getstripe $file.1
3472
3473         pool=$($LFS getstripe -p $file.1)
3474         [[ "$pool" == "$normal_pool" ]] || error "got pool '$pool', expected '$normal_pool'"
3475
3476         stripe_count2=$($LFS getstripe -c $file.1)
3477         ((stripe_count2 == stripe_count)) ||
3478                 error "got stripe_count '$stripe_count2', expected '$stripe_count'"
3479
3480         do_nodes $mdts $LCTL set_param mdd.*.append_pool=$append_pool
3481
3482         echo XXX >> $file.2
3483         $LFS getstripe $file.2
3484
3485         pool=$($LFS getstripe -p $file.2)
3486         [[ "$pool" == "$append_pool" ]] || error "got pool '$pool', expected '$append_pool'"
3487
3488         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
3489
3490         echo XXX >> $file.3
3491         $LFS getstripe $file.3
3492
3493         stripe_count2=$($LFS getstripe -c $file.3)
3494         ((stripe_count2 == 2)) || error "got stripe_count '$stripe_count2', expected 2"
3495 }
3496 run_test 27U "append pool and stripe count work with composite default layout"
3497
3498 # createtest also checks that device nodes are created and
3499 # then visible correctly (#2091)
3500 test_28() { # bug 2091
3501         test_mkdir $DIR/d28
3502         $CREATETEST $DIR/d28/ct || error "createtest failed"
3503 }
3504 run_test 28 "create/mknod/mkdir with bad file types ============"
3505
3506 test_29() {
3507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3508
3509         [ $MDS1_VERSION -ge $(version_code 2.14.51) ] && {
3510                 disable_opencache
3511                 stack_trap "restore_opencache"
3512         }
3513
3514         sync; sleep 1; sync # flush out any dirty pages from previous tests
3515         cancel_lru_locks
3516         test_mkdir $DIR/d29
3517         touch $DIR/d29/foo
3518         log 'first d29'
3519         ls -l $DIR/d29
3520
3521         declare -i LOCKCOUNTORIG=0
3522         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3523                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
3524         done
3525         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
3526
3527         declare -i LOCKUNUSEDCOUNTORIG=0
3528         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3529                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
3530         done
3531
3532         log 'second d29'
3533         ls -l $DIR/d29
3534         log 'done'
3535
3536         declare -i LOCKCOUNTCURRENT=0
3537         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3538                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3539         done
3540
3541         declare -i LOCKUNUSEDCOUNTCURRENT=0
3542         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3543                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3544         done
3545
3546         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3547                 $LCTL set_param -n ldlm.dump_namespaces ""
3548                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3549                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3550                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3551                 return 2
3552         fi
3553         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3554                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3555                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3556                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3557                 return 3
3558         fi
3559 }
3560 run_test 29 "IT_GETATTR regression  ============================"
3561
3562 test_30a() { # was test_30
3563         cp $(which ls) $DIR || cp /bin/ls $DIR
3564         $DIR/ls / || error "Can't execute binary from lustre"
3565         rm $DIR/ls
3566 }
3567 run_test 30a "execute binary from Lustre (execve) =============="
3568
3569 test_30b() {
3570         cp `which ls` $DIR || cp /bin/ls $DIR
3571         chmod go+rx $DIR/ls
3572         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3573         rm $DIR/ls
3574 }
3575 run_test 30b "execute binary from Lustre as non-root ==========="
3576
3577 test_30c() { # b=22376
3578         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3579
3580         cp $(which ls) $DIR || cp /bin/ls $DIR
3581         chmod a-rw $DIR/ls
3582         cancel_lru_locks mdc
3583         cancel_lru_locks osc
3584         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3585         rm -f $DIR/ls
3586 }
3587 run_test 30c "execute binary from Lustre without read perms ===="
3588
3589 test_30d() {
3590         cp $(which dd) $DIR || error "failed to copy dd to $DIR/dd"
3591
3592         for i in {1..10}; do
3593                 $DIR/dd bs=1M count=128 if=/dev/zero of=$DIR/$tfile &
3594                 local PID=$!
3595                 sleep 1
3596                 $LCTL set_param ldlm.namespaces.*MDT*.lru_size=clear
3597                 wait $PID || error "executing dd from Lustre failed"
3598                 rm -f $DIR/$tfile
3599         done
3600
3601         rm -f $DIR/dd
3602 }
3603 run_test 30d "execute binary from Lustre while clear locks"
3604
3605 test_31a() {
3606         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3607         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3608 }
3609 run_test 31a "open-unlink file =================================="
3610
3611 test_31b() {
3612         touch $DIR/f31 || error "touch $DIR/f31 failed"
3613         ln $DIR/f31 $DIR/f31b || error "ln failed"
3614         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3615         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3616 }
3617 run_test 31b "unlink file with multiple links while open ======="
3618
3619 test_31c() {
3620         touch $DIR/f31 || error "touch $DIR/f31 failed"
3621         ln $DIR/f31 $DIR/f31c || error "ln failed"
3622         multiop_bg_pause $DIR/f31 O_uc ||
3623                 error "multiop_bg_pause for $DIR/f31 failed"
3624         MULTIPID=$!
3625         $MULTIOP $DIR/f31c Ouc
3626         kill -USR1 $MULTIPID
3627         wait $MULTIPID
3628 }
3629 run_test 31c "open-unlink file with multiple links ============="
3630
3631 test_31d() {
3632         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3633         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3634 }
3635 run_test 31d "remove of open directory ========================="
3636
3637 test_31e() { # bug 2904
3638         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3639 }
3640 run_test 31e "remove of open non-empty directory ==============="
3641
3642 test_31f() { # bug 4554
3643         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3644
3645         set -vx
3646         test_mkdir $DIR/d31f
3647         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3648         cp /etc/hosts $DIR/d31f
3649         ls -l $DIR/d31f
3650         $LFS getstripe $DIR/d31f/hosts
3651         multiop_bg_pause $DIR/d31f D_c || return 1
3652         MULTIPID=$!
3653
3654         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3655         test_mkdir $DIR/d31f
3656         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3657         cp /etc/hosts $DIR/d31f
3658         ls -l $DIR/d31f
3659         $LFS getstripe $DIR/d31f/hosts
3660         multiop_bg_pause $DIR/d31f D_c || return 1
3661         MULTIPID2=$!
3662
3663         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3664         wait $MULTIPID || error "first opendir $MULTIPID failed"
3665
3666         sleep 6
3667
3668         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3669         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3670         set +vx
3671 }
3672 run_test 31f "remove of open directory with open-unlink file ==="
3673
3674 test_31g() {
3675         echo "-- cross directory link --"
3676         test_mkdir -c1 $DIR/${tdir}ga
3677         test_mkdir -c1 $DIR/${tdir}gb
3678         touch $DIR/${tdir}ga/f
3679         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3680         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3681         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3682         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3683         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3684 }
3685 run_test 31g "cross directory link==============="
3686
3687 test_31h() {
3688         echo "-- cross directory link --"
3689         test_mkdir -c1 $DIR/${tdir}
3690         test_mkdir -c1 $DIR/${tdir}/dir
3691         touch $DIR/${tdir}/f
3692         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3693         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3694         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3695         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3696         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3697 }
3698 run_test 31h "cross directory link under child==============="
3699
3700 test_31i() {
3701         echo "-- cross directory link --"
3702         test_mkdir -c1 $DIR/$tdir
3703         test_mkdir -c1 $DIR/$tdir/dir
3704         touch $DIR/$tdir/dir/f
3705         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3706         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3707         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3708         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3709         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3710 }
3711 run_test 31i "cross directory link under parent==============="
3712
3713 test_31j() {
3714         test_mkdir -c1 -p $DIR/$tdir
3715         test_mkdir -c1 -p $DIR/$tdir/dir1
3716         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3717         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3718         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3719         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3720         return 0
3721 }
3722 run_test 31j "link for directory==============="
3723
3724 test_31k() {
3725         test_mkdir -c1 -p $DIR/$tdir
3726         touch $DIR/$tdir/s
3727         touch $DIR/$tdir/exist
3728         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3729         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3730         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3731         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3732         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3733         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3734         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3735         return 0
3736 }
3737 run_test 31k "link to file: the same, non-existing, dir==============="
3738
3739 test_31l() {
3740         local ln_ver=$(ln --version | awk '/coreutils/ { print $4 }')
3741
3742         (( $(version_code $ln_ver) < $(version_code 8.31) )) ||
3743         (( $(version_code $(uname -r)) >= $(version_code 5.18) )) ||
3744                 skip "need coreutils < 8.31 or kernel >= 5.18 for ln"
3745
3746         touch $DIR/$tfile || error "create failed"
3747         mkdir $DIR/$tdir || error "mkdir failed"
3748         ln $DIR/$tfile $DIR/$tdir/ || error "ln to '$tdir/' failed"
3749 }
3750 run_test 31l "link to file: target dir has trailing slash"
3751
3752 test_31m() {
3753         mkdir $DIR/d31m
3754         touch $DIR/d31m/s
3755         mkdir $DIR/d31m2
3756         touch $DIR/d31m2/exist
3757         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3758         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3759         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3760         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3761         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3762         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3763         return 0
3764 }
3765 run_test 31m "link to file: the same, non-existing, dir==============="
3766
3767 test_31n() {
3768         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3769         nlink=$(stat --format=%h $DIR/$tfile)
3770         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3771         local fd=$(free_fd)
3772         local cmd="exec $fd<$DIR/$tfile"
3773         eval $cmd
3774         cmd="exec $fd<&-"
3775         trap "eval $cmd" EXIT
3776         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3777         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3778         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3779         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3780         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3781         eval $cmd
3782 }
3783 run_test 31n "check link count of unlinked file"
3784
3785 link_one() {
3786         local tempfile=$(mktemp $1_XXXXXX)
3787         mlink $tempfile $1 2> /dev/null &&
3788                 echo "$BASHPID: link $tempfile to $1 succeeded"
3789         munlink $tempfile
3790 }
3791
3792 test_31o() { # LU-2901
3793         test_mkdir $DIR/$tdir
3794         for LOOP in $(seq 100); do
3795                 rm -f $DIR/$tdir/$tfile*
3796                 for THREAD in $(seq 8); do
3797                         link_one $DIR/$tdir/$tfile.$LOOP &
3798                 done
3799                 wait
3800                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3801                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3802                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3803                         break || true
3804         done
3805 }
3806 run_test 31o "duplicate hard links with same filename"
3807
3808 test_31p() {
3809         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3810
3811         test_mkdir $DIR/$tdir
3812         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3813         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3814
3815         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3816                 error "open unlink test1 failed"
3817         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3818                 error "open unlink test2 failed"
3819
3820         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3821                 error "test1 still exists"
3822         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3823                 error "test2 still exists"
3824 }
3825 run_test 31p "remove of open striped directory"
3826
3827 test_31q() {
3828         [ $MDSCOUNT -lt 3 ] && skip_env "needs >= 3 MDTs"
3829
3830         $LFS mkdir -i 3,1 $DIR/$tdir || error "mkdir failed"
3831         index=$($LFS getdirstripe -i $DIR/$tdir)
3832         [ $index -eq 3 ] || error "first stripe index $index != 3"
3833         index=$($LFS getdirstripe $DIR/$tdir | tail -1 | awk '{print $1}')
3834         [ $index -eq 1 ] || error "second stripe index $index != 1"
3835
3836         # when "-c <stripe_count>" is set, the number of MDTs specified after
3837         # "-i" should equal to the stripe count
3838         $LFS mkdir -i 3,1 -c 3 $DIR/$tdir.2 && error "mkdir should fail" || true
3839 }
3840 run_test 31q "create striped directory on specific MDTs"
3841
3842 #LU-14949
3843 test_31r() {
3844         touch $DIR/$tfile.target
3845         touch $DIR/$tfile.source
3846
3847         #OBD_FAIL_LLITE_OPEN_DELAY 0x1419
3848         $LCTL set_param fail_loc=0x1419 fail_val=3
3849         cat $DIR/$tfile.target &
3850         CATPID=$!
3851
3852         # Guarantee open is waiting before we get here
3853         sleep 1
3854         mv $DIR/$tfile.source $DIR/$tfile.target
3855
3856         wait $CATPID
3857         RC=$?
3858         if [[ $RC -ne 0 ]]; then
3859                 error "open with cat failed, rc=$RC"
3860         fi
3861 }
3862 run_test 31r "open-rename(replace) race"
3863
3864 cleanup_test32_mount() {
3865         local rc=0
3866         trap 0
3867         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3868         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3869         losetup -d $loopdev || true
3870         rm -rf $DIR/$tdir
3871         return $rc
3872 }
3873
3874 test_32a() {
3875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3876
3877         echo "== more mountpoints and symlinks ================="
3878         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3879         trap cleanup_test32_mount EXIT
3880         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3881         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3882                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3883         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3884                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3885         cleanup_test32_mount
3886 }
3887 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3888
3889 test_32b() {
3890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3891
3892         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3893         trap cleanup_test32_mount EXIT
3894         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3895         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3896                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3897         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3898                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3899         cleanup_test32_mount
3900 }
3901 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3902
3903 test_32c() {
3904         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3905
3906         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3907         trap cleanup_test32_mount EXIT
3908         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3909         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3910                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3911         test_mkdir -p $DIR/$tdir/d2/test_dir
3912         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3913                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3914         cleanup_test32_mount
3915 }
3916 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3917
3918 test_32d() {
3919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3920
3921         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3922         trap cleanup_test32_mount EXIT
3923         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3924         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3925                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3926         test_mkdir -p $DIR/$tdir/d2/test_dir
3927         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3928                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3929         cleanup_test32_mount
3930 }
3931 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3932
3933 test_32e() {
3934         rm -fr $DIR/$tdir
3935         test_mkdir -p $DIR/$tdir/tmp
3936         local tmp_dir=$DIR/$tdir/tmp
3937         ln -s $DIR/$tdir $tmp_dir/symlink11
3938         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3939         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3940         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3941 }
3942 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3943
3944 test_32f() {
3945         rm -fr $DIR/$tdir
3946         test_mkdir -p $DIR/$tdir/tmp
3947         local tmp_dir=$DIR/$tdir/tmp
3948         ln -s $DIR/$tdir $tmp_dir/symlink11
3949         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3950         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3951         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3952 }
3953 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3954
3955 test_32g() {
3956         local tmp_dir=$DIR/$tdir/tmp
3957         test_mkdir -p $tmp_dir
3958         test_mkdir $DIR/${tdir}2
3959         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3960         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3961         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3962         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3963         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3964         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3965 }
3966 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3967
3968 test_32h() {
3969         rm -fr $DIR/$tdir $DIR/${tdir}2
3970         tmp_dir=$DIR/$tdir/tmp
3971         test_mkdir -p $tmp_dir
3972         test_mkdir $DIR/${tdir}2
3973         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3974         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3975         ls $tmp_dir/symlink12 || error "listing symlink12"
3976         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3977 }
3978 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3979
3980 test_32i() {
3981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3982
3983         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3984         trap cleanup_test32_mount EXIT
3985         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3986         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3987                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3988         touch $DIR/$tdir/test_file
3989         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3990                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3991         cleanup_test32_mount
3992 }
3993 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3994
3995 test_32j() {
3996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3997
3998         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3999         trap cleanup_test32_mount EXIT
4000         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4001         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4002                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4003         touch $DIR/$tdir/test_file
4004         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
4005                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
4006         cleanup_test32_mount
4007 }
4008 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
4009
4010 test_32k() {
4011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4012
4013         rm -fr $DIR/$tdir
4014         trap cleanup_test32_mount EXIT
4015         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4016         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4017                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4018         test_mkdir -p $DIR/$tdir/d2
4019         touch $DIR/$tdir/d2/test_file || error "touch failed"
4020         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4021                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
4022         cleanup_test32_mount
4023 }
4024 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
4025
4026 test_32l() {
4027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4028
4029         rm -fr $DIR/$tdir
4030         trap cleanup_test32_mount EXIT
4031         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4032         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4033                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4034         test_mkdir -p $DIR/$tdir/d2
4035         touch $DIR/$tdir/d2/test_file || error "touch failed"
4036         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
4037                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
4038         cleanup_test32_mount
4039 }
4040 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
4041
4042 test_32m() {
4043         rm -fr $DIR/d32m
4044         test_mkdir -p $DIR/d32m/tmp
4045         TMP_DIR=$DIR/d32m/tmp
4046         ln -s $DIR $TMP_DIR/symlink11
4047         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4048         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
4049                 error "symlink11 not a link"
4050         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
4051                 error "symlink01 not a link"
4052 }
4053 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
4054
4055 test_32n() {
4056         rm -fr $DIR/d32n
4057         test_mkdir -p $DIR/d32n/tmp
4058         TMP_DIR=$DIR/d32n/tmp
4059         ln -s $DIR $TMP_DIR/symlink11
4060         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
4061         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
4062         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
4063 }
4064 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
4065
4066 test_32o() {
4067         touch $DIR/$tfile
4068         test_mkdir -p $DIR/d32o/tmp
4069         TMP_DIR=$DIR/d32o/tmp
4070         ln -s $DIR/$tfile $TMP_DIR/symlink12
4071         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4072         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
4073                 error "symlink12 not a link"
4074         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
4075         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
4076                 error "$DIR/d32o/tmp/symlink12 not file type"
4077         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
4078                 error "$DIR/d32o/symlink02 not file type"
4079 }
4080 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
4081
4082 test_32p() {
4083         log 32p_1
4084         rm -fr $DIR/d32p
4085         log 32p_2
4086         rm -f $DIR/$tfile
4087         log 32p_3
4088         touch $DIR/$tfile
4089         log 32p_4
4090         test_mkdir -p $DIR/d32p/tmp
4091         log 32p_5
4092         TMP_DIR=$DIR/d32p/tmp
4093         log 32p_6
4094         ln -s $DIR/$tfile $TMP_DIR/symlink12
4095         log 32p_7
4096         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
4097         log 32p_8
4098         cat $DIR/d32p/tmp/symlink12 ||
4099                 error "Can't open $DIR/d32p/tmp/symlink12"
4100         log 32p_9
4101         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
4102         log 32p_10
4103 }
4104 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
4105
4106 test_32q() {
4107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4108
4109         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4110         trap cleanup_test32_mount EXIT
4111         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4112         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4113         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4114                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4115         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
4116         cleanup_test32_mount
4117 }
4118 run_test 32q "stat follows mountpoints in Lustre (should return error)"
4119
4120 test_32r() {
4121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4122
4123         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
4124         trap cleanup_test32_mount EXIT
4125         test_mkdir -p $DIR/$tdir/ext2-mountpoint
4126         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
4127         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
4128                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
4129         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
4130         cleanup_test32_mount
4131 }
4132 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
4133
4134 test_33aa() {
4135         rm -f $DIR/$tfile
4136         touch $DIR/$tfile
4137         chmod 444 $DIR/$tfile
4138         chown $RUNAS_ID $DIR/$tfile
4139         log 33_1
4140         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4141         log 33_2
4142 }
4143 run_test 33aa "write file with mode 444 (should return error)"
4144
4145 test_33a() {
4146         rm -fr $DIR/$tdir
4147         test_mkdir $DIR/$tdir
4148         chown $RUNAS_ID $DIR/$tdir
4149         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
4150                 error "$RUNAS create $tdir/$tfile failed"
4151         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
4152                 error "open RDWR" || true
4153 }
4154 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
4155
4156 test_33b() {
4157         rm -fr $DIR/$tdir
4158         test_mkdir $DIR/$tdir
4159         chown $RUNAS_ID $DIR/$tdir
4160         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
4161 }
4162 run_test 33b "test open file with malformed flags (No panic)"
4163
4164 test_33c() {
4165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4166         remote_ost_nodsh && skip "remote OST with nodsh"
4167
4168         local ostnum
4169         local ostname
4170         local write_bytes
4171         local all_zeros
4172
4173         all_zeros=true
4174         test_mkdir $DIR/$tdir
4175         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
4176
4177         sync
4178         for ostnum in $(seq $OSTCOUNT); do
4179                 # test-framework's OST numbering is one-based, while Lustre's
4180                 # is zero-based
4181                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4182                 # check if at least some write_bytes stats are counted
4183                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4184                               obdfilter.$ostname.stats |
4185                               awk '/^write_bytes/ {print $7}' )
4186                 echo "baseline_write_bytes@ost$ostnum/$ostname=$write_bytes"
4187                 if (( ${write_bytes:-0} > 0 )); then
4188                         all_zeros=false
4189                         break
4190                 fi
4191         done
4192
4193         $all_zeros || return 0
4194
4195         # Write four bytes
4196         echo foo > $DIR/$tdir/bar
4197         # Really write them
4198         sync
4199
4200         # Total up write_bytes after writing.  We'd better find non-zeros.
4201         for ostnum in $(seq $OSTCOUNT); do
4202                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4203                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
4204                               obdfilter/$ostname/stats |
4205                               awk '/^write_bytes/ {print $7}' )
4206                 echo "write_bytes@ost$ostnum/$ostname=$write_bytes"
4207                 if (( ${write_bytes:-0} > 0 )); then
4208                         all_zeros=false
4209                         break
4210                 fi
4211         done
4212
4213         if $all_zeros; then
4214                 for ostnum in $(seq $OSTCOUNT); do
4215                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
4216                         echo "Check write_bytes is in obdfilter.*.stats:"
4217                         do_facet ost$ostnum lctl get_param -n \
4218                                 obdfilter.$ostname.stats
4219                 done
4220                 error "OST not keeping write_bytes stats (b=22312)"
4221         fi
4222 }
4223 run_test 33c "test write_bytes stats"
4224
4225 test_33d() {
4226         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4228
4229         local MDTIDX=1
4230         local remote_dir=$DIR/$tdir/remote_dir
4231
4232         test_mkdir $DIR/$tdir
4233         $LFS mkdir -i $MDTIDX $remote_dir ||
4234                 error "create remote directory failed"
4235
4236         touch $remote_dir/$tfile
4237         chmod 444 $remote_dir/$tfile
4238         chown $RUNAS_ID $remote_dir/$tfile
4239
4240         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
4241
4242         chown $RUNAS_ID $remote_dir
4243         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
4244                                         error "create" || true
4245         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
4246                                     error "open RDWR" || true
4247         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
4248 }
4249 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
4250
4251 test_33e() {
4252         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4253
4254         mkdir $DIR/$tdir
4255
4256         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4257         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4258         mkdir $DIR/$tdir/local_dir
4259
4260         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4261         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4262         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4263
4264         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4265                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
4266
4267         rmdir $DIR/$tdir/* || error "rmdir failed"
4268
4269         umask 777
4270         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4271         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4272         mkdir $DIR/$tdir/local_dir
4273
4274         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4275         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4276         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4277
4278         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4279                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
4280
4281         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
4282
4283         umask 000
4284         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
4285         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
4286         mkdir $DIR/$tdir/local_dir
4287
4288         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
4289         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
4290         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
4291
4292         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
4293                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
4294 }
4295 run_test 33e "mkdir and striped directory should have same mode"
4296
4297 cleanup_33f() {
4298         trap 0
4299         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
4300 }
4301
4302 test_33f() {
4303         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4304         remote_mds_nodsh && skip "remote MDS with nodsh"
4305
4306         mkdir $DIR/$tdir
4307         chmod go+rwx $DIR/$tdir
4308         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
4309         trap cleanup_33f EXIT
4310
4311         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
4312                 error "cannot create striped directory"
4313
4314         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
4315                 error "cannot create files in striped directory"
4316
4317         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
4318                 error "cannot remove files in striped directory"
4319
4320         $RUNAS rmdir $DIR/$tdir/striped_dir ||
4321                 error "cannot remove striped directory"
4322
4323         cleanup_33f
4324 }
4325 run_test 33f "nonroot user can create, access, and remove a striped directory"
4326
4327 test_33g() {
4328         mkdir -p $DIR/$tdir/dir2
4329
4330         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
4331         echo $err
4332         [[ $err =~ "exists" ]] || error "Not exists error"
4333 }
4334 run_test 33g "nonroot user create already existing root created file"
4335
4336 sub_33h() {
4337         local hash_type=$1
4338         local count=250
4339
4340         test_mkdir -c $MDSCOUNT -H $hash_type $DIR/$tdir ||
4341                 error "lfs mkdir -H $hash_type $tdir failed"
4342         touch $DIR/$tdir/$tfile || error "touch $tfile failed"
4343
4344         local index=$($LFS getstripe -m $DIR/$tdir/$tfile)
4345         local index2
4346         local fname
4347
4348         for fname in $DIR/$tdir/$tfile.bak \
4349                      $DIR/$tdir/$tfile.SAV \
4350                      $DIR/$tdir/$tfile.orig \
4351                      $DIR/$tdir/$tfile~; do
4352                 touch $fname || error "touch $fname failed"
4353                 index2=$($LFS getstripe -m $fname)
4354                 (( $index == $index2 )) ||
4355                         error "$fname MDT index mismatch $index != $index2"
4356         done
4357
4358         local failed=0
4359         local patterns=(".$tfile.XXXXXX" "$tfile.XXXXXXXX")
4360         local pattern
4361
4362         for pattern in ${patterns[*]}; do
4363                 echo "pattern $pattern"
4364                 fname=$DIR/$tdir/$pattern
4365                 for (( i = 0; i < $count; i++ )); do
4366                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4367                                 error "mktemp $DIR/$tdir/$pattern failed"
4368                         index2=$($LFS getstripe -m $fname)
4369                         (( $index == $index2 )) && continue
4370
4371                         failed=$((failed + 1))
4372                         echo "$fname MDT index mismatch $index != $index2"
4373                 done
4374         done
4375
4376         echo "$failed/$count MDT index mismatches, expect ~2-4"
4377         (( failed < 10 )) || error "MDT index mismatch $failed/$count times"
4378
4379         local same=0
4380         local expect
4381
4382         # verify that "crush" is still broken with all files on same MDT,
4383         # crush2 should have about 1/MDSCOUNT files on each MDT, with margin
4384         [[ "$hash_type" == "crush" ]] && expect=$count ||
4385                 expect=$((count / MDSCOUNT))
4386
4387         # crush2 doesn't put all-numeric suffixes on the same MDT,
4388         # filename like $tfile.12345678 should *not* be considered temp
4389         for pattern in ${patterns[*]}; do
4390                 local base=${pattern%%X*}
4391                 local suff=${pattern#$base}
4392
4393                 echo "pattern $pattern"
4394                 for (( i = 0; i < $count; i++ )); do
4395                         fname=$DIR/$tdir/$base$((${suff//X/1} + i))
4396                         touch $fname || error "touch $fname failed"
4397                         index2=$($LFS getstripe -m $fname)
4398                         (( $index != $index2 )) && continue
4399
4400                         same=$((same + 1))
4401                 done
4402         done
4403
4404         # the number of "bad" hashes is random, as it depends on the random
4405         # filenames generated by "mktemp".  Allow some margin in the results.
4406         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4407         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4408            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4409                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4410         same=0
4411
4412         # crush2 doesn't put suffixes with special characters on the same MDT
4413         # filename like $tfile.txt.1234 should *not* be considered temp
4414         for pattern in ${patterns[*]}; do
4415                 local base=${pattern%%X*}
4416                 local suff=${pattern#$base}
4417
4418                 pattern=$base...${suff/XXX}
4419                 echo "pattern=$pattern"
4420                 for (( i = 0; i < $count; i++ )); do
4421                         fname=$(mktemp $DIR/$tdir/$pattern) ||
4422                                 error "touch $fname failed"
4423                         index2=$($LFS getstripe -m $fname)
4424                         (( $index != $index2 )) && continue
4425
4426                         same=$((same + 1))
4427                 done
4428         done
4429
4430         # the number of "bad" hashes is random, as it depends on the random
4431         # filenames generated by "mktemp".  Allow some margin in the results.
4432         echo "$((same/${#patterns[*]}))/$count matches, expect ~$expect for $1"
4433         (( same / ${#patterns[*]} <= expect * 9 / 7 &&
4434            same / ${#patterns[*]} > expect * 5 / 7 )) ||
4435                 error "MDT index match $((same / ${#patterns[*]}))/$count times"
4436 }
4437
4438 test_33h() {
4439         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4440         (( $MDS1_VERSION >= $(version_code 2.13.50) )) ||
4441                 skip "Need MDS version at least 2.13.50"
4442
4443         sub_33h crush
4444 }
4445 run_test 33h "temp file is located on the same MDT as target (crush)"
4446
4447 test_33hh() {
4448         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4449         echo "MDS1_VERSION=$MDS1_VERSION version_code=$(version_code 2.15.0)"
4450         (( $MDS1_VERSION > $(version_code 2.15.0) )) ||
4451                 skip "Need MDS version at least 2.15.0 for crush2"
4452
4453         sub_33h crush2
4454 }
4455 run_test 33hh "temp file is located on the same MDT as target (crush2)"
4456
4457 test_33i()
4458 {
4459         (( MDSCOUNT < 2 )) && skip "needs >= 2 MDTs"
4460
4461         local FNAME=$(str_repeat 'f' 250)
4462
4463         test_mkdir -i 0 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
4464         createmany -o $DIR/$tdir/$FNAME 1000 || error "createmany failed"
4465
4466         local count
4467         local total
4468
4469         count=$($LFS getstripe -m $DIR/$tdir/* | grep -cw 1)
4470
4471         local MDC=$(lctl dl | awk '/MDT0001-mdc-[^M]/ { print $4 }')
4472
4473         lctl --device %$MDC deactivate
4474         stack_trap "lctl --device %$MDC activate"
4475         ls $DIR/$tdir > /dev/null && error "ls should return an error"
4476         total=$(\ls -l $DIR/$tdir | wc -l)
4477         # "ls -l" will list total in the first line
4478         total=$((total - 1))
4479         (( total + count == 1000 )) ||
4480                 error "ls list $total files, $count files on MDT1"
4481 }
4482 run_test 33i "striped directory can be accessed when one MDT is down"
4483
4484 test_33j() {
4485         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
4486
4487         mkdir -p $DIR/$tdir/
4488
4489         $LFS setdirstripe -D -i0,1 $DIR/$tdir/striped_dir_a &&
4490                 error "setdirstripe -D -i0,1 incorrectly succeeded"
4491
4492         $LFS setdirstripe -D -i0,1 -c1 $DIR/$tdir/striped_dir_b &&
4493                 error "setdirstripe -D -i0,1 -c1 incorrectly succeeded"
4494
4495         $LFS setdirstripe -D -i0,1 -c3 $DIR/$tdir/striped_dir_c &&
4496                 error "setdirstripe -D -i0,1 -c3 incorrectly succeeded"
4497
4498         $LFS setdirstripe -i0,1 $DIR/$tdir/striped_dir_e ||
4499                 error "-D was not specified, but still failed"
4500 }
4501 run_test 33j "lfs setdirstripe -D -i x,y,x should fail"
4502
4503 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
4504 test_34a() {
4505         rm -f $DIR/f34
4506         $MCREATE $DIR/f34 || error "mcreate failed"
4507         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4508                 error "getstripe failed"
4509         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
4510         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4511                 error "getstripe failed"
4512         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4513                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4514 }
4515 run_test 34a "truncate file that has not been opened ==========="
4516
4517 test_34b() {
4518         [ ! -f $DIR/f34 ] && test_34a
4519         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4520                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4521         $OPENFILE -f O_RDONLY $DIR/f34
4522         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
4523                 error "getstripe failed"
4524         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4525                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4526 }
4527 run_test 34b "O_RDONLY opening file doesn't create objects ====="
4528
4529 test_34c() {
4530         [ ! -f $DIR/f34 ] && test_34a
4531         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4532                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4533         $OPENFILE -f O_RDWR $DIR/f34
4534         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
4535                 error "$LFS getstripe failed"
4536         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4537                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4538 }
4539 run_test 34c "O_RDWR opening file-with-size works =============="
4540
4541 test_34d() {
4542         [ ! -f $DIR/f34 ] && test_34a
4543         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
4544                 error "dd failed"
4545         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
4546                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
4547         rm $DIR/f34
4548 }
4549 run_test 34d "write to sparse file ============================="
4550
4551 test_34e() {
4552         rm -f $DIR/f34e
4553         $MCREATE $DIR/f34e || error "mcreate failed"
4554         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
4555         $CHECKSTAT -s 1000 $DIR/f34e ||
4556                 error "Size of $DIR/f34e not equal to 1000 bytes"
4557         $OPENFILE -f O_RDWR $DIR/f34e
4558         $CHECKSTAT -s 1000 $DIR/f34e ||
4559                 error "Size of $DIR/f34e not equal to 1000 bytes"
4560 }
4561 run_test 34e "create objects, some with size and some without =="
4562
4563 test_34f() { # bug 6242, 6243
4564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4565
4566         SIZE34F=48000
4567         rm -f $DIR/f34f
4568         $MCREATE $DIR/f34f || error "mcreate failed"
4569         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
4570         dd if=$DIR/f34f of=$TMP/f34f
4571         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
4572         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
4573         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
4574         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
4575         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
4576 }
4577 run_test 34f "read from a file with no objects until EOF ======="
4578
4579 test_34g() {
4580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4581
4582         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
4583                 error "dd failed"
4584         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
4585         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4586                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
4587         cancel_lru_locks osc
4588         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
4589                 error "wrong size after lock cancel"
4590
4591         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
4592         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4593                 error "expanding truncate failed"
4594         cancel_lru_locks osc
4595         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
4596                 error "wrong expanded size after lock cancel"
4597 }
4598 run_test 34g "truncate long file ==============================="
4599
4600 test_34h() {
4601         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4602
4603         local gid=10
4604         local sz=1000
4605
4606         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
4607         sync # Flush the cache so that multiop below does not block on cache
4608              # flush when getting the group lock
4609         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
4610         MULTIPID=$!
4611
4612         # Since just timed wait is not good enough, let's do a sync write
4613         # that way we are sure enough time for a roundtrip + processing
4614         # passed + 2 seconds of extra margin.
4615         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
4616         rm $DIR/${tfile}-1
4617         sleep 2
4618
4619         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
4620                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
4621                 kill -9 $MULTIPID
4622         fi
4623         wait $MULTIPID
4624         local nsz=`stat -c %s $DIR/$tfile`
4625         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
4626 }
4627 run_test 34h "ftruncate file under grouplock should not block"
4628
4629 test_35a() {
4630         cp /bin/sh $DIR/f35a
4631         chmod 444 $DIR/f35a
4632         chown $RUNAS_ID $DIR/f35a
4633         $RUNAS $DIR/f35a && error || true
4634         rm $DIR/f35a
4635 }
4636 run_test 35a "exec file with mode 444 (should return and not leak)"
4637
4638 test_36a() {
4639         rm -f $DIR/f36
4640         utime $DIR/f36 || error "utime failed for MDS"
4641 }
4642 run_test 36a "MDS utime check (mknod, utime)"
4643
4644 test_36b() {
4645         echo "" > $DIR/f36
4646         utime $DIR/f36 || error "utime failed for OST"
4647 }
4648 run_test 36b "OST utime check (open, utime)"
4649
4650 test_36c() {
4651         rm -f $DIR/d36/f36
4652         test_mkdir $DIR/d36
4653         chown $RUNAS_ID $DIR/d36
4654         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
4655 }
4656 run_test 36c "non-root MDS utime check (mknod, utime)"
4657
4658 test_36d() {
4659         [ ! -d $DIR/d36 ] && test_36c
4660         echo "" > $DIR/d36/f36
4661         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
4662 }
4663 run_test 36d "non-root OST utime check (open, utime)"
4664
4665 test_36e() {
4666         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
4667
4668         test_mkdir $DIR/$tdir
4669         touch $DIR/$tdir/$tfile
4670         $RUNAS utime $DIR/$tdir/$tfile &&
4671                 error "utime worked, expected failure" || true
4672 }
4673 run_test 36e "utime on non-owned file (should return error)"
4674
4675 subr_36fh() {
4676         local fl="$1"
4677         local LANG_SAVE=$LANG
4678         local LC_LANG_SAVE=$LC_LANG
4679         export LANG=C LC_LANG=C # for date language
4680
4681         DATESTR="Dec 20  2000"
4682         test_mkdir $DIR/$tdir
4683         lctl set_param fail_loc=$fl
4684         date; date +%s
4685         cp /etc/hosts $DIR/$tdir/$tfile
4686         sync & # write RPC generated with "current" inode timestamp, but delayed
4687         sleep 1
4688         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
4689         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
4690         cancel_lru_locks $OSC
4691         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
4692         date; date +%s
4693         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
4694                 echo "BEFORE: $LS_BEFORE" && \
4695                 echo "AFTER : $LS_AFTER" && \
4696                 echo "WANT  : $DATESTR" && \
4697                 error "$DIR/$tdir/$tfile timestamps changed" || true
4698
4699         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
4700 }
4701
4702 test_36f() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
4706         subr_36fh "0x80000214"
4707 }
4708 run_test 36f "utime on file racing with OST BRW write =========="
4709
4710 test_36g() {
4711         remote_ost_nodsh && skip "remote OST with nodsh"
4712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4713         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
4714                 skip "Need MDS version at least 2.12.51"
4715
4716         local fmd_max_age
4717         local fmd
4718         local facet="ost1"
4719         local tgt="obdfilter"
4720
4721         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
4722
4723         test_mkdir $DIR/$tdir
4724         fmd_max_age=$(do_facet $facet \
4725                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
4726                 head -n 1")
4727
4728         echo "FMD max age: ${fmd_max_age}s"
4729         touch $DIR/$tdir/$tfile
4730         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4731                 gawk '{cnt=cnt+$1}  END{print cnt}')
4732         echo "FMD before: $fmd"
4733         [[ $fmd == 0 ]] &&
4734                 error "FMD wasn't create by touch"
4735         sleep $((fmd_max_age + 12))
4736         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
4737                 gawk '{cnt=cnt+$1}  END{print cnt}')
4738         echo "FMD after: $fmd"
4739         [[ $fmd == 0 ]] ||
4740                 error "FMD wasn't expired by ping"
4741 }
4742 run_test 36g "FMD cache expiry ====================="
4743
4744 test_36h() {
4745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4746
4747         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
4748         subr_36fh "0x80000227"
4749 }
4750 run_test 36h "utime on file racing with OST BRW write =========="
4751
4752 test_36i() {
4753         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
4754
4755         test_mkdir $DIR/$tdir
4756         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
4757
4758         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
4759         local new_mtime=$((mtime + 200))
4760
4761         #change Modify time of striped dir
4762         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4763                         error "change mtime failed"
4764
4765         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4766
4767         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4768 }
4769 run_test 36i "change mtime on striped directory"
4770
4771 # test_37 - duplicate with tests 32q 32r
4772
4773 test_38() {
4774         local file=$DIR/$tfile
4775         touch $file
4776         openfile -f O_DIRECTORY $file
4777         local RC=$?
4778         local ENOTDIR=20
4779         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4780         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4781 }
4782 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4783
4784 test_39a() { # was test_39
4785         touch $DIR/$tfile
4786         touch $DIR/${tfile}2
4787 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4788 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4789 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4790         sleep 2
4791         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4792         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4793                 echo "mtime"
4794                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4795                 echo "atime"
4796                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4797                 echo "ctime"
4798                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4799                 error "O_TRUNC didn't change timestamps"
4800         fi
4801 }
4802 run_test 39a "mtime changed on create"
4803
4804 test_39b() {
4805         test_mkdir -c1 $DIR/$tdir
4806         cp -p /etc/passwd $DIR/$tdir/fopen
4807         cp -p /etc/passwd $DIR/$tdir/flink
4808         cp -p /etc/passwd $DIR/$tdir/funlink
4809         cp -p /etc/passwd $DIR/$tdir/frename
4810         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4811
4812         sleep 1
4813         echo "aaaaaa" >> $DIR/$tdir/fopen
4814         echo "aaaaaa" >> $DIR/$tdir/flink
4815         echo "aaaaaa" >> $DIR/$tdir/funlink
4816         echo "aaaaaa" >> $DIR/$tdir/frename
4817
4818         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4819         local link_new=`stat -c %Y $DIR/$tdir/flink`
4820         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4821         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4822
4823         cat $DIR/$tdir/fopen > /dev/null
4824         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4825         rm -f $DIR/$tdir/funlink2
4826         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4827
4828         for (( i=0; i < 2; i++ )) ; do
4829                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4830                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4831                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4832                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4833
4834                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4835                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4836                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4837                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4838
4839                 cancel_lru_locks $OSC
4840                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4841         done
4842 }
4843 run_test 39b "mtime change on open, link, unlink, rename  ======"
4844
4845 # this should be set to past
4846 TEST_39_MTIME=`date -d "1 year ago" +%s`
4847
4848 # bug 11063
4849 test_39c() {
4850         touch $DIR1/$tfile
4851         sleep 2
4852         local mtime0=`stat -c %Y $DIR1/$tfile`
4853
4854         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4855         local mtime1=`stat -c %Y $DIR1/$tfile`
4856         [ "$mtime1" = $TEST_39_MTIME ] || \
4857                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4858
4859         local d1=`date +%s`
4860         echo hello >> $DIR1/$tfile
4861         local d2=`date +%s`
4862         local mtime2=`stat -c %Y $DIR1/$tfile`
4863         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4864                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4865
4866         mv $DIR1/$tfile $DIR1/$tfile-1
4867
4868         for (( i=0; i < 2; i++ )) ; do
4869                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4870                 [ "$mtime2" = "$mtime3" ] || \
4871                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4872
4873                 cancel_lru_locks $OSC
4874                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4875         done
4876 }
4877 run_test 39c "mtime change on rename ==========================="
4878
4879 # bug 21114
4880 test_39d() {
4881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4882
4883         touch $DIR1/$tfile
4884         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4885
4886         for (( i=0; i < 2; i++ )) ; do
4887                 local mtime=`stat -c %Y $DIR1/$tfile`
4888                 [ $mtime = $TEST_39_MTIME ] || \
4889                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4890
4891                 cancel_lru_locks $OSC
4892                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4893         done
4894 }
4895 run_test 39d "create, utime, stat =============================="
4896
4897 # bug 21114
4898 test_39e() {
4899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4900
4901         touch $DIR1/$tfile
4902         local mtime1=`stat -c %Y $DIR1/$tfile`
4903
4904         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4905
4906         for (( i=0; i < 2; i++ )) ; do
4907                 local mtime2=`stat -c %Y $DIR1/$tfile`
4908                 [ $mtime2 = $TEST_39_MTIME ] || \
4909                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4910
4911                 cancel_lru_locks $OSC
4912                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4913         done
4914 }
4915 run_test 39e "create, stat, utime, stat ========================"
4916
4917 # bug 21114
4918 test_39f() {
4919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4920
4921         touch $DIR1/$tfile
4922         mtime1=`stat -c %Y $DIR1/$tfile`
4923
4924         sleep 2
4925         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4926
4927         for (( i=0; i < 2; i++ )) ; do
4928                 local mtime2=`stat -c %Y $DIR1/$tfile`
4929                 [ $mtime2 = $TEST_39_MTIME ] || \
4930                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4931
4932                 cancel_lru_locks $OSC
4933                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4934         done
4935 }
4936 run_test 39f "create, stat, sleep, utime, stat ================="
4937
4938 # bug 11063
4939 test_39g() {
4940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4941
4942         echo hello >> $DIR1/$tfile
4943         local mtime1=`stat -c %Y $DIR1/$tfile`
4944
4945         sleep 2
4946         chmod o+r $DIR1/$tfile
4947
4948         for (( i=0; i < 2; i++ )) ; do
4949                 local mtime2=`stat -c %Y $DIR1/$tfile`
4950                 [ "$mtime1" = "$mtime2" ] || \
4951                         error "lost mtime: $mtime2, should be $mtime1"
4952
4953                 cancel_lru_locks $OSC
4954                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4955         done
4956 }
4957 run_test 39g "write, chmod, stat ==============================="
4958
4959 # bug 11063
4960 test_39h() {
4961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4962
4963         touch $DIR1/$tfile
4964         sleep 1
4965
4966         local d1=`date`
4967         echo hello >> $DIR1/$tfile
4968         local mtime1=`stat -c %Y $DIR1/$tfile`
4969
4970         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4971         local d2=`date`
4972         if [ "$d1" != "$d2" ]; then
4973                 echo "write and touch not within one second"
4974         else
4975                 for (( i=0; i < 2; i++ )) ; do
4976                         local mtime2=`stat -c %Y $DIR1/$tfile`
4977                         [ "$mtime2" = $TEST_39_MTIME ] || \
4978                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4979
4980                         cancel_lru_locks $OSC
4981                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4982                 done
4983         fi
4984 }
4985 run_test 39h "write, utime within one second, stat ============="
4986
4987 test_39i() {
4988         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4989
4990         touch $DIR1/$tfile
4991         sleep 1
4992
4993         echo hello >> $DIR1/$tfile
4994         local mtime1=`stat -c %Y $DIR1/$tfile`
4995
4996         mv $DIR1/$tfile $DIR1/$tfile-1
4997
4998         for (( i=0; i < 2; i++ )) ; do
4999                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5000
5001                 [ "$mtime1" = "$mtime2" ] || \
5002                         error "lost mtime: $mtime2, should be $mtime1"
5003
5004                 cancel_lru_locks $OSC
5005                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5006         done
5007 }
5008 run_test 39i "write, rename, stat =============================="
5009
5010 test_39j() {
5011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5012
5013         start_full_debug_logging
5014         touch $DIR1/$tfile
5015         sleep 1
5016
5017         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
5018         lctl set_param fail_loc=0x80000412
5019         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
5020                 error "multiop failed"
5021         local multipid=$!
5022         local mtime1=`stat -c %Y $DIR1/$tfile`
5023
5024         mv $DIR1/$tfile $DIR1/$tfile-1
5025
5026         kill -USR1 $multipid
5027         wait $multipid || error "multiop close failed"
5028
5029         for (( i=0; i < 2; i++ )) ; do
5030                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
5031                 [ "$mtime1" = "$mtime2" ] ||
5032                         error "mtime is lost on close: $mtime2, " \
5033                               "should be $mtime1"
5034
5035                 cancel_lru_locks
5036                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5037         done
5038         lctl set_param fail_loc=0
5039         stop_full_debug_logging
5040 }
5041 run_test 39j "write, rename, close, stat ======================="
5042
5043 test_39k() {
5044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5045
5046         touch $DIR1/$tfile
5047         sleep 1
5048
5049         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
5050         local multipid=$!
5051         local mtime1=`stat -c %Y $DIR1/$tfile`
5052
5053         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
5054
5055         kill -USR1 $multipid
5056         wait $multipid || error "multiop close failed"
5057
5058         for (( i=0; i < 2; i++ )) ; do
5059                 local mtime2=`stat -c %Y $DIR1/$tfile`
5060
5061                 [ "$mtime2" = $TEST_39_MTIME ] || \
5062                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
5063
5064                 cancel_lru_locks
5065                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5066         done
5067 }
5068 run_test 39k "write, utime, close, stat ========================"
5069
5070 # this should be set to future
5071 TEST_39_ATIME=`date -d "1 year" +%s`
5072
5073 test_39l() {
5074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5075         remote_mds_nodsh && skip "remote MDS with nodsh"
5076
5077         local atime_diff=$(do_facet $SINGLEMDS \
5078                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5079         rm -rf $DIR/$tdir
5080         mkdir_on_mdt0 $DIR/$tdir
5081
5082         # test setting directory atime to future
5083         touch -a -d @$TEST_39_ATIME $DIR/$tdir
5084         local atime=$(stat -c %X $DIR/$tdir)
5085         [ "$atime" = $TEST_39_ATIME ] ||
5086                 error "atime is not set to future: $atime, $TEST_39_ATIME"
5087
5088         # test setting directory atime from future to now
5089         local now=$(date +%s)
5090         touch -a -d @$now $DIR/$tdir
5091
5092         atime=$(stat -c %X $DIR/$tdir)
5093         [ "$atime" -eq "$now"  ] ||
5094                 error "atime is not updated from future: $atime, $now"
5095
5096         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
5097         sleep 3
5098
5099         # test setting directory atime when now > dir atime + atime_diff
5100         local d1=$(date +%s)
5101         ls $DIR/$tdir
5102         local d2=$(date +%s)
5103         cancel_lru_locks mdc
5104         atime=$(stat -c %X $DIR/$tdir)
5105         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5106                 error "atime is not updated  : $atime, should be $d2"
5107
5108         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
5109         sleep 3
5110
5111         # test not setting directory atime when now < dir atime + atime_diff
5112         ls $DIR/$tdir
5113         cancel_lru_locks mdc
5114         atime=$(stat -c %X $DIR/$tdir)
5115         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
5116                 error "atime is updated to $atime, should remain $d1<atime<$d2"
5117
5118         do_facet $SINGLEMDS \
5119                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5120 }
5121 run_test 39l "directory atime update ==========================="
5122
5123 test_39m() {
5124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5125
5126         touch $DIR1/$tfile
5127         sleep 2
5128         local far_past_mtime=$(date -d "May 29 1953" +%s)
5129         local far_past_atime=$(date -d "Dec 17 1903" +%s)
5130
5131         touch -m -d @$far_past_mtime $DIR1/$tfile
5132         touch -a -d @$far_past_atime $DIR1/$tfile
5133
5134         for (( i=0; i < 2; i++ )) ; do
5135                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
5136                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
5137                         error "atime or mtime set incorrectly"
5138
5139                 cancel_lru_locks $OSC
5140                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
5141         done
5142 }
5143 run_test 39m "test atime and mtime before 1970"
5144
5145 test_39n() { # LU-3832
5146         remote_mds_nodsh && skip "remote MDS with nodsh"
5147
5148         local atime_diff=$(do_facet $SINGLEMDS \
5149                 lctl get_param -n mdd.*MDT0000*.atime_diff)
5150         local atime0
5151         local atime1
5152         local atime2
5153
5154         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
5155
5156         rm -rf $DIR/$tfile
5157         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
5158         atime0=$(stat -c %X $DIR/$tfile)
5159
5160         sleep 5
5161         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5162         atime1=$(stat -c %X $DIR/$tfile)
5163
5164         sleep 5
5165         cancel_lru_locks mdc
5166         cancel_lru_locks osc
5167         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
5168         atime2=$(stat -c %X $DIR/$tfile)
5169
5170         do_facet $SINGLEMDS \
5171                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
5172
5173         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
5174         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
5175 }
5176 run_test 39n "check that O_NOATIME is honored"
5177
5178 test_39o() {
5179         TESTDIR=$DIR/$tdir/$tfile
5180         [ -e $TESTDIR ] && rm -rf $TESTDIR
5181         mkdir -p $TESTDIR
5182         cd $TESTDIR
5183         links1=2
5184         ls
5185         mkdir a b
5186         ls
5187         links2=$(stat -c %h .)
5188         [ $(($links1 + 2)) != $links2 ] &&
5189                 error "wrong links count $(($links1 + 2)) != $links2"
5190         rmdir b
5191         links3=$(stat -c %h .)
5192         [ $(($links1 + 1)) != $links3 ] &&
5193                 error "wrong links count $links1 != $links3"
5194         return 0
5195 }
5196 run_test 39o "directory cached attributes updated after create"
5197
5198 test_39p() {
5199         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
5200
5201         local MDTIDX=1
5202         TESTDIR=$DIR/$tdir/$tdir
5203         [ -e $TESTDIR ] && rm -rf $TESTDIR
5204         test_mkdir -p $TESTDIR
5205         cd $TESTDIR
5206         links1=2
5207         ls
5208         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
5209         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
5210         ls
5211         links2=$(stat -c %h .)
5212         [ $(($links1 + 2)) != $links2 ] &&
5213                 error "wrong links count $(($links1 + 2)) != $links2"
5214         rmdir remote_dir2
5215         links3=$(stat -c %h .)
5216         [ $(($links1 + 1)) != $links3 ] &&
5217                 error "wrong links count $links1 != $links3"
5218         return 0
5219 }
5220 run_test 39p "remote directory cached attributes updated after create ========"
5221
5222 test_39r() {
5223         [ $OST1_VERSION -ge $(version_code 2.13.52) ] ||
5224                 skip "no atime update on old OST"
5225         if [ "$ost1_FSTYPE" != ldiskfs ]; then
5226                 skip_env "ldiskfs only test"
5227         fi
5228
5229         local saved_adiff
5230         saved_adiff=$(do_facet ost1 \
5231                 lctl get_param -n obdfilter.*OST0000.atime_diff)
5232         stack_trap "do_facet ost1 \
5233                 lctl set_param obdfilter.*.atime_diff=$saved_adiff"
5234
5235         do_facet ost1 "lctl set_param obdfilter.*.atime_diff=5"
5236
5237         $LFS setstripe -i 0 $DIR/$tfile
5238         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 ||
5239                 error "can't write initial file"
5240         cancel_lru_locks osc
5241
5242         # exceed atime_diff and access file
5243         sleep 10
5244         dd if=$DIR/$tfile of=/dev/null bs=4k count=1 ||
5245                 error "can't udpate atime"
5246
5247         local atime_cli=$(stat -c %X $DIR/$tfile)
5248         echo "client atime: $atime_cli"
5249         # allow atime update to be written to device
5250         do_facet ost1 "$LCTL set_param -n osd*.*OST*.force_sync 1"
5251         sleep 5
5252
5253         local ostdev=$(ostdevname 1)
5254         local fid=($($LFS getstripe $DIR/$tfile | grep 0x))
5255         local seq=${fid[3]#0x}
5256         local oid=${fid[1]}
5257         local oid_hex
5258
5259         if [ $seq == 0 ]; then
5260                 oid_hex=${fid[1]}
5261         else
5262                 oid_hex=${fid[2]#0x}
5263         fi
5264         local objpath="O/$seq/d$(($oid % 32))/$oid_hex"
5265         local cmd="debugfs -c -R \\\"stat $objpath\\\" $ostdev"
5266
5267         echo "OST atime: $(do_facet ost1 "$cmd" |& grep atime)"
5268         local atime_ost=$(do_facet ost1 "$cmd" |&
5269                           awk -F'[: ]' '/atime:/ { print $4 }')
5270         (( atime_cli == atime_ost )) ||
5271                 error "atime on client $atime_cli != ost $atime_ost"
5272 }
5273 run_test 39r "lazy atime update on OST"
5274
5275 test_39q() { # LU-8041
5276         local testdir=$DIR/$tdir
5277         mkdir -p $testdir
5278         multiop_bg_pause $testdir D_c || error "multiop failed"
5279         local multipid=$!
5280         cancel_lru_locks mdc
5281         kill -USR1 $multipid
5282         local atime=$(stat -c %X $testdir)
5283         [ "$atime" -ne 0 ] || error "atime is zero"
5284 }
5285 run_test 39q "close won't zero out atime"
5286
5287 test_39s() {
5288         local atime0
5289         local atime1
5290         local atime2
5291         local atime3
5292         local atime4
5293
5294         umount_client $MOUNT
5295         mount_client $MOUNT relatime
5296
5297         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer conv=fsync
5298         atime0=$(stat -c %X $DIR/$tfile)
5299
5300         # First read updates atime
5301         sleep 1
5302         cat $DIR/$tfile >/dev/null
5303         atime1=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5304
5305         # Next reads do not update atime
5306         sleep 1
5307         cat $DIR/$tfile >/dev/null
5308         atime2=$(stat -c %X $DIR/$tfile) # (atime = atime0 + 1)
5309
5310         # If mtime is greater than atime, atime is updated
5311         sleep 1
5312         touch -m $DIR/$tfile # (mtime = now)
5313         sleep 1
5314         cat $DIR/$tfile >/dev/null # (atime is updated because atime < mtime)
5315         atime3=$(stat -c %X $DIR/$tfile) # (atime = mtime = atime0 + 3)
5316
5317         # Next reads do not update atime
5318         sleep 1
5319         cat $DIR/$tfile >/dev/null
5320         atime4=$(stat -c %X $DIR/$tfile)
5321
5322         # Remount the client to clear 'relatime' option
5323         remount_client $MOUNT
5324
5325         (( atime0 < atime1 )) ||
5326                 error "atime $atime0 should be smaller than $atime1"
5327         (( atime1 == atime2 )) ||
5328                 error "atime $atime1 was updated to $atime2"
5329         (( atime1 < atime3 )) || error "atime1 $atime1 != atime3 $atime3"
5330         (( atime3 == atime4 )) || error "atime3 $atime3 != atime4 $atime4"
5331 }
5332 run_test 39s "relatime is supported"
5333
5334 test_40() {
5335         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
5336         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
5337                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
5338         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
5339                 error "$tfile is not 4096 bytes in size"
5340 }
5341 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
5342
5343 test_41() {
5344         # bug 1553
5345         small_write $DIR/f41 18
5346 }
5347 run_test 41 "test small file write + fstat ====================="
5348
5349 count_ost_writes() {
5350         lctl get_param -n ${OSC}.*.stats |
5351                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
5352                         END { printf("%0.0f", writes) }'
5353 }
5354
5355 # decent default
5356 WRITEBACK_SAVE=500
5357 DIRTY_RATIO_SAVE=40
5358 MAX_DIRTY_RATIO=50
5359 BG_DIRTY_RATIO_SAVE=10
5360 MAX_BG_DIRTY_RATIO=25
5361
5362 start_writeback() {
5363         trap 0
5364         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
5365         # dirty_ratio, dirty_background_ratio
5366         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5367                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
5368                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
5369                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
5370         else
5371                 # if file not here, we are a 2.4 kernel
5372                 kill -CONT `pidof kupdated`
5373         fi
5374 }
5375
5376 stop_writeback() {
5377         # setup the trap first, so someone cannot exit the test at the
5378         # exact wrong time and mess up a machine
5379         trap start_writeback EXIT
5380         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
5381         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
5382                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
5383                 sysctl -w vm.dirty_writeback_centisecs=0
5384                 sysctl -w vm.dirty_writeback_centisecs=0
5385                 # save and increase /proc/sys/vm/dirty_ratio
5386                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
5387                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
5388                 # save and increase /proc/sys/vm/dirty_background_ratio
5389                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
5390                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
5391         else
5392                 # if file not here, we are a 2.4 kernel
5393                 kill -STOP `pidof kupdated`
5394         fi
5395 }
5396
5397 # ensure that all stripes have some grant before we test client-side cache
5398 setup_test42() {
5399         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
5400                 dd if=/dev/zero of=$i bs=4k count=1
5401                 rm $i
5402         done
5403 }
5404
5405 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
5406 # file truncation, and file removal.
5407 test_42a() {
5408         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5409
5410         setup_test42
5411         cancel_lru_locks $OSC
5412         stop_writeback
5413         sync; sleep 1; sync # just to be safe
5414         BEFOREWRITES=`count_ost_writes`
5415         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
5416         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
5417         AFTERWRITES=`count_ost_writes`
5418         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
5419                 error "$BEFOREWRITES < $AFTERWRITES"
5420         start_writeback
5421 }
5422 run_test 42a "ensure that we don't flush on close"
5423
5424 test_42b() {
5425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5426
5427         setup_test42
5428         cancel_lru_locks $OSC
5429         stop_writeback
5430         sync
5431         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
5432         BEFOREWRITES=$(count_ost_writes)
5433         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
5434         AFTERWRITES=$(count_ost_writes)
5435         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5436                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
5437         fi
5438         BEFOREWRITES=$(count_ost_writes)
5439         sync || error "sync: $?"
5440         AFTERWRITES=$(count_ost_writes)
5441         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
5442                 error "$BEFOREWRITES < $AFTERWRITES on sync"
5443         fi
5444         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
5445         start_writeback
5446         return 0
5447 }
5448 run_test 42b "test destroy of file with cached dirty data ======"
5449
5450 # if these tests just want to test the effect of truncation,
5451 # they have to be very careful.  consider:
5452 # - the first open gets a {0,EOF}PR lock
5453 # - the first write conflicts and gets a {0, count-1}PW
5454 # - the rest of the writes are under {count,EOF}PW
5455 # - the open for truncate tries to match a {0,EOF}PR
5456 #   for the filesize and cancels the PWs.
5457 # any number of fixes (don't get {0,EOF} on open, match
5458 # composite locks, do smarter file size management) fix
5459 # this, but for now we want these tests to verify that
5460 # the cancellation with truncate intent works, so we
5461 # start the file with a full-file pw lock to match against
5462 # until the truncate.
5463 trunc_test() {
5464         test=$1
5465         file=$DIR/$test
5466         offset=$2
5467         cancel_lru_locks $OSC
5468         stop_writeback
5469         # prime the file with 0,EOF PW to match
5470         touch $file
5471         $TRUNCATE $file 0
5472         sync; sync
5473         # now the real test..
5474         dd if=/dev/zero of=$file bs=1024 count=100
5475         BEFOREWRITES=`count_ost_writes`
5476         $TRUNCATE $file $offset
5477         cancel_lru_locks $OSC
5478         AFTERWRITES=`count_ost_writes`
5479         start_writeback
5480 }
5481
5482 test_42c() {
5483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5484
5485         trunc_test 42c 1024
5486         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
5487                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
5488         rm $file
5489 }
5490 run_test 42c "test partial truncate of file with cached dirty data"
5491
5492 test_42d() {
5493         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5494
5495         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
5496         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
5497         $LCTL set_param debug=+cache
5498
5499         trunc_test 42d 0
5500         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
5501                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
5502         rm $file
5503 }
5504 run_test 42d "test complete truncate of file with cached dirty data"
5505
5506 test_42e() { # bug22074
5507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5508
5509         local TDIR=$DIR/${tdir}e
5510         local pages=16 # hardcoded 16 pages, don't change it.
5511         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
5512         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
5513         local max_dirty_mb
5514         local warmup_files
5515
5516         test_mkdir $DIR/${tdir}e
5517         $LFS setstripe -c 1 $TDIR
5518         createmany -o $TDIR/f $files
5519
5520         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
5521
5522         # we assume that with $OSTCOUNT files, at least one of them will
5523         # be allocated on OST0.
5524         warmup_files=$((OSTCOUNT * max_dirty_mb))
5525         createmany -o $TDIR/w $warmup_files
5526
5527         # write a large amount of data into one file and sync, to get good
5528         # avail_grant number from OST.
5529         for ((i=0; i<$warmup_files; i++)); do
5530                 idx=$($LFS getstripe -i $TDIR/w$i)
5531                 [ $idx -ne 0 ] && continue
5532                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
5533                 break
5534         done
5535         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
5536         sync
5537         $LCTL get_param $proc_osc0/cur_dirty_bytes
5538         $LCTL get_param $proc_osc0/cur_grant_bytes
5539
5540         # create as much dirty pages as we can while not to trigger the actual
5541         # RPCs directly. but depends on the env, VFS may trigger flush during this
5542         # period, hopefully we are good.
5543         for ((i=0; i<$warmup_files; i++)); do
5544                 idx=$($LFS getstripe -i $TDIR/w$i)
5545                 [ $idx -ne 0 ] && continue
5546                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
5547         done
5548         $LCTL get_param $proc_osc0/cur_dirty_bytes
5549         $LCTL get_param $proc_osc0/cur_grant_bytes
5550
5551         # perform the real test
5552         $LCTL set_param $proc_osc0/rpc_stats 0
5553         for ((;i<$files; i++)); do
5554                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
5555                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
5556         done
5557         sync
5558         $LCTL get_param $proc_osc0/rpc_stats
5559
5560         local percent=0
5561         local have_ppr=false
5562         $LCTL get_param $proc_osc0/rpc_stats |
5563                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
5564                         # skip lines until we are at the RPC histogram data
5565                         [ "$PPR" == "pages" ] && have_ppr=true && continue
5566                         $have_ppr || continue
5567
5568                         # we only want the percent stat for < 16 pages
5569                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
5570
5571                         percent=$((percent + WPCT))
5572                         if [[ $percent -gt 15 ]]; then
5573                                 error "less than 16-pages write RPCs" \
5574                                       "$percent% > 15%"
5575                                 break
5576                         fi
5577                 done
5578         rm -rf $TDIR
5579 }
5580 run_test 42e "verify sub-RPC writes are not done synchronously"
5581
5582 test_43A() { # was test_43
5583         test_mkdir $DIR/$tdir
5584         cp -p /bin/ls $DIR/$tdir/$tfile
5585         $MULTIOP $DIR/$tdir/$tfile Ow_c &
5586         pid=$!
5587         # give multiop a chance to open
5588         sleep 1
5589
5590         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
5591         kill -USR1 $pid
5592         # Wait for multiop to exit
5593         wait $pid
5594 }
5595 run_test 43A "execution of file opened for write should return -ETXTBSY"
5596
5597 test_43a() {
5598         test_mkdir $DIR/$tdir
5599         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5600         $DIR/$tdir/sleep 60 &
5601         SLEEP_PID=$!
5602         # Make sure exec of $tdir/sleep wins race with truncate
5603         sleep 1
5604         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
5605         kill $SLEEP_PID
5606 }
5607 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
5608
5609 test_43b() {
5610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5611
5612         test_mkdir $DIR/$tdir
5613         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
5614         $DIR/$tdir/sleep 60 &
5615         SLEEP_PID=$!
5616         # Make sure exec of $tdir/sleep wins race with truncate
5617         sleep 1
5618         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
5619         kill $SLEEP_PID
5620 }
5621 run_test 43b "truncate of file being executed should return -ETXTBSY"
5622
5623 test_43c() {
5624         local testdir="$DIR/$tdir"
5625         test_mkdir $testdir
5626         cp $SHELL $testdir/
5627         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
5628                 ( cd $testdir && md5sum -c )
5629 }
5630 run_test 43c "md5sum of copy into lustre"
5631
5632 test_44A() { # was test_44
5633         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5634
5635         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
5636         dd if=$DIR/f1 bs=4k count=1 > /dev/null
5637 }
5638 run_test 44A "zero length read from a sparse stripe"
5639
5640 test_44a() {
5641         local nstripe=$($LFS getstripe -c -d $DIR)
5642         [ -z "$nstripe" ] && skip "can't get stripe info"
5643         [[ $nstripe -gt $OSTCOUNT ]] &&
5644                 skip "Wrong default stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
5645
5646         local stride=$($LFS getstripe -S -d $DIR)
5647         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
5648                 nstripe=$($LFS df $DIR | grep OST: | wc -l)
5649         fi
5650
5651         OFFSETS="0 $((stride/2)) $((stride-1))"
5652         for offset in $OFFSETS; do
5653                 for i in $(seq 0 $((nstripe-1))); do
5654                         local GLOBALOFFSETS=""
5655                         # size in Bytes
5656                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
5657                         local myfn=$DIR/d44a-$size
5658                         echo "--------writing $myfn at $size"
5659                         ll_sparseness_write $myfn $size ||
5660                                 error "ll_sparseness_write"
5661                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
5662                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5663                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5664
5665                         for j in $(seq 0 $((nstripe-1))); do
5666                                 # size in Bytes
5667                                 size=$((((j + $nstripe )*$stride + $offset)))
5668                                 ll_sparseness_write $myfn $size ||
5669                                         error "ll_sparseness_write"
5670                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
5671                         done
5672                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
5673                                 error "ll_sparseness_verify $GLOBALOFFSETS"
5674                         rm -f $myfn
5675                 done
5676         done
5677 }
5678 run_test 44a "test sparse pwrite ==============================="
5679
5680 dirty_osc_total() {
5681         tot=0
5682         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
5683                 tot=$(($tot + $d))
5684         done
5685         echo $tot
5686 }
5687 do_dirty_record() {
5688         before=`dirty_osc_total`
5689         echo executing "\"$*\""
5690         eval $*
5691         after=`dirty_osc_total`
5692         echo before $before, after $after
5693 }
5694 test_45() {
5695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5696
5697         f="$DIR/f45"
5698         # Obtain grants from OST if it supports it
5699         echo blah > ${f}_grant
5700         stop_writeback
5701         sync
5702         do_dirty_record "echo blah > $f"
5703         [[ $before -eq $after ]] && error "write wasn't cached"
5704         do_dirty_record "> $f"
5705         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
5706         do_dirty_record "echo blah > $f"
5707         [[ $before -eq $after ]] && error "write wasn't cached"
5708         do_dirty_record "sync"
5709         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
5710         do_dirty_record "echo blah > $f"
5711         [[ $before -eq $after ]] && error "write wasn't cached"
5712         do_dirty_record "cancel_lru_locks osc"
5713         [[ $before -gt $after ]] ||
5714                 error "lock cancellation didn't lower dirty count"
5715         start_writeback
5716 }
5717 run_test 45 "osc io page accounting ============================"
5718
5719 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
5720 # test tickles a bug where re-dirtying a page was failing to be mapped to the
5721 # objects offset and an assert hit when an rpc was built with 1023's mapped
5722 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
5723 test_46() {
5724         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5725
5726         f="$DIR/f46"
5727         stop_writeback
5728         sync
5729         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5730         sync
5731         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
5732         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
5733         sync
5734         start_writeback
5735 }
5736 run_test 46 "dirtying a previously written page ================"
5737
5738 # test_47 is removed "Device nodes check" is moved to test_28
5739
5740 test_48a() { # bug 2399
5741         [ "$mds1_FSTYPE" = "zfs" ] &&
5742         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
5743                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
5744
5745         test_mkdir $DIR/$tdir
5746         cd $DIR/$tdir
5747         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
5748         test_mkdir $DIR/$tdir
5749         touch foo || error "'touch foo' failed after recreating cwd"
5750         test_mkdir bar
5751         touch .foo || error "'touch .foo' failed after recreating cwd"
5752         test_mkdir .bar
5753         ls . > /dev/null || error "'ls .' failed after recreating cwd"
5754         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5755         cd . || error "'cd .' failed after recreating cwd"
5756         mkdir . && error "'mkdir .' worked after recreating cwd"
5757         rmdir . && error "'rmdir .' worked after recreating cwd"
5758         ln -s . baz || error "'ln -s .' failed after recreating cwd"
5759         cd .. || error "'cd ..' failed after recreating cwd"
5760 }
5761 run_test 48a "Access renamed working dir (should return errors)="
5762
5763 test_48b() { # bug 2399
5764         rm -rf $DIR/$tdir
5765         test_mkdir $DIR/$tdir
5766         cd $DIR/$tdir
5767         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
5768         touch foo && error "'touch foo' worked after removing cwd"
5769         mkdir foo && error "'mkdir foo' worked after removing cwd"
5770         touch .foo && error "'touch .foo' worked after removing cwd"
5771         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
5772         ls . > /dev/null && error "'ls .' worked after removing cwd"
5773         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
5774         mkdir . && error "'mkdir .' worked after removing cwd"
5775         rmdir . && error "'rmdir .' worked after removing cwd"
5776         ln -s . foo && error "'ln -s .' worked after removing cwd"
5777         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
5778 }
5779 run_test 48b "Access removed working dir (should return errors)="
5780
5781 test_48c() { # bug 2350
5782         #lctl set_param debug=-1
5783         #set -vx
5784         rm -rf $DIR/$tdir
5785         test_mkdir -p $DIR/$tdir/dir
5786         cd $DIR/$tdir/dir
5787         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5788         $TRACE touch foo && error "touch foo worked after removing cwd"
5789         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
5790         touch .foo && error "touch .foo worked after removing cwd"
5791         mkdir .foo && error "mkdir .foo worked after removing cwd"
5792         $TRACE ls . && error "'ls .' worked after removing cwd"
5793         $TRACE ls .. || error "'ls ..' failed after removing cwd"
5794         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
5795         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
5796         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
5797         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
5798 }
5799 run_test 48c "Access removed working subdir (should return errors)"
5800
5801 test_48d() { # bug 2350
5802         #lctl set_param debug=-1
5803         #set -vx
5804         rm -rf $DIR/$tdir
5805         test_mkdir -p $DIR/$tdir/dir
5806         cd $DIR/$tdir/dir
5807         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5808         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5809         $TRACE touch foo && error "'touch foo' worked after removing parent"
5810         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
5811         touch .foo && error "'touch .foo' worked after removing parent"
5812         mkdir .foo && error "mkdir .foo worked after removing parent"
5813         $TRACE ls . && error "'ls .' worked after removing parent"
5814         $TRACE ls .. && error "'ls ..' worked after removing parent"
5815         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
5816         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
5817         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
5818         true
5819 }
5820 run_test 48d "Access removed parent subdir (should return errors)"
5821
5822 test_48e() { # bug 4134
5823         #lctl set_param debug=-1
5824         #set -vx
5825         rm -rf $DIR/$tdir
5826         test_mkdir -p $DIR/$tdir/dir
5827         cd $DIR/$tdir/dir
5828         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
5829         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
5830         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
5831         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
5832         # On a buggy kernel addition of "touch foo" after cd .. will
5833         # produce kernel oops in lookup_hash_it
5834         touch ../foo && error "'cd ..' worked after recreate parent"
5835         cd $DIR
5836         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
5837 }
5838 run_test 48e "Access to recreated parent subdir (should return errors)"
5839
5840 test_48f() {
5841         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
5842                 skip "need MDS >= 2.13.55"
5843         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
5844         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] ||
5845                 skip "needs different host for mdt1 mdt2"
5846         [[ $(facet_fstype mds1) == ldiskfs ]] || skip "ldiskfs only"
5847
5848         $LFS mkdir -i0 $DIR/$tdir
5849         $LFS mkdir -i 1 $DIR/$tdir/sub1 $DIR/$tdir/sub2 $DIR/$tdir/sub3
5850
5851         for d in sub1 sub2 sub3; do
5852                 #define OBD_FAIL_OSD_REF_DEL    0x19c
5853                 do_facet mds1 $LCTL set_param fail_loc=0x8000019c
5854                 rm -rf $DIR/$tdir/$d && error "rm $d should fail"
5855         done
5856
5857         rm -d --interactive=never $DIR/$tdir || error "rm $tdir fail"
5858 }
5859 run_test 48f "non-zero nlink dir unlink won't LBUG()"
5860
5861 test_49() { # LU-1030
5862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5863         remote_ost_nodsh && skip "remote OST with nodsh"
5864
5865         # get ost1 size - $FSNAME-OST0000
5866         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
5867                 awk '{ print $4 }')
5868         # write 800M at maximum
5869         [[ $ost1_size -lt 2 ]] && ost1_size=2
5870         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
5871
5872         $LFS setstripe -c 1 -i 0 $DIR/$tfile
5873         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
5874         local dd_pid=$!
5875
5876         # change max_pages_per_rpc while writing the file
5877         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
5878         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
5879         # loop until dd process exits
5880         while ps ax -opid | grep -wq $dd_pid; do
5881                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
5882                 sleep $((RANDOM % 5 + 1))
5883         done
5884         # restore original max_pages_per_rpc
5885         $LCTL set_param $osc1_mppc=$orig_mppc
5886         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5887 }
5888 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5889
5890 test_50() {
5891         # bug 1485
5892         test_mkdir $DIR/$tdir
5893         cd $DIR/$tdir
5894         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5895 }
5896 run_test 50 "special situations: /proc symlinks  ==============="
5897
5898 test_51a() {    # was test_51
5899         # bug 1516 - create an empty entry right after ".." then split dir
5900         test_mkdir -c1 $DIR/$tdir
5901         touch $DIR/$tdir/foo
5902         $MCREATE $DIR/$tdir/bar
5903         rm $DIR/$tdir/foo
5904         createmany -m $DIR/$tdir/longfile 201
5905         FNUM=202
5906         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5907                 $MCREATE $DIR/$tdir/longfile$FNUM
5908                 FNUM=$(($FNUM + 1))
5909                 echo -n "+"
5910         done
5911         echo
5912         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5913 }
5914 run_test 51a "special situations: split htree with empty entry =="
5915
5916 cleanup_print_lfs_df () {
5917         trap 0
5918         $LFS df
5919         $LFS df -i
5920 }
5921
5922 test_51b() {
5923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5924
5925         local dir=$DIR/$tdir
5926         local nrdirs=$((65536 + 100))
5927
5928         # cleanup the directory
5929         rm -fr $dir
5930
5931         mkdir_on_mdt -i $((RANDOM % MDSCOUNT)) $dir
5932
5933         $LFS df
5934         $LFS df -i
5935         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5936         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5937         [[ $numfree -lt $nrdirs ]] &&
5938                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5939
5940         # need to check free space for the directories as well
5941         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5942         numfree=$(( blkfree / $(fs_inode_ksize) ))
5943         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5944
5945         trap cleanup_print_lfs_df EXIT
5946
5947         # create files
5948         createmany -d $dir/d $nrdirs || {
5949                 unlinkmany $dir/d $nrdirs
5950                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5951         }
5952
5953         # really created :
5954         nrdirs=$(ls -U $dir | wc -l)
5955
5956         # unlink all but 100 subdirectories, then check it still works
5957         local left=100
5958         local delete=$((nrdirs - left))
5959
5960         $LFS df
5961         $LFS df -i
5962
5963         # for ldiskfs the nlink count should be 1, but this is OSD specific
5964         # and so this is listed for informational purposes only
5965         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5966         unlinkmany -d $dir/d $delete ||
5967                 error "unlink of first $delete subdirs failed"
5968
5969         echo "nlink between: $(stat -c %h $dir)"
5970         local found=$(ls -U $dir | wc -l)
5971         [ $found -ne $left ] &&
5972                 error "can't find subdirs: found only $found, expected $left"
5973
5974         unlinkmany -d $dir/d $delete $left ||
5975                 error "unlink of second $left subdirs failed"
5976         # regardless of whether the backing filesystem tracks nlink accurately
5977         # or not, the nlink count shouldn't be more than "." and ".." here
5978         local after=$(stat -c %h $dir)
5979         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5980                 echo "nlink after: $after"
5981
5982         cleanup_print_lfs_df
5983 }
5984 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5985
5986 test_51d_sub() {
5987         local stripecount=$1
5988         local nfiles=$2
5989
5990         log "create files with stripecount=$stripecount"
5991         $LFS setstripe -C $stripecount $DIR/$tdir
5992         createmany -o $DIR/$tdir/t- $nfiles
5993         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5994         for ((n = 0; n < $OSTCOUNT; n++)); do
5995                 objs[$n]=$(awk -vobjs=0 '($1 == '$n') { objs += 1 } \
5996                            END { printf("%0.0f", objs) }' $TMP/$tfile)
5997                 objs0[$n]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5998                             '($1 == '$n') { objs += 1 } \
5999                             END { printf("%0.0f", objs) }')
6000                 log "OST$n has ${objs[$n]} objects, ${objs0[$n]} are index 0"
6001         done
6002         unlinkmany $DIR/$tdir/t- $nfiles
6003         rm  -f $TMP/$tfile
6004
6005         local nlast
6006         local min=4
6007         local max=6 # allow variance of (1 - $min/$max) = 33% by default
6008
6009         # For some combinations of stripecount and OSTCOUNT current code
6010         # is not ideal, and allocates 50% fewer *first* objects to some OSTs
6011         # than others. Rather than skipping this test entirely, check that
6012         # and keep testing to ensure imbalance does not get worse. LU-15282
6013         (( (OSTCOUNT == 6 && stripecount == 4) ||
6014            (OSTCOUNT == 10 && (stripecount == 4 || stripecount == 8)) ||
6015            (OSTCOUNT == 12 && (stripecount == 8 || stripecount == 9)))) && max=9
6016         for ((nlast=0, n = 1; n < $OSTCOUNT; nlast=n,n++)); do
6017                 (( ${objs[$n]} > ${objs[$nlast]} * 4 / 5 )) ||
6018                         { $LFS df && $LFS df -i &&
6019                         error "stripecount=$stripecount: " \
6020                               "OST $n has fewer objects vs. OST $nlast " \
6021                               "(${objs[$n]} < ${objs[$nlast]} x 4/5)"; }
6022                 (( ${objs[$n]} < ${objs[$nlast]} * 5 / 4 )) ||
6023                         { $LFS df && $LFS df -i &&
6024                         error "stripecount=$stripecount: " \
6025                               "OST $n has more objects vs. OST $nlast " \
6026                               "(${objs[$n]} > ${objs[$nlast]} x 5/4)"; }
6027
6028                 (( ${objs0[$n]} > ${objs0[$nlast]} * $min / $max )) ||
6029                         { $LFS df && $LFS df -i &&
6030                         error "stripecount=$stripecount: " \
6031                               "OST $n has fewer #0 objects vs. OST $nlast " \
6032                               "(${objs0[$n]} < ${objs0[$nlast]} x $min/$max)"; }
6033                 (( ${objs0[$n]} < ${objs0[$nlast]} * $max / $min )) ||
6034                         { $LFS df && $LFS df -i &&
6035                         error "stripecount=$stripecount: " \
6036                               "OST $n has more #0 objects vs. OST $nlast " \
6037                               "(${objs0[$n]} > ${objs0[$nlast]} x $max/$min)"; }
6038         done
6039 }
6040
6041 test_51d() {
6042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6043         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
6044
6045         local stripecount
6046         local per_ost=100
6047         local nfiles=$((per_ost * OSTCOUNT))
6048         local mdts=$(comma_list $(mdts_nodes))
6049         local param="osp.*.create_count"
6050         local qos_old=$(do_facet mds1 \
6051                 "$LCTL get_param -n lod.$FSNAME-*.qos_threshold_rr" | head -n 1)
6052
6053         do_nodes $mdts \
6054                 "$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=100"
6055         stack_trap "do_nodes $mdts \
6056                 '$LCTL set_param lod.$FSNAME-*.qos_threshold_rr=${qos_old%%%}'"
6057
6058         test_mkdir $DIR/$tdir
6059         local dirstripes=$(lfs getdirstripe -c $DIR/$tdir)
6060         (( dirstripes > 0 )) || dirstripes=1
6061
6062         # Ensure enough OST objects precreated for tests to pass without
6063         # running out of objects.  This is an LOV r-r OST algorithm test,
6064         # not an OST object precreation test.
6065         local old=$(do_facet mds1 "$LCTL get_param -n $param" | head -n 1)
6066         (( old >= nfiles )) ||
6067         {
6068                 local create_count=$((nfiles * OSTCOUNT / dirstripes))
6069
6070                 do_nodes $mdts "$LCTL set_param $param=$create_count"
6071                 stack_trap "do_nodes $mdts $LCTL set_param $param=$old"
6072
6073                 # trigger precreation from all MDTs for all OSTs
6074                 for ((i = 0; i < $MDSCOUNT * 2; i++ )); do
6075                         $LFS setstripe -c -1 $DIR/$tdir/wide.$i
6076                 done
6077         }
6078
6079         for ((stripecount = 3; stripecount <= $OSTCOUNT; stripecount++)); do
6080                 sleep 8  # allow object precreation to catch up
6081                 test_51d_sub $stripecount $nfiles
6082         done
6083 }
6084 run_test 51d "check LOV round-robin OST object distribution"
6085
6086 test_51e() {
6087         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6088                 skip_env "ldiskfs only test"
6089         fi
6090
6091         test_mkdir -c1 $DIR/$tdir
6092         test_mkdir -c1 $DIR/$tdir/d0
6093
6094         touch $DIR/$tdir/d0/foo
6095         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
6096                 error "file exceed 65000 nlink limit!"
6097         unlinkmany $DIR/$tdir/d0/f- 65001
6098         return 0
6099 }
6100 run_test 51e "check file nlink limit"
6101
6102 test_51f() {
6103         test_mkdir $DIR/$tdir
6104
6105         local max=100000
6106         local ulimit_old=$(ulimit -n)
6107         local spare=20 # number of spare fd's for scripts/libraries, etc.
6108         local mdt=$($LFS getstripe -m $DIR/$tdir)
6109         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
6110
6111         echo "MDT$mdt numfree=$numfree, max=$max"
6112         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
6113         if [ $((numfree + spare)) -gt $ulimit_old ]; then
6114                 while ! ulimit -n $((numfree + spare)); do
6115                         numfree=$((numfree * 3 / 4))
6116                 done
6117                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
6118         else
6119                 echo "left ulimit at $ulimit_old"
6120         fi
6121
6122         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
6123                 unlinkmany $DIR/$tdir/f $numfree
6124                 error "create+open $numfree files in $DIR/$tdir failed"
6125         }
6126         ulimit -n $ulimit_old
6127
6128         # if createmany exits at 120s there will be fewer than $numfree files
6129         unlinkmany $DIR/$tdir/f $numfree || true
6130 }
6131 run_test 51f "check many open files limit"
6132
6133 test_52a() {
6134         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
6135         test_mkdir $DIR/$tdir
6136         touch $DIR/$tdir/foo
6137         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
6138         echo bar >> $DIR/$tdir/foo || error "append bar failed"
6139         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6140         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6141         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6142                                         error "link worked"
6143         echo foo >> $DIR/$tdir/foo || error "append foo failed"
6144         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6145         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
6146                                                      error "lsattr"
6147         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
6148         cp -r $DIR/$tdir $TMP/
6149         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
6150 }
6151 run_test 52a "append-only flag test (should return errors)"
6152
6153 test_52b() {
6154         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
6155         test_mkdir $DIR/$tdir
6156         touch $DIR/$tdir/foo
6157         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
6158         cat test > $DIR/$tdir/foo && error "cat test worked"
6159         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
6160         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
6161         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
6162                                         error "link worked"
6163         echo foo >> $DIR/$tdir/foo && error "echo worked"
6164         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
6165         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
6166         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
6167         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
6168                                                         error "lsattr"
6169         chattr -i $DIR/$tdir/foo || error "chattr failed"
6170
6171         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
6172 }
6173 run_test 52b "immutable flag test (should return errors) ======="
6174
6175 test_53() {
6176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6177         remote_mds_nodsh && skip "remote MDS with nodsh"
6178         remote_ost_nodsh && skip "remote OST with nodsh"
6179
6180         local param
6181         local param_seq
6182         local ostname
6183         local mds_last
6184         local mds_last_seq
6185         local ost_last
6186         local ost_last_seq
6187         local ost_last_id
6188         local ostnum
6189         local node
6190         local found=false
6191         local support_last_seq=true
6192
6193         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
6194                 support_last_seq=false
6195
6196         # only test MDT0000
6197         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
6198         local value
6199         for value in $(do_facet $SINGLEMDS \
6200                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
6201                 param=$(echo ${value[0]} | cut -d "=" -f1)
6202                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
6203
6204                 if $support_last_seq; then
6205                         param_seq=$(echo $param |
6206                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
6207                         mds_last_seq=$(do_facet $SINGLEMDS \
6208                                        $LCTL get_param -n $param_seq)
6209                 fi
6210                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
6211
6212                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
6213                 node=$(facet_active_host ost$((ostnum+1)))
6214                 param="obdfilter.$ostname.last_id"
6215                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
6216                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
6217                         ost_last_id=$ost_last
6218
6219                         if $support_last_seq; then
6220                                 ost_last_id=$(echo $ost_last |
6221                                               awk -F':' '{print $2}' |
6222                                               sed -e "s/^0x//g")
6223                                 ost_last_seq=$(echo $ost_last |
6224                                                awk -F':' '{print $1}')
6225                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
6226                         fi
6227
6228                         if [[ $ost_last_id != $mds_last ]]; then
6229                                 error "$ost_last_id != $mds_last"
6230                         else
6231                                 found=true
6232                                 break
6233                         fi
6234                 done
6235         done
6236         $found || error "can not match last_seq/last_id for $mdtosc"
6237         return 0
6238 }
6239 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
6240
6241 test_54a() {
6242         perl -MSocket -e ';' || skip "no Socket perl module installed"
6243
6244         $SOCKETSERVER $DIR/socket ||
6245                 error "$SOCKETSERVER $DIR/socket failed: $?"
6246         $SOCKETCLIENT $DIR/socket ||
6247                 error "$SOCKETCLIENT $DIR/socket failed: $?"
6248         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
6249 }
6250 run_test 54a "unix domain socket test =========================="
6251
6252 test_54b() {
6253         f="$DIR/f54b"
6254         mknod $f c 1 3
6255         chmod 0666 $f
6256         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
6257 }
6258 run_test 54b "char device works in lustre ======================"
6259
6260 find_loop_dev() {
6261         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
6262         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
6263         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
6264
6265         for i in $(seq 3 7); do
6266                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
6267                 LOOPDEV=$LOOPBASE$i
6268                 LOOPNUM=$i
6269                 break
6270         done
6271 }
6272
6273 cleanup_54c() {
6274         local rc=0
6275         loopdev="$DIR/loop54c"
6276
6277         trap 0
6278         $UMOUNT $DIR/$tdir || rc=$?
6279         losetup -d $loopdev || true
6280         losetup -d $LOOPDEV || true
6281         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
6282         return $rc
6283 }
6284
6285 test_54c() {
6286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6287
6288         loopdev="$DIR/loop54c"
6289
6290         find_loop_dev
6291         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
6292         trap cleanup_54c EXIT
6293         mknod $loopdev b 7 $LOOPNUM
6294         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
6295         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
6296         losetup $loopdev $DIR/$tfile ||
6297                 error "can't set up $loopdev for $DIR/$tfile"
6298         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
6299         test_mkdir $DIR/$tdir
6300         mount -t ext2 $loopdev $DIR/$tdir ||
6301                 error "error mounting $loopdev on $DIR/$tdir"
6302         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
6303                 error "dd write"
6304         df $DIR/$tdir
6305         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
6306                 error "dd read"
6307         cleanup_54c
6308 }
6309 run_test 54c "block device works in lustre ====================="
6310
6311 test_54d() {
6312         local pipe="$DIR/$tfile.pipe"
6313         local string="aaaaaa"
6314
6315         mknod $pipe p
6316         echo -n "$string" > $pipe &
6317         local result=$(cat $pipe)
6318         [[ "$result" == "$string" ]] || error "$result != $string"
6319 }
6320 run_test 54d "fifo device works in lustre ======================"
6321
6322 test_54e() {
6323         f="$DIR/f54e"
6324         string="aaaaaa"
6325         cp -aL /dev/console $f
6326         echo $string > $f || error "echo $string to $f failed"
6327 }
6328 run_test 54e "console/tty device works in lustre ======================"
6329
6330 test_56a() {
6331         local numfiles=3
6332         local numdirs=2
6333         local dir=$DIR/$tdir
6334
6335         rm -rf $dir
6336         test_mkdir -p $dir/dir
6337         for i in $(seq $numfiles); do
6338                 touch $dir/file$i
6339                 touch $dir/dir/file$i
6340         done
6341
6342         local numcomp=$($LFS getstripe --component-count $dir)
6343
6344         [[ $numcomp == 0 ]] && numcomp=1
6345
6346         # test lfs getstripe with --recursive
6347         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
6348
6349         [[ $filenum -eq $((numfiles * 2)) ]] ||
6350                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
6351         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
6352         [[ $filenum -eq $numfiles ]] ||
6353                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
6354         echo "$LFS getstripe showed obdidx or l_ost_idx"
6355
6356         # test lfs getstripe with file instead of dir
6357         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
6358         [[ $filenum -eq 1 ]] ||
6359                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
6360         echo "$LFS getstripe file1 passed"
6361
6362         #test lfs getstripe with --verbose
6363         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
6364         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
6365                 error "$LFS getstripe --verbose $dir: "\
6366                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
6367         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
6368                 error "$LFS getstripe $dir: showed lmm_magic"
6369
6370         #test lfs getstripe with -v prints lmm_fid
6371         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
6372         local countfids=$((numdirs + numfiles * numcomp))
6373         [[ $filenum -eq $countfids ]] ||
6374                 error "$LFS getstripe -v $dir: "\
6375                       "got $filenum want $countfids lmm_fid"
6376         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
6377                 error "$LFS getstripe $dir: showed lmm_fid by default"
6378         echo "$LFS getstripe --verbose passed"
6379
6380         #check for FID information
6381         local fid1=$($LFS getstripe --fid $dir/file1)
6382         local fid2=$($LFS getstripe --verbose $dir/file1 |
6383                      awk '/lmm_fid: / { print $2; exit; }')
6384         local fid3=$($LFS path2fid $dir/file1)
6385
6386         [ "$fid1" != "$fid2" ] &&
6387                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
6388         [ "$fid1" != "$fid3" ] &&
6389                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
6390         echo "$LFS getstripe --fid passed"
6391
6392         #test lfs getstripe with --obd
6393         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
6394                 error "$LFS getstripe --obd wrong_uuid: should return error"
6395
6396         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6397
6398         local ostidx=1
6399         local obduuid=$(ostuuid_from_index $ostidx)
6400         local found=$($LFS getstripe -r --obd $obduuid $dir |
6401                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
6402
6403         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
6404         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
6405                 ((filenum--))
6406         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
6407                 ((filenum--))
6408
6409         [[ $found -eq $filenum ]] ||
6410                 error "$LFS getstripe --obd: found $found expect $filenum"
6411         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
6412                 sed '/^[         ]*'${ostidx}'[  ]/d' |
6413                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
6414                 error "$LFS getstripe --obd: should not show file on other obd"
6415         echo "$LFS getstripe --obd passed"
6416 }
6417 run_test 56a "check $LFS getstripe"
6418
6419 test_56b() {
6420         local dir=$DIR/$tdir
6421         local numdirs=3
6422
6423         test_mkdir $dir
6424         for i in $(seq $numdirs); do
6425                 test_mkdir $dir/dir$i
6426         done
6427
6428         # test lfs getdirstripe default mode is non-recursion, which is
6429         # different from lfs getstripe
6430         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
6431
6432         [[ $dircnt -eq 1 ]] ||
6433                 error "$LFS getdirstripe: found $dircnt, not 1"
6434         dircnt=$($LFS getdirstripe --recursive $dir |
6435                 grep -c lmv_stripe_count)
6436         [[ $dircnt -eq $((numdirs + 1)) ]] ||
6437                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
6438 }
6439 run_test 56b "check $LFS getdirstripe"
6440
6441 test_56bb() {
6442         verify_yaml_available || skip_env "YAML verification not installed"
6443         local output_file=$DIR/$tfile.out
6444
6445         $LFS getdirstripe -v -D -y $DIR 1> $output_file
6446
6447         cat $output_file
6448         cat $output_file | verify_yaml || error "layout is not valid YAML"
6449 }
6450 run_test 56bb "check $LFS getdirstripe layout is YAML"
6451
6452 test_56c() {
6453         remote_ost_nodsh && skip "remote OST with nodsh"
6454
6455         local ost_idx=0
6456         local ost_name=$(ostname_from_index $ost_idx)
6457         local old_status=$(ost_dev_status $ost_idx)
6458         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
6459
6460         [[ -z "$old_status" ]] ||
6461                 skip_env "OST $ost_name is in $old_status status"
6462
6463         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
6464         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6465                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=1
6466         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6467                 save_lustre_params ost1 osd-*.$ost_name.nonrotational > $p
6468                 do_facet ost1 $LCTL set_param -n osd-*.$ost_name.nonrotational=1
6469         fi
6470
6471         [[ $($LFS df -v $MOUNT |& grep -c "inactive device") -eq 0 ]] ||
6472                 error "$LFS df -v showing inactive devices"
6473         sleep_maxage
6474
6475         local new_status=$(ost_dev_status $ost_idx $MOUNT -v)
6476
6477         [[ "$new_status" =~ "D" ]] ||
6478                 error "$ost_name status is '$new_status', missing 'D'"
6479         if [[ $OST1_VERSION -ge $(version_code 2.12.55) ]]; then
6480                 [[ "$new_status" =~ "N" ]] ||
6481                         error "$ost_name status is '$new_status', missing 'N'"
6482         fi
6483         if [[ $OST1_VERSION -ge $(version_code 2.12.57) ]]; then
6484                 [[ "$new_status" =~ "f" ]] ||
6485                         error "$ost_name status is '$new_status', missing 'f'"
6486         fi
6487
6488         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
6489         [[ $OST1_VERSION -lt $(version_code 2.12.55) ]] || do_facet ost1 \
6490                 $LCTL set_param -n obdfilter.$ost_name.no_precreate=0
6491         [[ -z "$p" ]] && restore_lustre_params < $p || true
6492         sleep_maxage
6493
6494         new_status=$(ost_dev_status $ost_idx)
6495         [[ ! "$new_status" =~ "D" && ! "$new_status" =~ "N" ]] ||
6496                 error "$ost_name status is '$new_status', has 'D' and/or 'N'"
6497         # can't check 'f' as devices may actually be on flash
6498 }
6499 run_test 56c "check 'lfs df' showing device status"
6500
6501 test_56d() {
6502         local mdts=$($LFS df -v $MOUNT | grep -c MDT)
6503         local osts=$($LFS df -v $MOUNT | grep -c OST)
6504
6505         $LFS df $MOUNT
6506
6507         (( mdts == MDSCOUNT )) ||
6508                 error "lfs df -v showed $mdts MDTs, not $MDSCOUNT"
6509         (( osts == OSTCOUNT )) ||
6510                 error "lfs df -v showed $osts OSTs, not $OSTCOUNT"
6511 }
6512 run_test 56d "'lfs df -v' prints only configured devices"
6513
6514 test_56e() {
6515         err_enoent=2 # No such file or directory
6516         err_eopnotsupp=95 # Operation not supported
6517
6518         enoent_mnt=/pmt1 # Invalid dentry. Path not present
6519         notsup_mnt=/tmp  # Valid dentry, but Not a lustreFS
6520
6521         # Check for handling of path not exists
6522         output=$($LFS df $enoent_mnt 2>&1)
6523         ret=$?
6524
6525         fs=$(echo $output | awk -F: '{print $2}' | awk '{print $3}' | tr -d \')
6526         [[ $fs = $enoent_mnt && $ret -eq $err_enoent ]] ||
6527                 error "expect failure $err_enoent, not $ret"
6528
6529         # Check for handling of non-Lustre FS
6530         output=$($LFS df $notsup_mnt)
6531         ret=$?
6532
6533         fs=$(echo $output | awk '{print $1}' | awk -F: '{print $2}')
6534         [[ $fs = $notsup_mnt && $ret -eq $err_eopnotsupp ]] ||
6535                 error "expect success $err_eopnotsupp, not $ret"
6536
6537         # Check for multiple LustreFS argument
6538         output=$($LFS df $MOUNT $MOUNT $MOUNT | grep -c "filesystem_summary:")
6539         ret=$?
6540
6541         [[ $output -eq 3 && $ret -eq 0 ]] ||
6542                 error "expect success 3, not $output, rc = $ret"
6543
6544         # Check for correct non-Lustre FS handling among multiple
6545         # LustreFS argument
6546         output=$($LFS df $MOUNT $notsup_mnt $MOUNT |
6547                 grep -c "filesystem_summary:"; exit ${PIPESTATUS[0]})
6548         ret=$?
6549
6550         [[ $output -eq 2 && $ret -eq $err_eopnotsupp ]] ||
6551                 error "expect success 2, not $output, rc = $ret"
6552 }
6553 run_test 56e "'lfs df' Handle non LustreFS & multiple LustreFS"
6554
6555 NUMFILES=3
6556 NUMDIRS=3
6557 setup_56() {
6558         local local_tdir="$1"
6559         local local_numfiles="$2"
6560         local local_numdirs="$3"
6561         local dir_params="$4"
6562         local dir_stripe_params="$5"
6563
6564         if [ ! -d "$local_tdir" ] ; then
6565                 test_mkdir -p $dir_stripe_params $local_tdir
6566                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
6567                 for i in $(seq $local_numfiles) ; do
6568                         touch $local_tdir/file$i
6569                 done
6570                 for i in $(seq $local_numdirs) ; do
6571                         test_mkdir $dir_stripe_params $local_tdir/dir$i
6572                         for j in $(seq $local_numfiles) ; do
6573                                 touch $local_tdir/dir$i/file$j
6574                         done
6575                 done
6576         fi
6577 }
6578
6579 setup_56_special() {
6580         local local_tdir=$1
6581         local local_numfiles=$2
6582         local local_numdirs=$3
6583
6584         setup_56 $local_tdir $local_numfiles $local_numdirs
6585
6586         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
6587                 for i in $(seq $local_numfiles) ; do
6588                         mknod $local_tdir/loop${i}b b 7 $i
6589                         mknod $local_tdir/null${i}c c 1 3
6590                         ln -s $local_tdir/file1 $local_tdir/link${i}
6591                 done
6592                 for i in $(seq $local_numdirs) ; do
6593                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
6594                         mknod $local_tdir/dir$i/null${i}c c 1 3
6595                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
6596                 done
6597         fi
6598 }
6599
6600 test_56g() {
6601         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6602         local expected=$(($NUMDIRS + 2))
6603
6604         setup_56 $dir $NUMFILES $NUMDIRS
6605
6606         # test lfs find with -name
6607         for i in $(seq $NUMFILES) ; do
6608                 local nums=$($LFS find -name "*$i" $dir | wc -l)
6609
6610                 [ $nums -eq $expected ] ||
6611                         error "lfs find -name '*$i' $dir wrong: "\
6612                               "found $nums, expected $expected"
6613         done
6614 }
6615 run_test 56g "check lfs find -name"
6616
6617 test_56h() {
6618         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6619         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
6620
6621         setup_56 $dir $NUMFILES $NUMDIRS
6622
6623         # test lfs find with ! -name
6624         for i in $(seq $NUMFILES) ; do
6625                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
6626
6627                 [ $nums -eq $expected ] ||
6628                         error "lfs find ! -name '*$i' $dir wrong: "\
6629                               "found $nums, expected $expected"
6630         done
6631 }
6632 run_test 56h "check lfs find ! -name"
6633
6634 test_56i() {
6635         local dir=$DIR/$tdir
6636
6637         test_mkdir $dir
6638
6639         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
6640         local out=$($cmd)
6641
6642         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
6643 }
6644 run_test 56i "check 'lfs find -ost UUID' skips directories"
6645
6646 test_56j() {
6647         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6648
6649         setup_56_special $dir $NUMFILES $NUMDIRS
6650
6651         local expected=$((NUMDIRS + 1))
6652         local cmd="$LFS find -type d $dir"
6653         local nums=$($cmd | wc -l)
6654
6655         [ $nums -eq $expected ] ||
6656                 error "'$cmd' wrong: found $nums, expected $expected"
6657 }
6658 run_test 56j "check lfs find -type d"
6659
6660 test_56k() {
6661         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6662
6663         setup_56_special $dir $NUMFILES $NUMDIRS
6664
6665         local expected=$(((NUMDIRS + 1) * NUMFILES))
6666         local cmd="$LFS find -type f $dir"
6667         local nums=$($cmd | wc -l)
6668
6669         [ $nums -eq $expected ] ||
6670                 error "'$cmd' wrong: found $nums, expected $expected"
6671 }
6672 run_test 56k "check lfs find -type f"
6673
6674 test_56l() {
6675         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6676
6677         setup_56_special $dir $NUMFILES $NUMDIRS
6678
6679         local expected=$((NUMDIRS + NUMFILES))
6680         local cmd="$LFS find -type b $dir"
6681         local nums=$($cmd | wc -l)
6682
6683         [ $nums -eq $expected ] ||
6684                 error "'$cmd' wrong: found $nums, expected $expected"
6685 }
6686 run_test 56l "check lfs find -type b"
6687
6688 test_56m() {
6689         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6690
6691         setup_56_special $dir $NUMFILES $NUMDIRS
6692
6693         local expected=$((NUMDIRS + NUMFILES))
6694         local cmd="$LFS find -type c $dir"
6695         local nums=$($cmd | wc -l)
6696         [ $nums -eq $expected ] ||
6697                 error "'$cmd' wrong: found $nums, expected $expected"
6698 }
6699 run_test 56m "check lfs find -type c"
6700
6701 test_56n() {
6702         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
6703         setup_56_special $dir $NUMFILES $NUMDIRS
6704
6705         local expected=$((NUMDIRS + NUMFILES))
6706         local cmd="$LFS find -type l $dir"
6707         local nums=$($cmd | wc -l)
6708
6709         [ $nums -eq $expected ] ||
6710                 error "'$cmd' wrong: found $nums, expected $expected"
6711 }
6712 run_test 56n "check lfs find -type l"
6713
6714 test_56o() {
6715         local dir=$DIR/$tdir
6716
6717         setup_56 $dir $NUMFILES $NUMDIRS
6718         utime $dir/file1 > /dev/null || error "utime (1)"
6719         utime $dir/file2 > /dev/null || error "utime (2)"
6720         utime $dir/dir1 > /dev/null || error "utime (3)"
6721         utime $dir/dir2 > /dev/null || error "utime (4)"
6722         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
6723         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
6724
6725         local expected=4
6726         local nums=$($LFS find -mtime +0 $dir | wc -l)
6727
6728         [ $nums -eq $expected ] ||
6729                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
6730
6731         expected=12
6732         cmd="$LFS find -mtime 0 $dir"
6733         nums=$($cmd | wc -l)
6734         [ $nums -eq $expected ] ||
6735                 error "'$cmd' wrong: found $nums, expected $expected"
6736 }
6737 run_test 56o "check lfs find -mtime for old files"
6738
6739 test_56ob() {
6740         local dir=$DIR/$tdir
6741         local expected=1
6742         local count=0
6743
6744         # just to make sure there is something that won't be found
6745         test_mkdir $dir
6746         touch $dir/$tfile.now
6747
6748         for age in year week day hour min; do
6749                 count=$((count + 1))
6750
6751                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
6752                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
6753                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
6754
6755                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
6756                 local nums=$($cmd | wc -l)
6757                 [ $nums -eq $expected ] ||
6758                         error "'$cmd' wrong: found $nums, expected $expected"
6759
6760                 cmd="$LFS find $dir -atime $count${age:0:1}"
6761                 nums=$($cmd | wc -l)
6762                 [ $nums -eq $expected ] ||
6763                         error "'$cmd' wrong: found $nums, expected $expected"
6764         done
6765
6766         sleep 2
6767         cmd="$LFS find $dir -ctime +1s -type f"
6768         nums=$($cmd | wc -l)
6769         (( $nums == $count * 2 + 1)) ||
6770                 error "'$cmd' wrong: found $nums, expected $((count * 2 + 1))"
6771 }
6772 run_test 56ob "check lfs find -atime -mtime -ctime with units"
6773
6774 test_newerXY_base() {
6775         local x=$1
6776         local y=$2
6777         local dir=$DIR/$tdir
6778         local ref
6779         local negref
6780
6781         if [ $y == "t" ]; then
6782                 if [ $x == "b" ]; then
6783                         ref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6784                 else
6785                         ref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6786                 fi
6787         else
6788                 ref=$DIR/$tfile.newer.$x$y
6789                 touch $ref || error "touch $ref failed"
6790         fi
6791
6792         echo "before = $ref"
6793         sleep 2
6794         setup_56 $dir $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6795         sleep 2
6796         if [ $y == "t" ]; then
6797                 if [ $x == "b" ]; then
6798                         negref=\"$(do_facet mds1 date +"%Y-%m-%d\ %H:%M:%S")\"
6799                 else
6800                         negref=\"$(date +"%Y-%m-%d %H:%M:%S")\"
6801                 fi
6802         else
6803                 negref=$DIR/$tfile.negnewer.$x$y
6804                 touch $negref || error "touch $negref failed"
6805         fi
6806
6807         echo "after = $negref"
6808         local cmd="$LFS find $dir -newer$x$y $ref"
6809         local nums=$(eval $cmd | wc -l)
6810         local expected=$(((NUMFILES + 2) * NUMDIRS + 1))
6811
6812         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6813                 error "'$cmd' wrong: found $nums newer, expected $expected"  ; }
6814
6815         cmd="$LFS find $dir ! -newer$x$y $negref"
6816         nums=$(eval $cmd | wc -l)
6817         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6818                 error "'$cmd' wrong: found $nums older, expected $expected"  ; }
6819
6820         cmd="$LFS find $dir -newer$x$y $ref ! -newer$x$y $negref"
6821         nums=$(eval $cmd | wc -l)
6822         [ $nums -eq $expected ] || { ls -lauR --full-time $dir ;
6823                 error "'$cmd' wrong: found $nums between, expected $expected"; }
6824
6825         rm -rf $DIR/*
6826 }
6827
6828 test_56oc() {
6829         test_newerXY_base "a" "a"
6830         test_newerXY_base "a" "m"
6831         test_newerXY_base "a" "c"
6832         test_newerXY_base "m" "a"
6833         test_newerXY_base "m" "m"
6834         test_newerXY_base "m" "c"
6835         test_newerXY_base "c" "a"
6836         test_newerXY_base "c" "m"
6837         test_newerXY_base "c" "c"
6838
6839         test_newerXY_base "a" "t"
6840         test_newerXY_base "m" "t"
6841         test_newerXY_base "c" "t"
6842
6843         [[ $MDS1_VERSION -lt $(version_code 2.13.54) ||
6844            $CLIENT_VERSION -lt $(version_code 2.13.54) ]] &&
6845                 ! btime_supported && echo "btime unsupported" && return 0
6846
6847         test_newerXY_base "b" "b"
6848         test_newerXY_base "b" "t"
6849 }
6850 run_test 56oc "check lfs find -newerXY work"
6851
6852 btime_supported() {
6853         local dir=$DIR/$tdir
6854         local rc
6855
6856         mkdir -p $dir
6857         touch $dir/$tfile
6858         $LFS find $dir -btime -1d -type f
6859         rc=$?
6860         rm -rf $dir
6861         return $rc
6862 }
6863
6864 test_56od() {
6865         [ $MDS1_VERSION -lt $(version_code 2.13.53) ] &&
6866                 ! btime_supported && skip "btime unsupported on MDS"
6867
6868         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
6869                 ! btime_supported && skip "btime unsupported on clients"
6870
6871         local dir=$DIR/$tdir
6872         local ref=$DIR/$tfile.ref
6873         local negref=$DIR/$tfile.negref
6874
6875         mkdir $dir || error "mkdir $dir failed"
6876         touch $dir/$tfile.n1 || error "touch $dir/$tfile.n1 failed"
6877         touch $dir/$tfile.n2 || error "touch $dir/$tfile.n2 failed"
6878         mkdir $dir/$tdir.n1 || error "mkdir $dir/$tdir.n1 failed"
6879         mkdir $dir/$tdir.n2 || error "mkdir $dir/$tdir.n2 failed"
6880         touch $ref || error "touch $ref failed"
6881         # sleep 3 seconds at least
6882         sleep 3
6883
6884         local before=$(do_facet mds1 date +%s)
6885         local skew=$(($(date +%s) - before + 1))
6886
6887         if (( skew < 0 && skew > -5 )); then
6888                 sleep $((0 - skew + 1))
6889                 skew=0
6890         fi
6891
6892         # Set the dir stripe params to limit files all on MDT0,
6893         # otherwise we need to calc the max clock skew between
6894         # the client and MDTs.
6895         setup_56 $dir/d.btime $NUMFILES $NUMDIRS "-i0 -c1" "-i0 -c1"
6896         sleep 2
6897         touch $negref || error "touch $negref failed"
6898
6899         local cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type f"
6900         local nums=$($cmd | wc -l)
6901         local expected=$(((NUMFILES + 1) * NUMDIRS))
6902
6903         [ $nums -eq $expected ] ||
6904                 error "'$cmd' wrong: found $nums, expected $expected"
6905
6906         cmd="$LFS find $dir -newerbb $ref ! -newerbb $negref -type d"
6907         nums=$($cmd | wc -l)
6908         expected=$((NUMFILES + 1))
6909         [ $nums -eq $expected ] ||
6910                 error "'$cmd' wrong: found $nums, expected $expected"
6911
6912         [ $skew -lt 0 ] && return
6913
6914         local after=$(do_facet mds1 date +%s)
6915         local age=$((after - before + 1 + skew))
6916
6917         cmd="$LFS find $dir -btime -${age}s -type f"
6918         nums=$($cmd | wc -l)
6919         expected=$(((NUMFILES + 1) * NUMDIRS))
6920
6921         echo "Clock skew between client and server: $skew, age:$age"
6922         [ $nums -eq $expected ] ||
6923                 error "'$cmd' wrong: found $nums, expected $expected"
6924
6925         expected=$(($NUMDIRS + 1))
6926         cmd="$LFS find $dir -btime -${age}s -type d"
6927         nums=$($cmd | wc -l)
6928         [ $nums -eq $expected ] ||
6929                 error "'$cmd' wrong: found $nums, expected $expected"
6930         rm -f $ref $negref || error "Failed to remove $ref $negref"
6931 }
6932 run_test 56od "check lfs find -btime with units"
6933
6934 test_56p() {
6935         [ $RUNAS_ID -eq $UID ] &&
6936                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6937
6938         local dir=$DIR/$tdir
6939
6940         setup_56 $dir $NUMFILES $NUMDIRS
6941         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
6942
6943         local expected=$NUMFILES
6944         local cmd="$LFS find -uid $RUNAS_ID $dir"
6945         local nums=$($cmd | wc -l)
6946
6947         [ $nums -eq $expected ] ||
6948                 error "'$cmd' wrong: found $nums, expected $expected"
6949
6950         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
6951         cmd="$LFS find ! -uid $RUNAS_ID $dir"
6952         nums=$($cmd | wc -l)
6953         [ $nums -eq $expected ] ||
6954                 error "'$cmd' wrong: found $nums, expected $expected"
6955 }
6956 run_test 56p "check lfs find -uid and ! -uid"
6957
6958 test_56q() {
6959         [ $RUNAS_ID -eq $UID ] &&
6960                 skip_env "RUNAS_ID = UID = $UID -- skipping"
6961
6962         local dir=$DIR/$tdir
6963
6964         setup_56 $dir $NUMFILES $NUMDIRS
6965         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
6966
6967         local expected=$NUMFILES
6968         local cmd="$LFS find -gid $RUNAS_GID $dir"
6969         local nums=$($cmd | wc -l)
6970
6971         [ $nums -eq $expected ] ||
6972                 error "'$cmd' wrong: found $nums, expected $expected"
6973
6974         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
6975         cmd="$LFS find ! -gid $RUNAS_GID $dir"
6976         nums=$($cmd | wc -l)
6977         [ $nums -eq $expected ] ||
6978                 error "'$cmd' wrong: found $nums, expected $expected"
6979 }
6980 run_test 56q "check lfs find -gid and ! -gid"
6981
6982 test_56r() {
6983         local dir=$DIR/$tdir
6984
6985         setup_56 $dir $NUMFILES $NUMDIRS
6986
6987         local expected=12
6988         local cmd="$LFS find -size 0 -type f -lazy $dir"
6989         local nums=$($cmd | wc -l)
6990
6991         [ $nums -eq $expected ] ||
6992                 error "'$cmd' wrong: found $nums, expected $expected"
6993         cmd="$LFS find -size 0 -type f $dir"
6994         nums=$($cmd | wc -l)
6995         [ $nums -eq $expected ] ||
6996                 error "'$cmd' wrong: found $nums, expected $expected"
6997
6998         expected=0
6999         cmd="$LFS find ! -size 0 -type f -lazy $dir"
7000         nums=$($cmd | wc -l)
7001         [ $nums -eq $expected ] ||
7002                 error "'$cmd' wrong: found $nums, expected $expected"
7003         cmd="$LFS find ! -size 0 -type f $dir"
7004         nums=$($cmd | wc -l)
7005         [ $nums -eq $expected ] ||
7006                 error "'$cmd' wrong: found $nums, expected $expected"
7007
7008         echo "test" > $dir/$tfile
7009         echo "test2" > $dir/$tfile.2 && sync
7010         expected=1
7011         cmd="$LFS find -size 5 -type f -lazy $dir"
7012         nums=$($cmd | wc -l)
7013         [ $nums -eq $expected ] ||
7014                 error "'$cmd' wrong: found $nums, expected $expected"
7015         cmd="$LFS find -size 5 -type f $dir"
7016         nums=$($cmd | wc -l)
7017         [ $nums -eq $expected ] ||
7018                 error "'$cmd' wrong: found $nums, expected $expected"
7019
7020         expected=1
7021         cmd="$LFS find -size +5 -type f -lazy $dir"
7022         nums=$($cmd | wc -l)
7023         [ $nums -eq $expected ] ||
7024                 error "'$cmd' wrong: found $nums, expected $expected"
7025         cmd="$LFS find -size +5 -type f $dir"
7026         nums=$($cmd | wc -l)
7027         [ $nums -eq $expected ] ||
7028                 error "'$cmd' wrong: found $nums, expected $expected"
7029
7030         expected=2
7031         cmd="$LFS find -size +0 -type f -lazy $dir"
7032         nums=$($cmd | wc -l)
7033         [ $nums -eq $expected ] ||
7034                 error "'$cmd' wrong: found $nums, expected $expected"
7035         cmd="$LFS find -size +0 -type f $dir"
7036         nums=$($cmd | wc -l)
7037         [ $nums -eq $expected ] ||
7038                 error "'$cmd' wrong: found $nums, expected $expected"
7039
7040         expected=2
7041         cmd="$LFS find ! -size -5 -type f -lazy $dir"
7042         nums=$($cmd | wc -l)
7043         [ $nums -eq $expected ] ||
7044                 error "'$cmd' wrong: found $nums, expected $expected"
7045         cmd="$LFS find ! -size -5 -type f $dir"
7046         nums=$($cmd | wc -l)
7047         [ $nums -eq $expected ] ||
7048                 error "'$cmd' wrong: found $nums, expected $expected"
7049
7050         expected=12
7051         cmd="$LFS find -size -5 -type f -lazy $dir"
7052         nums=$($cmd | wc -l)
7053         [ $nums -eq $expected ] ||
7054                 error "'$cmd' wrong: found $nums, expected $expected"
7055         cmd="$LFS find -size -5 -type f $dir"
7056         nums=$($cmd | wc -l)
7057         [ $nums -eq $expected ] ||
7058                 error "'$cmd' wrong: found $nums, expected $expected"
7059 }
7060 run_test 56r "check lfs find -size works"
7061
7062 test_56ra_sub() {
7063         local expected=$1
7064         local glimpses=$2
7065         local cmd="$3"
7066
7067         cancel_lru_locks $OSC
7068
7069         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7070         local nums=$($cmd | wc -l)
7071
7072         [ $nums -eq $expected ] ||
7073                 error "'$cmd' wrong: found $nums, expected $expected"
7074
7075         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
7076
7077         if (( rpcs_before + glimpses != rpcs_after )); then
7078                 echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
7079                 $LCTL get_param osc.*.stats | grep ldlm_glimpse_enqueue
7080
7081                 if [[ $glimpses == 0 ]]; then
7082                         error "'$cmd' should not send glimpse RPCs to OST"
7083                 else
7084                         error "'$cmd' should send $glimpses glimpse RPCs to OST"
7085                 fi
7086         fi
7087 }
7088
7089 test_56ra() {
7090         [[ $MDS1_VERSION -gt $(version_code 2.12.58) ]] ||
7091                 skip "MDS < 2.12.58 doesn't return LSOM data"
7092         local dir=$DIR/$tdir
7093         local old_agl=$($LCTL get_param -n llite.*.statahead_agl)
7094
7095         [[ $OSC == "mdc" ]] && skip "statahead not needed for DoM files"
7096
7097         # statahead_agl may cause extra glimpse which confuses results. LU-13017
7098         $LCTL set_param -n llite.*.statahead_agl=0
7099         stack_trap "$LCTL set_param -n llite.*.statahead_agl=$old_agl"
7100
7101         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7102         # open and close all files to ensure LSOM is updated
7103         cancel_lru_locks $OSC
7104         find $dir -type f | xargs cat > /dev/null
7105
7106         #   expect_found  glimpse_rpcs  command_to_run
7107         test_56ra_sub 12  0 "$LFS find -size 0 -type f -lazy $dir"
7108         test_56ra_sub 12 12 "$LFS find -size 0 -type f $dir"
7109         test_56ra_sub  0  0 "$LFS find ! -size 0 -type f -lazy $dir"
7110         test_56ra_sub  0 12 "$LFS find ! -size 0 -type f $dir"
7111
7112         echo "test" > $dir/$tfile
7113         echo "test2" > $dir/$tfile.2 && sync
7114         cancel_lru_locks $OSC
7115         cat $dir/$tfile $dir/$tfile.2 > /dev/null
7116
7117         test_56ra_sub  1  0 "$LFS find -size 5 -type f -lazy $dir"
7118         test_56ra_sub  1 14 "$LFS find -size 5 -type f $dir"
7119         test_56ra_sub  1  0 "$LFS find -size +5 -type f -lazy $dir"
7120         test_56ra_sub  1 14 "$LFS find -size +5 -type f $dir"
7121
7122         test_56ra_sub  2  0 "$LFS find -size +0 -type f -lazy $dir"
7123         test_56ra_sub  2 14 "$LFS find -size +0 -type f $dir"
7124         test_56ra_sub  2  0 "$LFS find ! -size -5 -type f -lazy $dir"
7125         test_56ra_sub  2 14 "$LFS find ! -size -5 -type f $dir"
7126         test_56ra_sub 12  0 "$LFS find -size -5 -type f -lazy $dir"
7127         test_56ra_sub 12 14 "$LFS find -size -5 -type f $dir"
7128 }
7129 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
7130
7131 test_56rb() {
7132         local dir=$DIR/$tdir
7133         local tmp=$TMP/$tfile.log
7134         local mdt_idx;
7135
7136         test_mkdir -p $dir || error "failed to mkdir $dir"
7137         $LFS setstripe -c 1 -i 0 $dir/$tfile ||
7138                 error "failed to setstripe $dir/$tfile"
7139         mdt_idx=$($LFS getdirstripe -i $dir)
7140         dd if=/dev/zero of=$dir/$tfile bs=1M count=1
7141
7142         stack_trap "rm -f $tmp" EXIT
7143         $LFS find --size +100K --ost 0 $dir |& tee $tmp
7144         ! grep -q obd_uuid $tmp ||
7145                 error "failed to find --size +100K --ost 0 $dir"
7146         $LFS find --size +100K --mdt $mdt_idx $dir |& tee $tmp
7147         ! grep -q obd_uuid $tmp ||
7148                 error "failed to find --size +100K --mdt $mdt_idx $dir"
7149 }
7150 run_test 56rb "check lfs find --size --ost/--mdt works"
7151
7152 test_56rc() {
7153         (( MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
7154         local dir=$DIR/$tdir
7155         local found
7156
7157         test_mkdir -c 2 -H all_char $dir || error "failed to mkdir $dir"
7158         $LFS mkdir -c 2 --mdt-hash all_char $dir/$tdir-all{1..10}
7159         (( $MDSCOUNT > 2 )) &&
7160                 $LFS mkdir -c 3 --mdt-hash fnv_1a_64 $dir/$tdir-fnv{1..10}
7161         mkdir $dir/$tdir-{1..10}
7162         touch $dir/$tfile-{1..10}
7163
7164         found=$($LFS find $dir --mdt-count 2 | wc -l)
7165         expect=11
7166         (( $found == $expect )) || error "found $found 2-stripe, expect $expect"
7167
7168         found=$($LFS find $dir -T +1 | wc -l)
7169         (( $MDSCOUNT > 2 )) && expect=$((expect + 10))
7170         (( $found == $expect )) || error "found $found 2+stripe, expect $expect"
7171
7172         found=$($LFS find $dir --mdt-hash all_char | wc -l)
7173         expect=11
7174         (( $found == $expect )) || error "found $found all_char, expect $expect"
7175
7176         found=$($LFS find $dir --mdt-hash fnv_1a_64 | wc -l)
7177         (( $MDSCOUNT > 2 )) && expect=10 || expect=0
7178         (( $found == $expect )) || error "found $found all_char, expect $expect"
7179 }
7180 run_test 56rc "check lfs find --mdt-count/--mdt-hash works"
7181
7182 test_56s() { # LU-611 #LU-9369
7183         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
7184
7185         local dir=$DIR/$tdir
7186         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
7187
7188         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
7189         for i in $(seq $NUMDIRS); do
7190                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
7191         done
7192
7193         local expected=$NUMDIRS
7194         local cmd="$LFS find -c $OSTCOUNT $dir"
7195         local nums=$($cmd | wc -l)
7196
7197         [ $nums -eq $expected ] || {
7198                 $LFS getstripe -R $dir
7199                 error "'$cmd' wrong: found $nums, expected $expected"
7200         }
7201
7202         expected=$((NUMDIRS + onestripe))
7203         cmd="$LFS find -stripe-count +0 -type f $dir"
7204         nums=$($cmd | wc -l)
7205         [ $nums -eq $expected ] || {
7206                 $LFS getstripe -R $dir
7207                 error "'$cmd' wrong: found $nums, expected $expected"
7208         }
7209
7210         expected=$onestripe
7211         cmd="$LFS find -stripe-count 1 -type f $dir"
7212         nums=$($cmd | wc -l)
7213         [ $nums -eq $expected ] || {
7214                 $LFS getstripe -R $dir
7215                 error "'$cmd' wrong: found $nums, expected $expected"
7216         }
7217
7218         cmd="$LFS find -stripe-count -2 -type f $dir"
7219         nums=$($cmd | wc -l)
7220         [ $nums -eq $expected ] || {
7221                 $LFS getstripe -R $dir
7222                 error "'$cmd' wrong: found $nums, expected $expected"
7223         }
7224
7225         expected=0
7226         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
7227         nums=$($cmd | wc -l)
7228         [ $nums -eq $expected ] || {
7229                 $LFS getstripe -R $dir
7230                 error "'$cmd' wrong: found $nums, expected $expected"
7231         }
7232 }
7233 run_test 56s "check lfs find -stripe-count works"
7234
7235 test_56t() { # LU-611 #LU-9369
7236         local dir=$DIR/$tdir
7237
7238         setup_56 $dir 0 $NUMDIRS
7239         for i in $(seq $NUMDIRS); do
7240                 $LFS setstripe -S 8M $dir/dir$i/$tfile
7241         done
7242
7243         local expected=$NUMDIRS
7244         local cmd="$LFS find -S 8M $dir"
7245         local nums=$($cmd | wc -l)
7246
7247         [ $nums -eq $expected ] || {
7248                 $LFS getstripe -R $dir
7249                 error "'$cmd' wrong: found $nums, expected $expected"
7250         }
7251         rm -rf $dir
7252
7253         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
7254
7255         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
7256
7257         expected=$(((NUMDIRS + 1) * NUMFILES))
7258         cmd="$LFS find -stripe-size 512k -type f $dir"
7259         nums=$($cmd | wc -l)
7260         [ $nums -eq $expected ] ||
7261                 error "'$cmd' wrong: found $nums, expected $expected"
7262
7263         cmd="$LFS find -stripe-size +320k -type f $dir"
7264         nums=$($cmd | wc -l)
7265         [ $nums -eq $expected ] ||
7266                 error "'$cmd' wrong: found $nums, expected $expected"
7267
7268         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
7269         cmd="$LFS find -stripe-size +200k -type f $dir"
7270         nums=$($cmd | wc -l)
7271         [ $nums -eq $expected ] ||
7272                 error "'$cmd' wrong: found $nums, expected $expected"
7273
7274         cmd="$LFS find -stripe-size -640k -type f $dir"
7275         nums=$($cmd | wc -l)
7276         [ $nums -eq $expected ] ||
7277                 error "'$cmd' wrong: found $nums, expected $expected"
7278
7279         expected=4
7280         cmd="$LFS find -stripe-size 256k -type f $dir"
7281         nums=$($cmd | wc -l)
7282         [ $nums -eq $expected ] ||
7283                 error "'$cmd' wrong: found $nums, expected $expected"
7284
7285         cmd="$LFS find -stripe-size -320k -type f $dir"
7286         nums=$($cmd | wc -l)
7287         [ $nums -eq $expected ] ||
7288                 error "'$cmd' wrong: found $nums, expected $expected"
7289
7290         expected=0
7291         cmd="$LFS find -stripe-size 1024k -type f $dir"
7292         nums=$($cmd | wc -l)
7293         [ $nums -eq $expected ] ||
7294                 error "'$cmd' wrong: found $nums, expected $expected"
7295 }
7296 run_test 56t "check lfs find -stripe-size works"
7297
7298 test_56u() { # LU-611
7299         local dir=$DIR/$tdir
7300
7301         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
7302
7303         if [[ $OSTCOUNT -gt 1 ]]; then
7304                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
7305                 onestripe=4
7306         else
7307                 onestripe=0
7308         fi
7309
7310         local expected=$(((NUMDIRS + 1) * NUMFILES))
7311         local cmd="$LFS find -stripe-index 0 -type f $dir"
7312         local nums=$($cmd | wc -l)
7313
7314         [ $nums -eq $expected ] ||
7315                 error "'$cmd' wrong: found $nums, expected $expected"
7316
7317         expected=$onestripe
7318         cmd="$LFS find -stripe-index 1 -type f $dir"
7319         nums=$($cmd | wc -l)
7320         [ $nums -eq $expected ] ||
7321                 error "'$cmd' wrong: found $nums, expected $expected"
7322
7323         cmd="$LFS find ! -stripe-index 0 -type f $dir"
7324         nums=$($cmd | wc -l)
7325         [ $nums -eq $expected ] ||
7326                 error "'$cmd' wrong: found $nums, expected $expected"
7327
7328         expected=0
7329         # This should produce an error and not return any files
7330         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
7331         nums=$($cmd 2>/dev/null | wc -l)
7332         [ $nums -eq $expected ] ||
7333                 error "'$cmd' wrong: found $nums, expected $expected"
7334
7335         if [[ $OSTCOUNT -gt 1 ]]; then
7336                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
7337                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
7338                 nums=$($cmd | wc -l)
7339                 [ $nums -eq $expected ] ||
7340                         error "'$cmd' wrong: found $nums, expected $expected"
7341         fi
7342 }
7343 run_test 56u "check lfs find -stripe-index works"
7344
7345 test_56v() {
7346         local mdt_idx=0
7347         local dir=$DIR/$tdir
7348
7349         setup_56 $dir $NUMFILES $NUMDIRS
7350
7351         UUID=$(mdtuuid_from_index $mdt_idx $dir)
7352         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
7353
7354         for file in $($LFS find -m $UUID $dir); do
7355                 file_midx=$($LFS getstripe -m $file)
7356                 [ $file_midx -eq $mdt_idx ] ||
7357                         error "lfs find -m $UUID != getstripe -m $file_midx"
7358         done
7359 }
7360 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
7361
7362 test_56wa() {
7363         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7365
7366         local dir=$DIR/$tdir
7367
7368         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
7369
7370         local stripe_size=$($LFS getstripe -S -d $dir) ||
7371                 error "$LFS getstripe -S -d $dir failed"
7372         stripe_size=${stripe_size%% *}
7373
7374         local file_size=$((stripe_size * OSTCOUNT))
7375         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
7376         local required_space=$((file_num * file_size))
7377         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
7378                            head -n1)
7379         (( free_space >= required_space / 1024 )) ||
7380                 skip_env "need $required_space, have $free_space kbytes"
7381
7382         local dd_bs=65536
7383         local dd_count=$((file_size / dd_bs))
7384
7385         # write data into the files
7386         local i
7387         local j
7388         local file
7389
7390         for ((i = 1; i <= NUMFILES; i++ )); do
7391                 file=$dir/file$i
7392                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7393                         error "write data into $file failed"
7394         done
7395         for ((i = 1; i <= NUMDIRS; i++ )); do
7396                 for ((j = 1; j <= NUMFILES; j++ )); do
7397                         file=$dir/dir$i/file$j
7398                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
7399                                 error "write data into $file failed"
7400                 done
7401         done
7402
7403         # $LFS_MIGRATE will fail if hard link migration is unsupported
7404         if (( MDS1_VERSION > $(version_code 2.5.55) )); then
7405                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
7406                         error "creating links to $dir/dir1/file1 failed"
7407         fi
7408
7409         local expected=-1
7410
7411         (( OSTCOUNT <= 1 )) || expected=$((OSTCOUNT - 1))
7412
7413         # lfs_migrate file
7414         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
7415
7416         echo "$cmd"
7417         eval $cmd || error "$cmd failed"
7418
7419         check_stripe_count $dir/file1 $expected
7420
7421         if (( $MDS1_VERSION >= $(version_code 2.6.90) )); then
7422                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
7423                 # OST 1 if it is on OST 0. This file is small enough to
7424                 # be on only one stripe.
7425                 file=$dir/migr_1_ost
7426                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
7427                         error "write data into $file failed"
7428                 local obdidx=$($LFS getstripe -i $file)
7429                 local oldmd5=$(md5sum $file)
7430                 local newobdidx=0
7431
7432                 (( obdidx != 0 )) || newobdidx=1
7433                 cmd="$LFS migrate -i $newobdidx $file"
7434                 echo $cmd
7435                 eval $cmd || error "$cmd failed"
7436
7437                 local realobdix=$($LFS getstripe -i $file)
7438                 local newmd5=$(md5sum $file)
7439
7440                 (( $newobdidx == $realobdix )) ||
7441                         error "new OST is different (was=$obdidx, wanted=$newobdidx, got=$realobdix)"
7442                 [[ "$oldmd5" == "$newmd5" ]] ||
7443                         error "md5sum differ: $oldmd5, $newmd5"
7444         fi
7445
7446         # lfs_migrate dir
7447         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
7448         echo "$cmd"
7449         eval $cmd || error "$cmd failed"
7450
7451         for (( j = 1; j <= NUMFILES; j++ )); do
7452                 check_stripe_count $dir/dir1/file$j $expected
7453         done
7454
7455         # lfs_migrate works with lfs find
7456         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
7457              $LFS_MIGRATE -y -c $expected"
7458         echo "$cmd"
7459         eval $cmd || error "$cmd failed"
7460
7461         for (( i = 2; i <= NUMFILES; i++ )); do
7462                 check_stripe_count $dir/file$i $expected
7463         done
7464         for (( i = 2; i <= NUMDIRS; i++ )); do
7465                 for (( j = 1; j <= NUMFILES; j++ )); do
7466                         check_stripe_count $dir/dir$i/file$j $expected
7467                 done
7468         done
7469 }
7470 run_test 56wa "check lfs_migrate -c stripe_count works"
7471
7472 test_56wb() {
7473         local file1=$DIR/$tdir/file1
7474         local create_pool=false
7475         local initial_pool=$($LFS getstripe -p $DIR)
7476         local pool_list=()
7477         local pool=""
7478
7479         echo -n "Creating test dir..."
7480         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7481         echo "done."
7482
7483         echo -n "Creating test file..."
7484         touch $file1 || error "cannot create file"
7485         echo "done."
7486
7487         echo -n "Detecting existing pools..."
7488         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
7489
7490         if [ ${#pool_list[@]} -gt 0 ]; then
7491                 echo "${pool_list[@]}"
7492                 for thispool in "${pool_list[@]}"; do
7493                         if [[ -z "$initial_pool" ||
7494                               "$initial_pool" != "$thispool" ]]; then
7495                                 pool="$thispool"
7496                                 echo "Using existing pool '$pool'"
7497                                 break
7498                         fi
7499                 done
7500         else
7501                 echo "none detected."
7502         fi
7503         if [ -z "$pool" ]; then
7504                 pool=${POOL:-testpool}
7505                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
7506                 echo -n "Creating pool '$pool'..."
7507                 create_pool=true
7508                 pool_add $pool &> /dev/null ||
7509                         error "pool_add failed"
7510                 echo "done."
7511
7512                 echo -n "Adding target to pool..."
7513                 pool_add_targets $pool 0 0 1 &> /dev/null ||
7514                         error "pool_add_targets failed"
7515                 echo "done."
7516         fi
7517
7518         echo -n "Setting pool using -p option..."
7519         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
7520                 error "migrate failed rc = $?"
7521         echo "done."
7522
7523         echo -n "Verifying test file is in pool after migrating..."
7524         [ "$($LFS getstripe -p $file1)" = $pool ] ||
7525                 error "file was not migrated to pool $pool"
7526         echo "done."
7527
7528         echo -n "Removing test file from pool '$pool'..."
7529         # "lfs migrate $file" won't remove the file from the pool
7530         # until some striping information is changed.
7531         $LFS migrate -c 1 $file1 &> /dev/null ||
7532                 error "cannot remove from pool"
7533         [ "$($LFS getstripe -p $file1)" ] &&
7534                 error "pool still set"
7535         echo "done."
7536
7537         echo -n "Setting pool using --pool option..."
7538         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
7539                 error "migrate failed rc = $?"
7540         echo "done."
7541
7542         # Clean up
7543         rm -f $file1
7544         if $create_pool; then
7545                 destroy_test_pools 2> /dev/null ||
7546                         error "destroy test pools failed"
7547         fi
7548 }
7549 run_test 56wb "check lfs_migrate pool support"
7550
7551 test_56wc() {
7552         local file1="$DIR/$tdir/$tfile"
7553         local md5
7554         local parent_ssize
7555         local parent_scount
7556         local cur_ssize
7557         local cur_scount
7558         local orig_ssize
7559         local new_scount
7560         local cur_comp
7561
7562         echo -n "Creating test dir..."
7563         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
7564         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
7565                 error "cannot set stripe by '-S 1M -c 1'"
7566         echo "done"
7567
7568         echo -n "Setting initial stripe for test file..."
7569         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
7570                 error "cannot set stripe"
7571         cur_ssize=$($LFS getstripe -S "$file1")
7572         (( cur_ssize == 524288 )) || error "setstripe -S $cur_ssize != 524288"
7573         echo "done."
7574
7575         dd if=/dev/urandom of=$file1 bs=1M count=12 || error "dd $file1 failed"
7576         stack_trap "rm -f $file1"
7577         md5="$(md5sum $file1)"
7578
7579         # File currently set to -S 512K -c 1
7580
7581         # Ensure -c and -S options are rejected when -R is set
7582         echo -n "Verifying incompatible options are detected..."
7583         $LFS_MIGRATE -R -c 1 "$file1" &&
7584                 error "incompatible -R and -c options not detected"
7585         $LFS_MIGRATE -R -S 1M "$file1" &&
7586                 error "incompatible -R and -S options not detected"
7587         $LFS_MIGRATE -R -p pool "$file1" &&
7588                 error "incompatible -R and -p options not detected"
7589         $LFS_MIGRATE -R -E eof -c 1 "$file1" &&
7590                 error "incompatible -R and -E options not detected"
7591         $LFS_MIGRATE -R -A "$file1" &&
7592                 error "incompatible -R and -A options not detected"
7593         $LFS_MIGRATE -A -c 1 "$file1" &&
7594                 error "incompatible -A and -c options not detected"
7595         $LFS_MIGRATE -A -S 1M "$file1" &&
7596                 error "incompatible -A and -S options not detected"
7597         $LFS_MIGRATE -A -p pool "$file1" &&
7598                 error "incompatible -A and -p options not detected"
7599         $LFS_MIGRATE -A -E eof -c 1 "$file1" &&
7600                 error "incompatible -A and -E options not detected"
7601         echo "done."
7602
7603         # Ensure unrecognized options are passed through to 'lfs migrate'
7604         echo -n "Verifying -S option is passed through to lfs migrate..."
7605         $LFS_MIGRATE -y -S 1M "$file1" || error "migration failed"
7606         cur_ssize=$($LFS getstripe -S "$file1")
7607         (( cur_ssize == 1048576 )) || error "migrate -S $cur_ssize != 1048576"
7608         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (1)"
7609         echo "done."
7610
7611         # File currently set to -S 1M -c 1
7612
7613         # Ensure long options are supported
7614         echo -n "Verifying long options supported..."
7615         $LFS_MIGRATE --non-block "$file1" ||
7616                 error "long option without argument not supported"
7617         $LFS_MIGRATE --stripe-size 512K "$file1" ||
7618                 error "long option with argument not supported"
7619         cur_ssize=$($LFS getstripe -S "$file1")
7620         (( cur_ssize == 524288 )) ||
7621                 error "migrate --stripe-size $cur_ssize != 524288"
7622         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (2)"
7623         echo "done."
7624
7625         # File currently set to -S 512K -c 1
7626
7627         if (( OSTCOUNT > 1 )); then
7628                 echo -n "Verifying explicit stripe count can be set..."
7629                 $LFS_MIGRATE -c 2 "$file1" || error "migrate failed"
7630                 cur_scount=$($LFS getstripe -c "$file1")
7631                 (( cur_scount == 2 )) || error "migrate -c $cur_scount != 2"
7632                 [[ "$(md5sum $file1)" == "$md5" ]] ||
7633                         error "file data has changed (3)"
7634                 echo "done."
7635         fi
7636
7637         # File currently set to -S 512K -c 1 or -S 512K -c 2
7638
7639         # Ensure parent striping is used if -R is set, and no stripe
7640         # count or size is specified
7641         echo -n "Setting stripe for parent directory..."
7642         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7643                 error "cannot set stripe '-S 2M -c 1'"
7644         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (4)"
7645         echo "done."
7646
7647         echo -n "Verifying restripe option uses parent stripe settings..."
7648         parent_ssize=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
7649         parent_scount=$($LFS getstripe -c $DIR/$tdir 2>/dev/null)
7650         $LFS_MIGRATE -R "$file1" || error "migrate failed"
7651         cur_ssize=$($LFS getstripe -S "$file1")
7652         (( cur_ssize == parent_ssize )) ||
7653                 error "migrate -R stripe_size $cur_ssize != $parent_ssize"
7654         cur_scount=$($LFS getstripe -c "$file1")
7655         (( cur_scount == parent_scount )) ||
7656                 error "migrate -R stripe_count $cur_scount != $parent_scount"
7657         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (5)"
7658         echo "done."
7659
7660         # File currently set to -S 1M -c 1
7661
7662         # Ensure striping is preserved if -R is not set, and no stripe
7663         # count or size is specified
7664         echo -n "Verifying striping size preserved when not specified..."
7665         orig_ssize=$($LFS getstripe -S "$file1" 2>/dev/null)
7666         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
7667                 error "cannot set stripe on parent directory"
7668         $LFS_MIGRATE "$file1" || error "migrate failed"
7669         cur_ssize=$($LFS getstripe -S "$file1")
7670         (( cur_ssize == orig_ssize )) ||
7671                 error "migrate by default $cur_ssize != $orig_ssize"
7672         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (6)"
7673         echo "done."
7674
7675         # Ensure file name properly detected when final option has no argument
7676         echo -n "Verifying file name properly detected..."
7677         $LFS_MIGRATE "$file1" ||
7678                 error "file name interpreted as option argument"
7679         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (7)"
7680         echo "done."
7681
7682         # Ensure PFL arguments are passed through properly
7683         echo -n "Verifying PFL options passed through..."
7684         new_scount=$(((OSTCOUNT + 1) / 2))
7685         $LFS_MIGRATE -E 1M -c 1 -E 16M -c $new_scount -E eof -c -1 "$file1" ||
7686                 error "migrate PFL arguments failed"
7687         cur_comp=$($LFS getstripe --comp-count $file1)
7688         (( cur_comp == 3 )) || error "component count '$cur_comp' != 3"
7689         cur_scount=$($LFS getstripe --stripe-count $file1)
7690         (( cur_scount == new_scount)) ||
7691                 error "PFL stripe count $cur_scount != $new_scount"
7692         [[ "$(md5sum $file1)" == "$md5" ]] || error "file data has changed (8)"
7693         echo "done."
7694 }
7695 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
7696
7697 test_56wd() {
7698         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
7699
7700         local file1=$DIR/$tdir/$tfile
7701
7702         echo -n "Creating test dir..."
7703         test_mkdir $DIR/$tdir || error "cannot create dir"
7704         echo "done."
7705
7706         echo -n "Creating test file..."
7707         echo "$tfile" > $file1
7708         echo "done."
7709
7710         # Ensure 'lfs migrate' will fail by using a non-existent option,
7711         # and make sure rsync is not called to recover
7712         echo -n "Make sure --no-rsync option works..."
7713         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
7714                 grep -q 'refusing to fall back to rsync' ||
7715                 error "rsync was called with --no-rsync set"
7716         echo "done."
7717
7718         # Ensure rsync is called without trying 'lfs migrate' first
7719         echo -n "Make sure --rsync option works..."
7720         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
7721                 grep -q 'falling back to rsync' &&
7722                 error "lfs migrate was called with --rsync set"
7723         echo "done."
7724 }
7725 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
7726
7727 test_56we() {
7728         local td=$DIR/$tdir
7729         local tf=$td/$tfile
7730
7731         test_mkdir $td || error "cannot create $td"
7732         touch $tf || error "cannot touch $tf"
7733
7734         echo -n "Make sure --non-direct|-D works..."
7735         $LFS_MIGRATE -y --non-direct -v $tf 2>&1 |
7736                 grep -q "lfs migrate --non-direct" ||
7737                 error "--non-direct option cannot work correctly"
7738         $LFS_MIGRATE -y -D -v $tf 2>&1 |
7739                 grep -q "lfs migrate -D" ||
7740                 error "-D option cannot work correctly"
7741         echo "done."
7742 }
7743 run_test 56we "check lfs_migrate --non-direct|-D support"
7744
7745 test_56x() {
7746         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7747         check_swap_layouts_support
7748
7749         local dir=$DIR/$tdir
7750         local ref1=/etc/passwd
7751         local file1=$dir/file1
7752
7753         test_mkdir $dir || error "creating dir $dir"
7754         $LFS setstripe -c 2 $file1
7755         cp $ref1 $file1
7756         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
7757         stripe=$($LFS getstripe -c $file1)
7758         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7759         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7760
7761         # clean up
7762         rm -f $file1
7763 }
7764 run_test 56x "lfs migration support"
7765
7766 test_56xa() {
7767         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7768         check_swap_layouts_support
7769
7770         local dir=$DIR/$tdir/$testnum
7771
7772         test_mkdir -p $dir
7773
7774         local ref1=/etc/passwd
7775         local file1=$dir/file1
7776
7777         $LFS setstripe -c 2 $file1
7778         cp $ref1 $file1
7779         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
7780
7781         local stripe=$($LFS getstripe -c $file1)
7782
7783         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
7784         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
7785
7786         # clean up
7787         rm -f $file1
7788 }
7789 run_test 56xa "lfs migration --block support"
7790
7791 check_migrate_links() {
7792         [[ "$1" == "--rsync" ]] && local opts="--rsync -y" && shift
7793         local dir="$1"
7794         local file1="$dir/file1"
7795         local begin="$2"
7796         local count="$3"
7797         local runas="$4"
7798         local total_count=$(($begin + $count - 1))
7799         local symlink_count=10
7800         local uniq_count=10
7801
7802         if [ ! -f "$file1" ]; then
7803                 echo -n "creating initial file..."
7804                 $LFS setstripe -c 1 -S "512k" "$file1" ||
7805                         error "cannot setstripe initial file"
7806                 echo "done"
7807
7808                 echo -n "creating symlinks..."
7809                 for s in $(seq 1 $symlink_count); do
7810                         ln -s "$file1" "$dir/slink$s" ||
7811                                 error "cannot create symlinks"
7812                 done
7813                 echo "done"
7814
7815                 echo -n "creating nonlinked files..."
7816                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
7817                         error "cannot create nonlinked files"
7818                 echo "done"
7819         fi
7820
7821         # create hard links
7822         if [ ! -f "$dir/file$total_count" ]; then
7823                 echo -n "creating hard links $begin:$total_count..."
7824                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
7825                         /dev/null || error "cannot create hard links"
7826                 echo "done"
7827         fi
7828
7829         echo -n "checking number of hard links listed in xattrs..."
7830         local fid=$($LFS getstripe -F "$file1")
7831         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
7832
7833         echo "${#paths[*]}"
7834         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
7835                         skip "hard link list has unexpected size, skipping test"
7836         fi
7837         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
7838                         error "link names should exceed xattrs size"
7839         fi
7840
7841         echo -n "migrating files..."
7842         local migrate_out=$($runas $LFS_MIGRATE $opts -S '1m' $dir)
7843         local rc=$?
7844         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
7845         echo "done"
7846
7847         # make sure all links have been properly migrated
7848         echo -n "verifying files..."
7849         fid=$($LFS getstripe -F "$file1") ||
7850                 error "cannot get fid for file $file1"
7851         for i in $(seq 2 $total_count); do
7852                 local fid2=$($LFS getstripe -F $dir/file$i)
7853
7854                 [ "$fid2" == "$fid" ] ||
7855                         error "migrated hard link has mismatched FID"
7856         done
7857
7858         # make sure hard links were properly detected, and migration was
7859         # performed only once for the entire link set; nonlinked files should
7860         # also be migrated
7861         local actual=$(grep -c 'done' <<< "$migrate_out")
7862         local expected=$(($uniq_count + 1))
7863
7864         [ "$actual" -eq  "$expected" ] ||
7865                 error "hard links individually migrated ($actual != $expected)"
7866
7867         # make sure the correct number of hard links are present
7868         local hardlinks=$(stat -c '%h' "$file1")
7869
7870         [ $hardlinks -eq $total_count ] ||
7871                 error "num hard links $hardlinks != $total_count"
7872         echo "done"
7873
7874         return 0
7875 }
7876
7877 test_56xb() {
7878         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
7879                 skip "Need MDS version at least 2.10.55"
7880
7881         local dir="$DIR/$tdir"
7882
7883         test_mkdir "$dir" || error "cannot create dir $dir"
7884
7885         echo "testing lfs migrate mode when all links fit within xattrs"
7886         check_migrate_links "$dir" 2 99
7887
7888         echo "testing rsync mode when all links fit within xattrs"
7889         check_migrate_links --rsync "$dir" 2 99
7890
7891         echo "testing lfs migrate mode when all links do not fit within xattrs"
7892         check_migrate_links "$dir" 101 100
7893
7894         echo "testing rsync mode when all links do not fit within xattrs"
7895         check_migrate_links --rsync "$dir" 101 100
7896
7897         chown -R $RUNAS_ID $dir
7898         echo "testing non-root lfs migrate mode when not all links are in xattr"
7899         check_migrate_links "$dir" 101 100 "$RUNAS"
7900
7901         # clean up
7902         rm -rf $dir
7903 }
7904 run_test 56xb "lfs migration hard link support"
7905
7906 test_56xc() {
7907         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7908
7909         local dir="$DIR/$tdir"
7910
7911         test_mkdir "$dir" || error "cannot create dir $dir"
7912
7913         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
7914         echo -n "Setting initial stripe for 20MB test file..."
7915         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
7916                 error "cannot setstripe 20MB file"
7917         echo "done"
7918         echo -n "Sizing 20MB test file..."
7919         $TRUNCATE "$dir/20mb" 20971520 || error "cannot create 20MB test file"
7920         echo "done"
7921         echo -n "Verifying small file autostripe count is 1..."
7922         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
7923                 error "cannot migrate 20MB file"
7924         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
7925                 error "cannot get stripe for $dir/20mb"
7926         [ $stripe_count -eq 1 ] ||
7927                 error "unexpected stripe count $stripe_count for 20MB file"
7928         rm -f "$dir/20mb"
7929         echo "done"
7930
7931         # Test 2: File is small enough to fit within the available space on
7932         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
7933         # have at least an additional 1KB for each desired stripe for test 3
7934         echo -n "Setting stripe for 1GB test file..."
7935         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
7936         echo "done"
7937         echo -n "Sizing 1GB test file..."
7938         # File size is 1GB + 3KB
7939         $TRUNCATE "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
7940         echo "done"
7941
7942         # need at least 512MB per OST for 1GB file to fit in 2 stripes
7943         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
7944         if (( avail > 524288 * OSTCOUNT )); then
7945                 echo -n "Migrating 1GB file..."
7946                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
7947                         error "cannot migrate 1GB file"
7948                 echo "done"
7949                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
7950                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
7951                         error "cannot getstripe for 1GB file"
7952                 [ $stripe_count -eq 2 ] ||
7953                         error "unexpected stripe count $stripe_count != 2"
7954                 echo "done"
7955         fi
7956
7957         # Test 3: File is too large to fit within the available space on
7958         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
7959         if [ $OSTCOUNT -ge 3 ]; then
7960                 # The required available space is calculated as
7961                 # file size (1GB + 3KB) / OST count (3).
7962                 local kb_per_ost=349526
7963
7964                 echo -n "Migrating 1GB file with limit..."
7965                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
7966                         error "cannot migrate 1GB file with limit"
7967                 echo "done"
7968
7969                 stripe_count=$($LFS getstripe -c "$dir/1gb")
7970                 echo -n "Verifying 1GB autostripe count with limited space..."
7971                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
7972                         error "unexpected stripe count $stripe_count (min 3)"
7973                 echo "done"
7974         fi
7975
7976         # clean up
7977         rm -rf $dir
7978 }
7979 run_test 56xc "lfs migration autostripe"
7980
7981 test_56xd() {
7982         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7983
7984         local dir=$DIR/$tdir
7985         local f_mgrt=$dir/$tfile.mgrt
7986         local f_yaml=$dir/$tfile.yaml
7987         local f_copy=$dir/$tfile.copy
7988         local layout_yaml="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
7989         local layout_copy="-c 2 -S 2M -i 1"
7990         local yamlfile=$dir/yamlfile
7991         local layout_before;
7992         local layout_after;
7993
7994         test_mkdir "$dir" || error "cannot create dir $dir"
7995         $LFS setstripe $layout_yaml $f_yaml ||
7996                 error "cannot setstripe $f_yaml with layout $layout_yaml"
7997         $LFS getstripe --yaml $f_yaml > $yamlfile
7998         $LFS setstripe $layout_copy $f_copy ||
7999                 error "cannot setstripe $f_copy with layout $layout_copy"
8000         touch $f_mgrt
8001         dd if=/dev/zero of=$f_mgrt bs=1M count=4
8002
8003         # 1. test option --yaml
8004         $LFS_MIGRATE -y --yaml $yamlfile $f_mgrt ||
8005                 error "cannot migrate $f_mgrt with --yaml $yamlfile"
8006         layout_before=$(get_layout_param $f_yaml)
8007         layout_after=$(get_layout_param $f_mgrt)
8008         [ "$layout_after" == "$layout_before" ] ||
8009                 error "lfs_migrate --yaml: $layout_after != $layout_before"
8010
8011         # 2. test option --copy
8012         $LFS_MIGRATE -y --copy $f_copy $f_mgrt ||
8013                 error "cannot migrate $f_mgrt with --copy $f_copy"
8014         layout_before=$(SKIP_INDEX=yes get_layout_param $f_copy)
8015         layout_after=$(SKIP_INDEX=yes get_layout_param $f_mgrt)
8016         [ "$layout_after" == "$layout_before" ] ||
8017                 error "lfs_migrate --copy: $layout_after != $layout_before"
8018 }
8019 run_test 56xd "check lfs_migrate --yaml and --copy support"
8020
8021 test_56xe() {
8022         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8023
8024         local dir=$DIR/$tdir
8025         local f_comp=$dir/$tfile
8026         local layout="-E 1M -S 512K -c 1 -E -1 -S 1M -c 2 -i 0"
8027         local layout_before=""
8028         local layout_after=""
8029
8030         test_mkdir "$dir" || error "cannot create dir $dir"
8031         $LFS setstripe $layout $f_comp ||
8032                 error "cannot setstripe $f_comp with layout $layout"
8033         layout_before=$(SKIP_INDEX=yes get_layout_param $f_comp)
8034         dd if=/dev/zero of=$f_comp bs=1M count=4
8035
8036         # 1. migrate a comp layout file by lfs_migrate
8037         $LFS_MIGRATE -y $f_comp || error "cannot migrate $f_comp by lfs_migrate"
8038         layout_after=$(SKIP_INDEX=yes get_layout_param $f_comp)
8039         [ "$layout_before" == "$layout_after" ] ||
8040                 error "lfs_migrate: $layout_before != $layout_after"
8041
8042         # 2. migrate a comp layout file by lfs migrate
8043         $LFS migrate $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 run_test 56xe "migrate a composite layout file"
8049
8050 test_56xf() {
8051         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
8052
8053         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
8054                 skip "Need server version at least 2.13.53"
8055
8056         local dir=$DIR/$tdir
8057         local f_comp=$dir/$tfile
8058         local layout="-E 1M -c1 -E -1 -c2"
8059         local fid_before=""
8060         local fid_after=""
8061
8062         test_mkdir "$dir" || error "cannot create dir $dir"
8063         $LFS setstripe $layout $f_comp ||
8064                 error "cannot setstripe $f_comp with layout $layout"
8065         fid_before=$($LFS getstripe --fid $f_comp)
8066         dd if=/dev/zero of=$f_comp bs=1M count=4
8067
8068         # 1. migrate a comp layout file to a comp layout
8069         $LFS migrate $f_comp || error "cannot migrate $f_comp by lfs migrate"
8070         fid_after=$($LFS getstripe --fid $f_comp)
8071         [ "$fid_before" == "$fid_after" ] ||
8072                 error "comp-to-comp migrate: $fid_before != $fid_after"
8073
8074         # 2. migrate a comp layout file to a plain layout
8075         $LFS migrate -c2 $f_comp ||
8076                 error "cannot migrate $f_comp by lfs migrate"
8077         fid_after=$($LFS getstripe --fid $f_comp)
8078         [ "$fid_before" == "$fid_after" ] ||
8079                 error "comp-to-plain migrate: $fid_before != $fid_after"
8080
8081         # 3. migrate a plain layout file to a comp layout
8082         $LFS migrate $layout $f_comp ||
8083                 error "cannot migrate $f_comp by lfs migrate"
8084         fid_after=$($LFS getstripe --fid $f_comp)
8085         [ "$fid_before" == "$fid_after" ] ||
8086                 error "plain-to-comp migrate: $fid_before != $fid_after"
8087 }
8088 run_test 56xf "FID is not lost during migration of a composite layout file"
8089
8090 check_file_ost_range() {
8091         local file="$1"
8092         shift
8093         local range="$*"
8094         local -a file_range
8095         local idx
8096
8097         file_range=($($LFS getstripe -y "$file" |
8098                 awk '/l_ost_idx:/ { print $NF }'))
8099
8100         if [[ "${#file_range[@]}" = 0 ]]; then
8101                 echo "No osts found for $file"
8102                 return 1
8103         fi
8104
8105         for idx in "${file_range[@]}"; do
8106                 [[ " $range " =~ " $idx " ]] ||
8107                         return 1
8108         done
8109
8110         return 0
8111 }
8112
8113 sub_test_56xg() {
8114         local stripe_opt="$1"
8115         local pool="$2"
8116         shift 2
8117         local pool_ostidx="$(seq $* | tr '\n' ' ')"
8118
8119         $LFS migrate $stripe_opt -p $pool $DIR/$tfile ||
8120                 error "Fail to migrate $tfile on $pool"
8121         [[ "$($LFS getstripe -p $DIR/$tfile)" = "$pool" ]] ||
8122                 error "$tfile is not in pool $pool"
8123         check_file_ost_range "$DIR/$tfile" $pool_ostidx ||
8124                 error "$tfile osts mismatch with pool $pool (osts $pool_ostidx)"
8125 }
8126
8127 test_56xg() {
8128         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
8129         [[ $OSTCOUNT -ge 2 ]] || skip "needs >= 2 OSTs"
8130         [[ $MDS1_VERSION -gt $(version_code 2.14.52) ]] ||
8131                 skip "Need MDS version newer than 2.14.52"
8132
8133         local -a pool_names=("${TESTNAME}_0" "${TESTNAME}_1" "${TESTNAME}_2")
8134         local -a pool_ranges=("0 0" "1 1" "0 1")
8135
8136         # init pools
8137         for i in "${!pool_names[@]}"; do
8138                 pool_add ${pool_names[$i]} ||
8139                         error "pool_add failed (pool: ${pool_names[$i]})"
8140                 pool_add_targets ${pool_names[$i]} ${pool_ranges[$i]} ||
8141                         error "pool_add_targets failed (pool: ${pool_names[$i]})"
8142         done
8143
8144         # init the file to migrate
8145         $LFS setstripe -c1 -i1 $DIR/$tfile ||
8146                 error "Unable to create $tfile on OST1"
8147         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=4 status=none ||
8148                 error "Unable to write on $tfile"
8149
8150         echo "1. migrate $tfile on pool ${pool_names[0]}"
8151         sub_test_56xg "-c-1" "${pool_names[0]}" ${pool_ranges[0]}
8152
8153         echo "2. migrate $tfile on pool ${pool_names[2]}"
8154         sub_test_56xg "-c-1 -S2M" "${pool_names[2]}" ${pool_ranges[2]}
8155
8156         echo "3. migrate $tfile on pool ${pool_names[1]}"
8157         sub_test_56xg "-n -c-1" "${pool_names[1]}" ${pool_ranges[1]}
8158
8159         echo "4. migrate $tfile on pool ${pool_names[2]} with default stripe parameters"
8160         sub_test_56xg "" "${pool_names[2]}" ${pool_ranges[2]}
8161         echo
8162
8163         # Clean pools
8164         destroy_test_pools ||
8165                 error "pool_destroy failed"
8166 }
8167 run_test 56xg "lfs migrate pool support"
8168
8169 test_56xh() {
8170         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8171
8172         local size_mb=25
8173         local file1=$DIR/$tfile
8174         local tmp1=$TMP/$tfile.tmp
8175
8176         $LFS setstripe -c 2 $file1
8177
8178         stack_trap "rm -f $file1 $tmp1"
8179         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8180                         error "error creating $tmp1"
8181         ls -lsh $tmp1
8182         cp $tmp1 $file1
8183
8184         local start=$SECONDS
8185
8186         $LFS migrate --stats --stats-interval=1 -W 1M -c 1 $file1 ||
8187                 error "migrate failed rc = $?"
8188
8189         local elapsed=$((SECONDS - start))
8190
8191         # with 1MB/s, elapsed should equal size_mb
8192         (( elapsed >= size_mb * 95 / 100 )) ||
8193                 error "'lfs migrate -W' too fast ($elapsed < 0.95 * $size_mb)?"
8194
8195         (( elapsed <= size_mb * 120 / 100 )) ||
8196                 error_not_in_vm "'lfs migrate -W' slow ($elapsed > 1.2 * $size_mb)"
8197
8198         (( elapsed <= size_mb * 350 / 100 )) ||
8199                 error "'lfs migrate -W' too slow in VM ($elapsed > 3.5 * $size_mb)"
8200
8201         stripe=$($LFS getstripe -c $file1)
8202         (( $stripe == 1 )) || error "stripe of $file1 is $stripe != 1"
8203         cmp $file1 $tmp1 || error "content mismatch $file1 differs from $tmp1"
8204
8205         # Clean up file (since it is multiple MB)
8206         rm -f $file1 $tmp1
8207 }
8208 run_test 56xh "lfs migrate bandwidth limitation support"
8209
8210 test_56xi() {
8211         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8212         verify_yaml_available || skip_env "YAML verification not installed"
8213
8214         local size_mb=5
8215         local file1=$DIR/$tfile.1
8216         local file2=$DIR/$tfile.2
8217         local file3=$DIR/$tfile.3
8218         local output_file=$DIR/$tfile.out
8219         local tmp1=$TMP/$tfile.tmp
8220
8221         $LFS setstripe -c 2 $file1
8222         $LFS setstripe -c 2 $file2
8223         $LFS setstripe -c 2 $file3
8224
8225         stack_trap "rm -f $file1 $file2 $file3 $tmp1 $output_file"
8226         dd if=/dev/urandom of=$tmp1 bs=1M count=$size_mb ||
8227                         error "error creating $tmp1"
8228         ls -lsh $tmp1
8229         cp $tmp1 $file1
8230         cp $tmp1 $file2
8231         cp $tmp1 $file3
8232
8233         $LFS migrate --stats --stats-interval=1 \
8234                 -c 1 $file1 $file2 $file3 1> $output_file ||
8235                 error "migrate failed rc = $?"
8236
8237         cat $output_file
8238         cat $output_file | verify_yaml || error "rename_stats is not valid YAML"
8239
8240         # Clean up file (since it is multiple MB)
8241         rm -f $file1 $file2 $file3 $tmp1 $output_file
8242 }
8243 run_test 56xi "lfs migrate stats support"
8244
8245 test_56xj() { # LU-16571 "lfs migrate -b" can cause thread starvation on OSS
8246         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
8247
8248         local file=$DIR/$tfile
8249         local linkdir=$DIR/$tdir
8250
8251         test_mkdir $linkdir || error "fail to create $linkdir"
8252         $LFS setstripe -i 0 -c 1 -S1M $file
8253         dd if=/dev/urandom of=$file bs=1M count=10 ||
8254                 error "fail to create $file"
8255
8256         # Create file links
8257         local cpts
8258         local threads_max
8259         local nlinks
8260
8261         thread_max=$(do_facet ost1 "$LCTL get_param -n ost.OSS.ost.threads_max")
8262         cpts=$(do_facet ost1 "$LCTL get_param -n cpu_partition_table | wc -l")
8263         (( nlinks = thread_max * 3 / 2 / cpts))
8264
8265         echo "create $nlinks hard links of $file"
8266         createmany -l $file $linkdir/link $nlinks
8267
8268         # Parallel migrates (should not block)
8269         local i
8270         for ((i = 0; i < nlinks; i++)); do
8271                 echo $linkdir/link$i
8272         done | xargs -n1 -P $nlinks $LFS migrate -c2
8273
8274         local stripe_count
8275         stripe_count=$($LFS getstripe -c $file) ||
8276                 error "fail to get stripe count on $file"
8277
8278         ((stripe_count == 2)) ||
8279                 error "fail to migrate $file (stripe_count = $stripe_count)"
8280 }
8281 run_test 56xj "lfs migrate -b should not cause starvation of threads on OSS"
8282
8283 test_56y() {
8284         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
8285                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
8286
8287         local res=""
8288         local dir=$DIR/$tdir
8289         local f1=$dir/file1
8290         local f2=$dir/file2
8291
8292         test_mkdir -p $dir || error "creating dir $dir"
8293         touch $f1 || error "creating std file $f1"
8294         $MULTIOP $f2 H2c || error "creating released file $f2"
8295
8296         # a directory can be raid0, so ask only for files
8297         res=$($LFS find $dir -L raid0 -type f | wc -l)
8298         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
8299
8300         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
8301         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
8302
8303         # only files can be released, so no need to force file search
8304         res=$($LFS find $dir -L released)
8305         [[ $res == $f2 ]] || error "search released: found $res != $f2"
8306
8307         res=$($LFS find $dir -type f \! -L released)
8308         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
8309 }
8310 run_test 56y "lfs find -L raid0|released"
8311
8312 test_56z() { # LU-4824
8313         # This checks to make sure 'lfs find' continues after errors
8314         # There are two classes of errors that should be caught:
8315         # - If multiple paths are provided, all should be searched even if one
8316         #   errors out
8317         # - If errors are encountered during the search, it should not terminate
8318         #   early
8319         local dir=$DIR/$tdir
8320         local i
8321
8322         test_mkdir $dir
8323         for i in d{0..9}; do
8324                 test_mkdir $dir/$i
8325                 touch $dir/$i/$tfile
8326         done
8327         $LFS find $DIR/non_existent_dir $dir &&
8328                 error "$LFS find did not return an error"
8329         # Make a directory unsearchable. This should NOT be the last entry in
8330         # directory order.  Arbitrarily pick the 6th entry
8331         chmod 700 $($LFS find $dir -type d | sed '6!d')
8332
8333         $RUNAS $LFS find $DIR/non_existent $dir
8334         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
8335
8336         # The user should be able to see 10 directories and 9 files
8337         (( count == 19 )) ||
8338                 error "$LFS find found $count != 19 entries after error"
8339 }
8340 run_test 56z "lfs find should continue after an error"
8341
8342 test_56aa() { # LU-5937
8343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
8344
8345         local dir=$DIR/$tdir
8346
8347         mkdir $dir
8348         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
8349
8350         createmany -o $dir/striped_dir/${tfile}- 1024
8351         local dirs=$($LFS find --size +8k $dir/)
8352
8353         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
8354 }
8355 run_test 56aa "lfs find --size under striped dir"
8356
8357 test_56ab() { # LU-10705
8358         test_mkdir $DIR/$tdir
8359         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
8360         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
8361         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
8362         # Flush writes to ensure valid blocks.  Need to be more thorough for
8363         # ZFS, since blocks are not allocated/returned to client immediately.
8364         sync_all_data
8365         wait_zfs_commit ost1 2
8366         cancel_lru_locks osc
8367         ls -ls $DIR/$tdir
8368
8369         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
8370
8371         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
8372
8373         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
8374         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
8375
8376         rm -f $DIR/$tdir/$tfile.[123]
8377 }
8378 run_test 56ab "lfs find --blocks"
8379
8380 # LU-11188
8381 test_56aca() {
8382         local dir="$DIR/$tdir"
8383         local perms=(001 002 003 004 005 006 007
8384                      010 020 030 040 050 060 070
8385                      100 200 300 400 500 600 700
8386                      111 222 333 444 555 666 777)
8387         local perm_minus=(8 8 4 8 4 4 2
8388                           8 8 4 8 4 4 2
8389                           8 8 4 8 4 4 2
8390                           4 4 2 4 2 2 1)
8391         local perm_slash=(8  8 12  8 12 12 14
8392                           8  8 12  8 12 12 14
8393                           8  8 12  8 12 12 14
8394                          16 16 24 16 24 24 28)
8395
8396         test_mkdir "$dir"
8397         for perm in ${perms[*]}; do
8398                 touch "$dir/$tfile.$perm"
8399                 chmod $perm "$dir/$tfile.$perm"
8400         done
8401
8402         for ((i = 0; i < ${#perms[*]}; i++)); do
8403                 local num=$($LFS find $dir -perm ${perms[i]} | wc -l)
8404                 (( $num == 1 )) ||
8405                         error "lfs find -perm ${perms[i]}:"\
8406                               "$num != 1"
8407
8408                 num=$($LFS find $dir -perm -${perms[i]} -type f| wc -l)
8409                 (( $num == ${perm_minus[i]} )) ||
8410                         error "lfs find -perm -${perms[i]}:"\
8411                               "$num != ${perm_minus[i]}"
8412
8413                 num=$($LFS find $dir -perm /${perms[i]} -type f| wc -l)
8414                 (( $num == ${perm_slash[i]} )) ||
8415                         error "lfs find -perm /${perms[i]}:"\
8416                               "$num != ${perm_slash[i]}"
8417         done
8418 }
8419 run_test 56aca "check lfs find -perm with octal representation"
8420
8421 test_56acb() {
8422         local dir=$DIR/$tdir
8423         # p is the permission of write and execute for user, group and other
8424         # without the umask. It is used to test +wx.
8425         local p=$(printf "%o" "$((0333 & ~$(umask)))")
8426         local perms=(1000 000 2000 4000 $p 644 111 110 100 004)
8427         local symbolic=(+t  a+t u+t g+t o+t
8428                         g+s u+s o+s +s o+sr
8429                         o=r,ug+o,u+w
8430                         u+ g+ o+ a+ ugo+
8431                         u- g- o- a- ugo-
8432                         u= g= o= a= ugo=
8433                         o=r,ug+o,u+w u=r,a+u,u+w
8434                         g=r,ugo=g,u+w u+x,+X +X
8435                         u+x,u+X u+X u+x,g+X o+r,+X
8436                         u+x,go+X +wx +rwx)
8437
8438         test_mkdir $dir
8439         for perm in ${perms[*]}; do
8440                 touch "$dir/$tfile.$perm"
8441                 chmod $perm "$dir/$tfile.$perm"
8442         done
8443
8444         for (( i = 0; i < ${#symbolic[*]}; i++ )); do
8445                 local num=$($LFS find $dir -perm ${symbolic[i]} | wc -l)
8446
8447                 (( $num == 1 )) ||
8448                         error "lfs find $dir -perm ${symbolic[i]}: $num != 1"
8449         done
8450 }
8451 run_test 56acb "check lfs find -perm with symbolic representation"
8452
8453 test_56acc() {
8454         local dir=$DIR/$tdir
8455         local tests="17777 787 789 abcd
8456                 ug=uu ug=a ug=gu uo=ou urw
8457                 u+xg+x a=r,u+x,"
8458
8459         test_mkdir $dir
8460         for err in $tests; do
8461                 if $LFS find $dir -perm $err 2>/dev/null; then
8462                         error "lfs find -perm $err: parsing should have failed"
8463                 fi
8464         done
8465 }
8466 run_test 56acc "check parsing error for lfs find -perm"
8467
8468 test_56ba() {
8469         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
8470                 skip "Need MDS version at least 2.10.50"
8471
8472         # Create composite files with one component
8473         local dir=$DIR/$tdir
8474
8475         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
8476         # Create composite files with three components
8477         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
8478         # Create non-composite files
8479         createmany -o $dir/${tfile}- 10
8480
8481         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
8482
8483         [[ $nfiles == 10 ]] ||
8484                 error "lfs find -E 1M found $nfiles != 10 files"
8485
8486         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
8487         [[ $nfiles == 25 ]] ||
8488                 error "lfs find ! -E 1M found $nfiles != 25 files"
8489
8490         # All files have a component that starts at 0
8491         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
8492         [[ $nfiles == 35 ]] ||
8493                 error "lfs find --component-start 0 - $nfiles != 35 files"
8494
8495         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
8496         [[ $nfiles == 15 ]] ||
8497                 error "lfs find --component-start 2M - $nfiles != 15 files"
8498
8499         # All files created here have a componenet that does not starts at 2M
8500         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
8501         [[ $nfiles == 35 ]] ||
8502                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
8503
8504         # Find files with a specified number of components
8505         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
8506         [[ $nfiles == 15 ]] ||
8507                 error "lfs find --component-count 3 - $nfiles != 15 files"
8508
8509         # Remember non-composite files have a component count of zero
8510         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
8511         [[ $nfiles == 10 ]] ||
8512                 error "lfs find --component-count 0 - $nfiles != 10 files"
8513
8514         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
8515         [[ $nfiles == 20 ]] ||
8516                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
8517
8518         # All files have a flag called "init"
8519         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
8520         [[ $nfiles == 35 ]] ||
8521                 error "lfs find --component-flags init - $nfiles != 35 files"
8522
8523         # Multi-component files will have a component not initialized
8524         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
8525         [[ $nfiles == 15 ]] ||
8526                 error "lfs find !--component-flags init - $nfiles != 15 files"
8527
8528         rm -rf $dir
8529
8530 }
8531 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
8532
8533 test_56ca() {
8534         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
8535                 skip "Need MDS version at least 2.10.57"
8536
8537         local td=$DIR/$tdir
8538         local tf=$td/$tfile
8539         local dir
8540         local nfiles
8541         local cmd
8542         local i
8543         local j
8544
8545         # create mirrored directories and mirrored files
8546         mkdir $td || error "mkdir $td failed"
8547         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
8548         createmany -o $tf- 10 || error "create $tf- failed"
8549
8550         for i in $(seq 2); do
8551                 dir=$td/dir$i
8552                 mkdir $dir || error "mkdir $dir failed"
8553                 $LFS mirror create -N$((3 + i)) $dir ||
8554                         error "create mirrored dir $dir failed"
8555                 createmany -o $dir/$tfile- 10 ||
8556                         error "create $dir/$tfile- failed"
8557         done
8558
8559         # change the states of some mirrored files
8560         echo foo > $tf-6
8561         for i in $(seq 2); do
8562                 dir=$td/dir$i
8563                 for j in $(seq 4 9); do
8564                         echo foo > $dir/$tfile-$j
8565                 done
8566         done
8567
8568         # find mirrored files with specific mirror count
8569         cmd="$LFS find --mirror-count 3 --type f $td"
8570         nfiles=$($cmd | wc -l)
8571         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
8572
8573         cmd="$LFS find ! --mirror-count 3 --type f $td"
8574         nfiles=$($cmd | wc -l)
8575         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
8576
8577         cmd="$LFS find --mirror-count +2 --type f $td"
8578         nfiles=$($cmd | wc -l)
8579         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8580
8581         cmd="$LFS find --mirror-count -6 --type f $td"
8582         nfiles=$($cmd | wc -l)
8583         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8584
8585         # find mirrored files with specific file state
8586         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
8587         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
8588
8589         cmd="$LFS find --mirror-state=ro --type f $td"
8590         nfiles=$($cmd | wc -l)
8591         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
8592
8593         cmd="$LFS find ! --mirror-state=ro --type f $td"
8594         nfiles=$($cmd | wc -l)
8595         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8596
8597         cmd="$LFS find --mirror-state=wp --type f $td"
8598         nfiles=$($cmd | wc -l)
8599         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
8600
8601         cmd="$LFS find ! --mirror-state=sp --type f $td"
8602         nfiles=$($cmd | wc -l)
8603         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
8604 }
8605 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
8606
8607 test_56da() { # LU-14179
8608         local path=$DIR/$tdir
8609
8610         test_mkdir $path
8611         cd $path
8612
8613         local longdir=$(str_repeat 'a' 255)
8614
8615         for i in {1..15}; do
8616                 path=$path/$longdir
8617                 test_mkdir $longdir
8618                 cd $longdir
8619         done
8620
8621         local len=${#path}
8622         local lastdir=$(str_repeat 'a' $((4096 - 1 - $len - 1)))
8623
8624         test_mkdir $lastdir
8625         cd $lastdir
8626         # PATH_MAX-1
8627         (( ${#PWD} == 4095 )) || error "bad PWD length ${#PWD}, expect 4095"
8628
8629         # NAME_MAX
8630         touch $(str_repeat 'f' 255)
8631
8632         $LFS find $DIR/$tdir --type d |& grep "lfs find: error" &&
8633                 error "lfs find reported an error"
8634
8635         rm -rf $DIR/$tdir
8636 }
8637 run_test 56da "test lfs find with long paths"
8638
8639 test_56ea() { #LU-10378
8640         local path=$DIR/$tdir
8641         local pool=$TESTNAME
8642
8643         # Create ost pool
8644         pool_add $pool || error "pool_add $pool failed"
8645         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
8646                 error "adding targets to $pool failed"
8647
8648         # Set default pool on directory before creating file
8649         mkdir $path || error "mkdir $path failed"
8650         $LFS setstripe -p $pool $path ||
8651                 error "set OST pool on $pool failed"
8652         touch $path/$tfile || error "touch $path/$tfile failed"
8653
8654         # Compare basic file attributes from -printf and stat
8655         local attr_printf=$($LFS find $path/$tfile -printf "%A@ %T@ %C@ %U %G")
8656         local attr_stat=$(stat -c "%X %Y %Z %u %g" $path/$tfile)
8657
8658         [[ "${attr_printf}" == "${attr_stat}" ]] ||
8659                 error "Attrs from lfs find and stat don't match"
8660
8661         # Compare Lustre attributes from lfs find and lfs getstripe
8662         local lattr_printf=$($LFS find $path/$tfile -printf "%Lc %LS %Li %Lp")
8663         local str_cnt=$($LFS getstripe --stripe-count $path/$tfile)
8664         local str_size=$($LFS getstripe --stripe-size $path/$tfile)
8665         local str_idx=$($LFS getstripe --stripe-index $path/$tfile)
8666         local fpool=$($LFS getstripe --pool $path/$tfile)
8667         local lattr_getstr="${str_cnt} ${str_size} ${str_idx} ${fpool}"
8668
8669         [[ "${lattr_printf}" == "${lattr_getstr}" ]] ||
8670                 error "Attrs from lfs find and lfs getstripe don't match"
8671
8672         # Verify behavior for unknown escape/format sequences
8673         local esc_printf=$($LFS find $path/$tfile -printf '\\ %% \Q %Q')
8674
8675         [[ "${esc_printf}" == '\ % \Q %Q' ]] ||
8676                 error "Escape/format codes don't match"
8677 }
8678 run_test 56ea "test lfs find -printf option"
8679
8680 test_56eb() {
8681         local dir=$DIR/$tdir
8682         local subdir_1=$dir/subdir_1
8683
8684         test_mkdir -p $subdir_1
8685         ln -s subdir_1 $dir/link_1
8686
8687         $LFS getstripe $dir | grep "^$dir/link_1$" -A1 ||
8688                 error "symlink is not followed"
8689
8690         $LFS getstripe --no-follow $dir |
8691                 grep "^$dir/link_1 has no stripe info$" ||
8692                 error "symlink should not have stripe info"
8693
8694         touch $dir/testfile
8695         ln -s testfile $dir/file_link_2
8696
8697         $LFS getstripe $dir | grep "^$dir/file_link_2$" -A1 ||
8698                 error "symlink is not followed"
8699
8700         $LFS getstripe --no-follow $dir |
8701                 grep "^$dir/file_link_2 has no stripe info$" ||
8702                 error "symlink should not have stripe info"
8703 }
8704 run_test 56eb "check lfs getstripe on symlink"
8705
8706 test_56ec() {
8707         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8708         local dir=$DIR/$tdir
8709         local srcfile=$dir/srcfile
8710         local srcyaml=$dir/srcyaml
8711         local destfile=$dir/destfile
8712
8713         test_mkdir -p $dir
8714
8715         $LFS setstripe -i 1 $srcfile
8716         $LFS getstripe --hex-idx --yaml $srcfile > $srcyaml
8717         # if the setstripe yaml parsing fails for any reason, the command can
8718         # randomly assign the correct OST index, leading to an erroneous
8719         # success. but the chance of false success is low enough that a
8720         # regression should still be quickly caught.
8721         $LFS setstripe --yaml=$srcyaml $destfile
8722
8723         local srcindex=$($LFS getstripe -i $srcfile)
8724         local destindex=$($LFS getstripe -i $destfile)
8725
8726         if [[ ! $srcindex -eq $destindex ]]; then
8727                 error "setstripe did not set OST index correctly"
8728         fi
8729 }
8730 run_test 56ec "check lfs getstripe,setstripe --hex --yaml"
8731
8732 test_57a() {
8733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8734         # note test will not do anything if MDS is not local
8735         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8736                 skip_env "ldiskfs only test"
8737         fi
8738         remote_mds_nodsh && skip "remote MDS with nodsh"
8739
8740         local MNTDEV="osd*.*MDT*.mntdev"
8741         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
8742         [ -z "$DEV" ] && error "can't access $MNTDEV"
8743         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
8744                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
8745                         error "can't access $DEV"
8746                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
8747                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
8748                 rm $TMP/t57a.dump
8749         done
8750 }
8751 run_test 57a "verify MDS filesystem created with large inodes =="
8752
8753 test_57b() {
8754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8755         if [ "$mds1_FSTYPE" != ldiskfs ]; then
8756                 skip_env "ldiskfs only test"
8757         fi
8758         remote_mds_nodsh && skip "remote MDS with nodsh"
8759
8760         local dir=$DIR/$tdir
8761         local filecount=100
8762         local file1=$dir/f1
8763         local fileN=$dir/f$filecount
8764
8765         rm -rf $dir || error "removing $dir"
8766         test_mkdir -c1 $dir
8767         local mdtidx=$($LFS getstripe -m $dir)
8768         local mdtname=MDT$(printf %04x $mdtidx)
8769         local facet=mds$((mdtidx + 1))
8770
8771         echo "mcreating $filecount files"
8772         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
8773
8774         # verify that files do not have EAs yet
8775         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
8776                 error "$file1 has an EA"
8777         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
8778                 error "$fileN has an EA"
8779
8780         sync
8781         sleep 1
8782         df $dir  #make sure we get new statfs data
8783         local mdsfree=$(do_facet $facet \
8784                         lctl get_param -n osd*.*$mdtname.kbytesfree)
8785         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8786         local file
8787
8788         echo "opening files to create objects/EAs"
8789         for file in $(seq -f $dir/f%g 1 $filecount); do
8790                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
8791                         error "opening $file"
8792         done
8793
8794         # verify that files have EAs now
8795         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
8796         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
8797
8798         sleep 1  #make sure we get new statfs data
8799         df $dir
8800         local mdsfree2=$(do_facet $facet \
8801                          lctl get_param -n osd*.*$mdtname.kbytesfree)
8802         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
8803
8804         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
8805                 if [ "$mdsfree" != "$mdsfree2" ]; then
8806                         error "MDC before $mdcfree != after $mdcfree2"
8807                 else
8808                         echo "MDC before $mdcfree != after $mdcfree2"
8809                         echo "unable to confirm if MDS has large inodes"
8810                 fi
8811         fi
8812         rm -rf $dir
8813 }
8814 run_test 57b "default LOV EAs are stored inside large inodes ==="
8815
8816 test_58() {
8817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8818         [ -z "$(which wiretest 2>/dev/null)" ] &&
8819                         skip_env "could not find wiretest"
8820
8821         wiretest
8822 }
8823 run_test 58 "verify cross-platform wire constants =============="
8824
8825 test_59() {
8826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8827
8828         echo "touch 130 files"
8829         createmany -o $DIR/f59- 130
8830         echo "rm 130 files"
8831         unlinkmany $DIR/f59- 130
8832         sync
8833         # wait for commitment of removal
8834         wait_delete_completed
8835 }
8836 run_test 59 "verify cancellation of llog records async ========="
8837
8838 TEST60_HEAD="test_60 run $RANDOM"
8839 test_60a() {
8840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8841         remote_mgs_nodsh && skip "remote MGS with nodsh"
8842         do_facet mgs "! which run-llog.sh &> /dev/null" &&
8843                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
8844                         skip_env "missing subtest run-llog.sh"
8845
8846         log "$TEST60_HEAD - from kernel mode"
8847         do_facet mgs "$LCTL dk > /dev/null"
8848         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
8849         do_facet mgs $LCTL dk > $TMP/$tfile
8850
8851         # LU-6388: test llog_reader
8852         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
8853         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
8854         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
8855                         skip_env "missing llog_reader"
8856         local fstype=$(facet_fstype mgs)
8857         [ $fstype != ldiskfs -a $fstype != zfs ] &&
8858                 skip_env "Only for ldiskfs or zfs type mgs"
8859
8860         local mntpt=$(facet_mntpt mgs)
8861         local mgsdev=$(mgsdevname 1)
8862         local fid_list
8863         local fid
8864         local rec_list
8865         local rec
8866         local rec_type
8867         local obj_file
8868         local path
8869         local seq
8870         local oid
8871         local pass=true
8872
8873         #get fid and record list
8874         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
8875                 tail -n 4))
8876         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
8877                 tail -n 4))
8878         #remount mgs as ldiskfs or zfs type
8879         stop mgs || error "stop mgs failed"
8880         mount_fstype mgs || error "remount mgs failed"
8881         for ((i = 0; i < ${#fid_list[@]}; i++)); do
8882                 fid=${fid_list[i]}
8883                 rec=${rec_list[i]}
8884                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
8885                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
8886                 oid=$((16#$oid))
8887
8888                 case $fstype in
8889                         ldiskfs )
8890                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
8891                         zfs )
8892                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
8893                 esac
8894                 echo "obj_file is $obj_file"
8895                 do_facet mgs $llog_reader $obj_file
8896
8897                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
8898                         awk '{ print $3 }' | sed -e "s/^type=//g")
8899                 if [ $rec_type != $rec ]; then
8900                         echo "FAILED test_60a wrong record type $rec_type," \
8901                               "should be $rec"
8902                         pass=false
8903                         break
8904                 fi
8905
8906                 #check obj path if record type is LLOG_LOGID_MAGIC
8907                 if [ "$rec" == "1064553b" ]; then
8908                         path=$(do_facet mgs $llog_reader $obj_file |
8909                                 grep "path=" | awk '{ print $NF }' |
8910                                 sed -e "s/^path=//g")
8911                         if [ $obj_file != $mntpt/$path ]; then
8912                                 echo "FAILED test_60a wrong obj path" \
8913                                       "$montpt/$path, should be $obj_file"
8914                                 pass=false
8915                                 break
8916                         fi
8917                 fi
8918         done
8919         rm -f $TMP/$tfile
8920         #restart mgs before "error", otherwise it will block the next test
8921         stop mgs || error "stop mgs failed"
8922         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
8923         $pass || error "test failed, see FAILED test_60a messages for specifics"
8924 }
8925 run_test 60a "llog_test run from kernel module and test llog_reader"
8926
8927 test_60b() { # bug 6411
8928         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8929
8930         dmesg > $DIR/$tfile
8931         LLOG_COUNT=$(do_facet mgs dmesg |
8932                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
8933                           /llog_[a-z]*.c:[0-9]/ {
8934                                 if (marker)
8935                                         from_marker++
8936                                 from_begin++
8937                           }
8938                           END {
8939                                 if (marker)
8940                                         print from_marker
8941                                 else
8942                                         print from_begin
8943                           }")
8944
8945         [[ $LLOG_COUNT -gt 120 ]] &&
8946                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
8947 }
8948 run_test 60b "limit repeated messages from CERROR/CWARN"
8949
8950 test_60c() {
8951         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8952
8953         echo "create 5000 files"
8954         createmany -o $DIR/f60c- 5000
8955 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
8956         lctl set_param fail_loc=0x80000137
8957         unlinkmany $DIR/f60c- 5000
8958         lctl set_param fail_loc=0
8959 }
8960 run_test 60c "unlink file when mds full"
8961
8962 test_60d() {
8963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8964
8965         SAVEPRINTK=$(lctl get_param -n printk)
8966         # verify "lctl mark" is even working"
8967         MESSAGE="test message ID $RANDOM $$"
8968         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8969         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
8970
8971         lctl set_param printk=0 || error "set lnet.printk failed"
8972         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
8973         MESSAGE="new test message ID $RANDOM $$"
8974         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
8975         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
8976         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
8977
8978         lctl set_param -n printk="$SAVEPRINTK"
8979 }
8980 run_test 60d "test printk console message masking"
8981
8982 test_60e() {
8983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8984         remote_mds_nodsh && skip "remote MDS with nodsh"
8985
8986         touch $DIR/$tfile
8987 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
8988         do_facet mds1 lctl set_param fail_loc=0x15b
8989         rm $DIR/$tfile
8990 }
8991 run_test 60e "no space while new llog is being created"
8992
8993 test_60f() {
8994         local old_path=$($LCTL get_param -n debug_path)
8995
8996         stack_trap "$LCTL set_param debug_path=$old_path"
8997         stack_trap "rm -f $TMP/$tfile*"
8998         rm -f $TMP/$tfile* 2> /dev/null
8999         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
9000         $LCTL set_param debug_path=$TMP/$tfile fail_loc=0x8000050e
9001         test_mkdir $DIR/$tdir
9002         # retry in case the open is cached and not released
9003         for (( i = 0; i < 100 && $(ls $TMP/$tfile* | wc -l) == 0; i++ )); do
9004                 echo $i > $DIR/$tdir/$tfile.$i && cat $DIR/$tdir/$tfile.$i
9005                 sleep 0.1
9006         done
9007         ls $TMP/$tfile*
9008         (( $(ls $TMP/$tfile* | wc -l) > 0 )) || error "$TMP/$tfile not dumped"
9009 }
9010 run_test 60f "change debug_path works"
9011
9012 test_60g() {
9013         local pid
9014         local i
9015
9016         test_mkdir -c $MDSCOUNT $DIR/$tdir
9017
9018         (
9019                 local index=0
9020                 while true; do
9021                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
9022                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
9023                                 2>/dev/null
9024                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
9025                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
9026                         index=$((index + 1))
9027                 done
9028         ) &
9029
9030         pid=$!
9031
9032         for i in {0..100}; do
9033                 # define OBD_FAIL_OSD_TXN_START    0x19a
9034                 local index=$((i % MDSCOUNT + 1))
9035
9036                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
9037                         > /dev/null
9038                 sleep 0.01
9039         done
9040
9041         kill -9 $pid
9042
9043         for i in $(seq $MDSCOUNT); do
9044                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
9045         done
9046
9047         mkdir $DIR/$tdir/new || error "mkdir failed"
9048         rmdir $DIR/$tdir/new || error "rmdir failed"
9049
9050         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
9051                 -t namespace
9052         for i in $(seq $MDSCOUNT); do
9053                 wait_update_facet mds$i "$LCTL get_param -n \
9054                         mdd.$(facet_svc mds$i).lfsck_namespace |
9055                         awk '/^status/ { print \\\$2 }'" "completed"
9056         done
9057
9058         ls -R $DIR/$tdir
9059         rm -rf $DIR/$tdir || error "rmdir failed"
9060 }
9061 run_test 60g "transaction abort won't cause MDT hung"
9062
9063 test_60h() {
9064         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
9065                 skip "Need MDS version at least 2.12.52"
9066         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
9067
9068         local f
9069
9070         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
9071         #define OBD_FAIL_MDS_STRIPE_FID          0x189
9072         for fail_loc in 0x80000188 0x80000189; do
9073                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
9074                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
9075                         error "mkdir $dir-$fail_loc failed"
9076                 for i in {0..10}; do
9077                         # create may fail on missing stripe
9078                         echo $i > $DIR/$tdir-$fail_loc/$i
9079                 done
9080                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9081                         error "getdirstripe $tdir-$fail_loc failed"
9082                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
9083                         error "migrate $tdir-$fail_loc failed"
9084                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
9085                         error "getdirstripe $tdir-$fail_loc failed"
9086                 pushd $DIR/$tdir-$fail_loc
9087                 for f in *; do
9088                         echo $f | cmp $f - || error "$f data mismatch"
9089                 done
9090                 popd
9091                 rm -rf $DIR/$tdir-$fail_loc
9092         done
9093 }
9094 run_test 60h "striped directory with missing stripes can be accessed"
9095
9096 function t60i_load() {
9097         mkdir $DIR/$tdir
9098         #define OBD_FAIL_LLOG_PAUSE_AFTER_PAD               0x131c
9099         $LCTL set_param fail_loc=0x131c fail_val=1
9100         for ((i=0; i<5000; i++)); do
9101                 touch $DIR/$tdir/f$i
9102         done
9103 }
9104
9105 test_60i() {
9106         changelog_register || error "changelog_register failed"
9107         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
9108         changelog_users $SINGLEMDS | grep -q $cl_user ||
9109                 error "User $cl_user not found in changelog_users"
9110         changelog_chmask "ALL"
9111         t60i_load &
9112         local PID=$!
9113         for((i=0; i<100; i++)); do
9114                 changelog_dump >/dev/null ||
9115                         error "can't read changelog"
9116         done
9117         kill $PID
9118         wait $PID
9119         changelog_deregister || error "changelog_deregister failed"
9120         $LCTL set_param fail_loc=0
9121 }
9122 run_test 60i "llog: new record vs reader race"
9123
9124 test_60j() {
9125         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
9126                 skip "need MDS version at least 2.15.50"
9127         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9128         remote_mds_nodsh && skip "remote MDS with nodsh"
9129         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
9130
9131         changelog_users $SINGLEMDS | grep "^cl" &&
9132                 skip "active changelog user"
9133
9134         local llog_reader=$(do_facet $SINGLEMDS "which llog_reader 2> /dev/null")
9135
9136         [[ -z $(do_facet $SINGLEMDS ls -d $llog_reader 2> /dev/null) ]] &&
9137                 skip_env "missing llog_reader"
9138
9139         mkdir_on_mdt0 $DIR/$tdir
9140
9141         local f=$DIR/$tdir/$tfile
9142         local mdt_dev
9143         local tmpfile
9144         local plain
9145
9146         changelog_register || error "cannot register changelog user"
9147
9148         # set changelog_mask to ALL
9149         changelog_chmask "ALL"
9150         changelog_clear
9151
9152         createmany -o ${f}- 100 || error "createmany failed as $RUNAS_ID"
9153         unlinkmany ${f}- 100 || error "unlinkmany failed"
9154
9155         tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
9156         mdt_dev=$(facet_device $SINGLEMDS)
9157
9158         do_facet $SINGLEMDS sync
9159         plain=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump changelog_catalog \
9160                 $tmpfile' $mdt_dev; $llog_reader $tmpfile" |
9161                 awk '{match($0,"path=([^ ]+)",a)}END{print a[1]}')
9162
9163         stack_trap "do_facet $SINGLEMDS rm -f $tmpfile"
9164
9165         # if $tmpfile is not on EXT3 filesystem for some reason
9166         [[ ${plain:0:1} == 'O' ]] ||
9167                 skip "path $plain is not in 'O/1/d<n>/<n>' format"
9168
9169         size=$(do_facet $SINGLEMDS "$DEBUGFS -c -R 'dump $plain $tmpfile' \
9170                 $mdt_dev; stat -c %s $tmpfile")
9171         echo "Truncate llog from $size to $((size - size % 8192))"
9172         size=$((size - size % 8192))
9173         do_facet $SINGLEMDS $TRUNCATE $tmpfile $size
9174         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9175                 grep -c 'in bitmap only')
9176         (( $errs > 0 )) || error "llog_reader didn't find lost records"
9177
9178         size=$((size - 9000))
9179         echo "Corrupt llog in the middle at $size"
9180         do_facet $SINGLEMDS dd if=/dev/urandom of=$tmpfile bs=1 seek=$size \
9181                 count=333 conv=notrunc
9182         errs=$(do_facet $SINGLEMDS "$llog_reader $tmpfile" |
9183                 grep -c 'next chunk')
9184         (( $errs > 0 )) || error "llog_reader didn't skip bad chunk"
9185 }
9186 run_test 60j "llog_reader reports corruptions"
9187
9188 test_61a() {
9189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9190
9191         f="$DIR/f61"
9192         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
9193         cancel_lru_locks osc
9194         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
9195         sync
9196 }
9197 run_test 61a "mmap() writes don't make sync hang ================"
9198
9199 test_61b() {
9200         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
9201 }
9202 run_test 61b "mmap() of unstriped file is successful"
9203
9204 # bug 2330 - insufficient obd_match error checking causes LBUG
9205 test_62() {
9206         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9207
9208         f="$DIR/f62"
9209         echo foo > $f
9210         cancel_lru_locks osc
9211         lctl set_param fail_loc=0x405
9212         cat $f && error "cat succeeded, expect -EIO"
9213         lctl set_param fail_loc=0
9214 }
9215 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
9216 # match every page all of the time.
9217 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
9218
9219 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
9220 # Though this test is irrelevant anymore, it helped to reveal some
9221 # other grant bugs (LU-4482), let's keep it.
9222 test_63a() {   # was test_63
9223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9224
9225         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
9226
9227         for i in `seq 10` ; do
9228                 dd if=/dev/zero of=$DIR/f63 bs=8k &
9229                 sleep 5
9230                 kill $!
9231                 sleep 1
9232         done
9233
9234         rm -f $DIR/f63 || true
9235 }
9236 run_test 63a "Verify oig_wait interruption does not crash ======="
9237
9238 # bug 2248 - async write errors didn't return to application on sync
9239 # bug 3677 - async write errors left page locked
9240 test_63b() {
9241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9242
9243         debugsave
9244         lctl set_param debug=-1
9245
9246         # ensure we have a grant to do async writes
9247         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
9248         rm $DIR/$tfile
9249
9250         sync    # sync lest earlier test intercept the fail_loc
9251
9252         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9253         lctl set_param fail_loc=0x80000406
9254         $MULTIOP $DIR/$tfile Owy && \
9255                 error "sync didn't return ENOMEM"
9256         sync; sleep 2; sync     # do a real sync this time to flush page
9257         lctl get_param -n llite.*.dump_page_cache | grep locked && \
9258                 error "locked page left in cache after async error" || true
9259         debugrestore
9260 }
9261 run_test 63b "async write errors should be returned to fsync ==="
9262
9263 test_64a () {
9264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9265
9266         lfs df $DIR
9267         lctl get_param osc.*[oO][sS][cC][_-]*.cur* | grep "=[1-9]"
9268 }
9269 run_test 64a "verify filter grant calculations (in kernel) ====="
9270
9271 test_64b () {
9272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9273
9274         bash oos.sh $MOUNT || error "oos.sh failed: $?"
9275 }
9276 run_test 64b "check out-of-space detection on client"
9277
9278 test_64c() {
9279         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
9280 }
9281 run_test 64c "verify grant shrink"
9282
9283 import_param() {
9284         local tgt=$1
9285         local param=$2
9286
9287         $LCTL get_param osc.$tgt.import | awk "/$param/ { print \$2 }"
9288 }
9289
9290 # this does exactly what osc_request.c:osc_announce_cached() does in
9291 # order to calculate max amount of grants to ask from server
9292 want_grant() {
9293         local tgt=$1
9294
9295         local nrpages=$($LCTL get_param -n osc.$tgt.max_pages_per_rpc)
9296         local rpc_in_flight=$($LCTL get_param -n osc.$tgt.max_rpcs_in_flight)
9297
9298         ((rpc_in_flight++));
9299         nrpages=$((nrpages * rpc_in_flight))
9300
9301         local dirty_max_pages=$($LCTL get_param -n osc.$tgt.max_dirty_mb)
9302
9303         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
9304
9305         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
9306         local undirty=$((nrpages * PAGE_SIZE))
9307
9308         local max_extent_pages
9309         max_extent_pages=$(import_param $tgt grant_max_extent_size)
9310         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
9311         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
9312         local grant_extent_tax
9313         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9314
9315         undirty=$((undirty + nrextents * grant_extent_tax))
9316
9317         echo $undirty
9318 }
9319
9320 # this is size of unit for grant allocation. It should be equal to
9321 # what tgt_grant.c:tgt_grant_chunk() calculates
9322 grant_chunk() {
9323         local tgt=$1
9324         local max_brw_size
9325         local grant_extent_tax
9326
9327         max_brw_size=$(import_param $tgt max_brw_size)
9328
9329         grant_extent_tax=$(import_param $tgt grant_extent_tax)
9330
9331         echo $(((max_brw_size + grant_extent_tax) * 2))
9332 }
9333
9334 test_64d() {
9335         [ $OST1_VERSION -ge $(version_code 2.10.56) ] ||
9336                 skip "OST < 2.10.55 doesn't limit grants enough"
9337
9338         local tgt=$($LCTL dl | awk '/OST0000-osc-[^mM]/ { print $4 }')
9339
9340         [[ "$($LCTL get_param osc.${tgt}.import)" =~ "grant_param" ]] ||
9341                 skip "no grant_param connect flag"
9342
9343         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9344
9345         $LCTL set_param -n -n debug="$OLDDEBUG" || true
9346         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9347
9348
9349         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
9350         stack_trap "rm -f $DIR/$tfile && wait_delete_completed" EXIT
9351
9352         $LFS setstripe $DIR/$tfile -i 0 -c 1
9353         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1000 &
9354         ddpid=$!
9355
9356         while kill -0 $ddpid; do
9357                 local cur_grant=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9358
9359                 if [[ $cur_grant -gt $max_cur_granted ]]; then
9360                         kill $ddpid
9361                         error "cur_grant $cur_grant > $max_cur_granted"
9362                 fi
9363
9364                 sleep 1
9365         done
9366 }
9367 run_test 64d "check grant limit exceed"
9368
9369 check_grants() {
9370         local tgt=$1
9371         local expected=$2
9372         local msg=$3
9373         local cur_grants=$($LCTL get_param -n osc.$tgt.cur_grant_bytes)
9374
9375         ((cur_grants == expected)) ||
9376                 error "$msg: grants mismatch: $cur_grants, expected $expected"
9377 }
9378
9379 round_up_p2() {
9380         echo $((($1 + $2 - 1) & ~($2 - 1)))
9381 }
9382
9383 test_64e() {
9384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9385         [ $OST1_VERSION -ge $(version_code 2.11.56) ] ||
9386                 skip "Need OSS version at least 2.11.56"
9387
9388         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9389         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9390         $LCTL set_param debug=+cache
9391
9392         # Remount client to reset grant
9393         remount_client $MOUNT || error "failed to remount client"
9394         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9395
9396         local init_grants=$(import_param $osc_tgt initial_grant)
9397
9398         check_grants $osc_tgt $init_grants "init grants"
9399
9400         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9401         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9402         local gbs=$(import_param $osc_tgt grant_block_size)
9403
9404         # write random number of bytes from max_brw_size / 4 to max_brw_size
9405         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9406         # align for direct io
9407         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9408         # round to grant consumption unit
9409         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9410
9411         local grants=$((wb_round_up + extent_tax))
9412
9413         $LFS setstripe -c 1 -i 0 $DIR/$tfile  || error "lfs setstripe failed"
9414
9415         # define OBD_FAIL_TGT_NO_GRANT 0x725
9416         # make the server not grant more back
9417         do_facet ost1 $LCTL set_param fail_loc=0x725
9418         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct
9419
9420         do_facet ost1 $LCTL set_param fail_loc=0
9421
9422         check_grants $osc_tgt $((init_grants - grants)) "dio w/o grant alloc"
9423
9424         rm -f $DIR/$tfile || error "rm failed"
9425
9426         # Remount client to reset grant
9427         remount_client $MOUNT || error "failed to remount client"
9428         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9429
9430         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9431
9432         # define OBD_FAIL_TGT_NO_GRANT 0x725
9433         # make the server not grant more back
9434         do_facet ost1 $LCTL set_param fail_loc=0x725
9435         $MULTIOP $DIR/$tfile "oO_WRONLY:w${write_bytes}yc"
9436         do_facet ost1 $LCTL set_param fail_loc=0
9437
9438         check_grants $osc_tgt $((init_grants - grants)) "buf io w/o grant alloc"
9439 }
9440 run_test 64e "check grant consumption (no grant allocation)"
9441
9442 test_64f() {
9443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9444
9445         local olddebug="$($LCTL get_param -n debug 2> /dev/null)"
9446         stack_trap "$LCTL set_param -n debug='$olddebug'" EXIT
9447         $LCTL set_param debug=+cache
9448
9449         # Remount client to reset grant
9450         remount_client $MOUNT || error "failed to remount client"
9451         local osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9452
9453         local init_grants=$(import_param $osc_tgt initial_grant)
9454         local extent_tax=$(import_param $osc_tgt grant_extent_tax)
9455         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9456         local gbs=$(import_param $osc_tgt grant_block_size)
9457         local chunk=$(grant_chunk $osc_tgt)
9458
9459         # write random number of bytes from max_brw_size / 4 to max_brw_size
9460         local write_bytes=$(shuf -i $((max_brw_size / 4))-$max_brw_size -n 1)
9461         # align for direct io
9462         write_bytes=$(round_up_p2 $write_bytes PAGE_SIZE)
9463         # round to grant consumption unit
9464         local wb_round_up=$(round_up_p2 $write_bytes gbs)
9465
9466         local grants=$((wb_round_up + extent_tax))
9467
9468         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9469         dd if=/dev/zero of=$DIR/$tfile bs=$write_bytes count=1 oflag=direct ||
9470                 error "error writing to $DIR/$tfile"
9471
9472         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9473                 "direct io with grant allocation"
9474
9475         rm -f $DIR/$tfile || error "rm failed"
9476
9477         # Remount client to reset grant
9478         remount_client $MOUNT || error "failed to remount client"
9479         osc_tgt="$FSNAME-OST0000-osc-$($LFS getname -i $DIR)"
9480
9481         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "lfs setstripe failed"
9482
9483         local cmd="oO_WRONLY:w${write_bytes}_yc"
9484
9485         $MULTIOP $DIR/$tfile $cmd &
9486         MULTIPID=$!
9487         sleep 1
9488
9489         check_grants $osc_tgt $((init_grants - grants)) \
9490                 "buffered io, not write rpc"
9491
9492         kill -USR1 $MULTIPID
9493         wait
9494
9495         check_grants $osc_tgt $((init_grants - grants + chunk)) \
9496                 "buffered io, one RPC"
9497 }
9498 run_test 64f "check grant consumption (with grant allocation)"
9499
9500 test_64g() {
9501         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
9502                 skip "Need MDS version at least 2.14.56"
9503
9504         local mdts=$(comma_list $(mdts_nodes))
9505
9506         local old=$($LCTL get_param mdc.$FSNAME-*.grant_shrink_interval |
9507                         tr '\n' ' ')
9508         stack_trap "$LCTL set_param $old"
9509
9510         # generate dirty pages and increase dirty granted on MDT
9511         stack_trap "rm -f $DIR/$tfile-*"
9512         for (( i = 0; i < 10; i++)); do
9513                 $LFS setstripe -E 1M -L mdt $DIR/$tfile-$i ||
9514                         error "can't set stripe"
9515                 dd if=/dev/zero of=$DIR/$tfile-$i bs=128k count=1 ||
9516                         error "can't dd"
9517                 $LFS getstripe $DIR/$tfile-$i | grep -q pattern.*mdt || {
9518                         $LFS getstripe $DIR/$tfile-$i
9519                         error "not DoM file"
9520                 }
9521         done
9522
9523         # flush dirty pages
9524         sync
9525
9526         # wait until grant shrink reset grant dirty on MDTs
9527         for ((i = 0; i < 120; i++)); do
9528                 grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9529                         awk '{sum=sum+$1} END {print sum}')
9530                 vm_dirty=$(awk '/Dirty:/{print $2}' /proc/meminfo)
9531                 echo "$grant_dirty grants, $vm_dirty pages"
9532                 (( grant_dirty + vm_dirty == 0 )) && break
9533                 (( i == 3 )) && sync &&
9534                         $LCTL set_param mdc.$FSNAME-*.grant_shrink_interval=5
9535                 sleep 1
9536         done
9537
9538         grant_dirty=$(do_nodes $mdts $LCTL get_param -n  mdt.*.tot_dirty |
9539                 awk '{sum=sum+$1} END {print sum}')
9540         (( grant_dirty == 0 )) || error "$grant_dirty on MDT"
9541 }
9542 run_test 64g "grant shrink on MDT"
9543
9544 test_64h() {
9545         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9546                 skip "need OST at least 2.14.56 to avoid grant shrink on read"
9547
9548         local instance=$($LFS getname -i $DIR)
9549         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9550         local num_exps=$(do_facet ost1 \
9551             $LCTL get_param -n obdfilter.*OST0000*.num_exports)
9552         local max_brw_size=$(import_param $osc_tgt max_brw_size)
9553         local avail=$($LCTL get_param -n osc.*OST0000-osc-$instance.kbytesavail)
9554         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
9555
9556         # 10MiB is for file to be written, max_brw_size * 16 *
9557         # num_exps is space reserve so that tgt_grant_shrink() decided
9558         # to not shrink
9559         local expect=$((max_brw_size * 16 * num_exps + 10 * 1048576))
9560         (( avail * 1024 < expect )) &&
9561                 skip "need $expect bytes on ost1, have $(( avail * 1024 )) only"
9562
9563         save_lustre_params client "osc.*OST0000*.grant_shrink" > $p
9564         save_lustre_params client "osc.*OST0000*.grant_shrink_interval" >> $p
9565         stack_trap "restore_lustre_params < $p; rm -f $save" EXIT
9566         $LCTL set_param osc.*OST0000*.grant_shrink=1
9567         $LCTL set_param osc.*OST0000*.grant_shrink_interval=10
9568
9569         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9570         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 oflag=sync
9571
9572         # drop cache so that coming read would do rpc
9573         cancel_lru_locks osc
9574
9575         # shrink interval is set to 10, pause for 7 seconds so that
9576         # grant thread did not wake up yet but coming read entered
9577         # shrink mode for rpc (osc_should_shrink_grant())
9578         sleep 7
9579
9580         declare -a cur_grant_bytes
9581         declare -a tot_granted
9582         cur_grant_bytes[0]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9583         tot_granted[0]=$(do_facet ost1 \
9584             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9585
9586         dd if=$DIR/$tfile bs=4K count=1 of=/dev/null
9587
9588         cur_grant_bytes[1]=$($LCTL get_param -n osc.*OST0000*.cur_grant_bytes)
9589         tot_granted[1]=$(do_facet ost1 \
9590             $LCTL get_param -n obdfilter.*OST0000*.tot_granted)
9591
9592         # grant change should be equal on both sides
9593         (( cur_grant_bytes[0] - cur_grant_bytes[1] ==
9594                 tot_granted[0] - tot_granted[1])) ||
9595                 error "grant change mismatch, "                                \
9596                         "server: ${tot_granted[0]} to ${tot_granted[1]}, "     \
9597                         "client: ${cur_grant_bytes[0]} to ${cur_grant_bytes[1]}"
9598 }
9599 run_test 64h "grant shrink on read"
9600
9601 test_64i() {
9602         (( $OST1_VERSION >= $(version_code 2.14.56) )) ||
9603                 skip "need OST at least 2.14.56 to avoid grant shrink on replay"
9604
9605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9606         remote_ost_nodsh && skip "remote OSTs with nodsh"
9607
9608         $LFS setstripe -c 1 -i 0 $DIR/$tfile
9609
9610         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
9611
9612         # lustre-ffff9fc75e850800 /mnt/lustre -> ffff9fc75e850800
9613         local instance=$($LFS getname -i $DIR)
9614
9615         local osc_tgt="$FSNAME-OST0000-osc-$instance"
9616         local cgb=$($LCTL get_param -n osc.$osc_tgt.cur_grant_bytes)
9617
9618         # shrink grants and simulate rpc loss
9619         #define OBD_FAIL_PTLRPC_DROP_REQ_OPC     0x513
9620         do_facet ost1 "$LCTL set_param fail_loc=0x80000513 fail_val=17"
9621         $LCTL set_param osc.$osc_tgt.cur_grant_bytes=$((cgb/2))B
9622
9623         fail ost1
9624
9625         dd if=/dev/zero of=$DIR/$tfile oflag=append bs=1M count=8 conv=notrunc
9626
9627         local testid=$(echo $TESTNAME | tr '_' ' ')
9628
9629         do_facet ost1 dmesg | tac | sed "/$testid/,$ d" |
9630                 grep "GRANT, real grant" &&
9631                 error "client has more grants then it owns" || true
9632 }
9633 run_test 64i "shrink on reconnect"
9634
9635 # bug 1414 - set/get directories' stripe info
9636 test_65a() {
9637         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9638
9639         test_mkdir $DIR/$tdir
9640         touch $DIR/$tdir/f1
9641         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
9642 }
9643 run_test 65a "directory with no stripe info"
9644
9645 test_65b() {
9646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9647
9648         test_mkdir $DIR/$tdir
9649         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9650
9651         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9652                                                 error "setstripe"
9653         touch $DIR/$tdir/f2
9654         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
9655 }
9656 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
9657
9658 test_65c() {
9659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9660         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
9661
9662         test_mkdir $DIR/$tdir
9663         local stripesize=$($LFS getstripe -S $DIR/$tdir)
9664
9665         $LFS setstripe -S $((stripesize * 4)) -i 1 \
9666                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
9667         touch $DIR/$tdir/f3
9668         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
9669 }
9670 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
9671
9672 test_65d() {
9673         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9674
9675         test_mkdir $DIR/$tdir
9676         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
9677         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9678
9679         if [[ $STRIPECOUNT -le 0 ]]; then
9680                 sc=1
9681         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
9682                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
9683                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
9684         else
9685                 sc=$(($STRIPECOUNT - 1))
9686         fi
9687         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
9688         touch $DIR/$tdir/f4 $DIR/$tdir/f5
9689         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
9690                 error "lverify failed"
9691 }
9692 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
9693
9694 test_65e() {
9695         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9696
9697         test_mkdir $DIR/$tdir
9698
9699         $LFS setstripe $DIR/$tdir || error "setstripe"
9700         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9701                                         error "no stripe info failed"
9702         touch $DIR/$tdir/f6
9703         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
9704 }
9705 run_test 65e "directory setstripe defaults"
9706
9707 test_65f() {
9708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9709
9710         test_mkdir $DIR/${tdir}f
9711         $RUNAS $LFS setstripe $DIR/${tdir}f &&
9712                 error "setstripe succeeded" || true
9713 }
9714 run_test 65f "dir setstripe permission (should return error) ==="
9715
9716 test_65g() {
9717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9718
9719         test_mkdir $DIR/$tdir
9720         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9721
9722         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9723                 error "setstripe -S failed"
9724         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
9725         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
9726                 error "delete default stripe failed"
9727 }
9728 run_test 65g "directory setstripe -d"
9729
9730 test_65h() {
9731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9732
9733         test_mkdir $DIR/$tdir
9734         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
9735
9736         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
9737                 error "setstripe -S failed"
9738         test_mkdir $DIR/$tdir/dd1
9739         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
9740                 error "stripe info inherit failed"
9741 }
9742 run_test 65h "directory stripe info inherit ===================="
9743
9744 test_65i() {
9745         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9746
9747         save_layout_restore_at_exit $MOUNT
9748
9749         # bug6367: set non-default striping on root directory
9750         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
9751
9752         # bug12836: getstripe on -1 default directory striping
9753         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
9754
9755         # bug12836: getstripe -v on -1 default directory striping
9756         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
9757
9758         # bug12836: new find on -1 default directory striping
9759         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
9760 }
9761 run_test 65i "various tests to set root directory striping"
9762
9763 test_65j() { # bug6367
9764         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9765
9766         sync; sleep 1
9767
9768         # if we aren't already remounting for each test, do so for this test
9769         if [ "$I_MOUNTED" = "yes" ]; then
9770                 cleanup || error "failed to unmount"
9771                 setup
9772         fi
9773
9774         save_layout_restore_at_exit $MOUNT
9775
9776         $LFS setstripe -d $MOUNT || error "setstripe failed"
9777 }
9778 run_test 65j "set default striping on root directory (bug 6367)="
9779
9780 cleanup_65k() {
9781         rm -rf $DIR/$tdir
9782         wait_delete_completed
9783         do_facet $SINGLEMDS "lctl set_param -n \
9784                 osp.$ost*MDT0000.max_create_count=$max_count"
9785         do_facet $SINGLEMDS "lctl set_param -n \
9786                 osp.$ost*MDT0000.create_count=$count"
9787         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9788         echo $INACTIVE_OSC "is Activate"
9789
9790         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9791 }
9792
9793 test_65k() { # bug11679
9794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9795         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9796         remote_mds_nodsh && skip "remote MDS with nodsh"
9797
9798         local disable_precreate=true
9799         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
9800                 disable_precreate=false
9801
9802         echo "Check OST status: "
9803         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
9804                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
9805
9806         for OSC in $MDS_OSCS; do
9807                 echo $OSC "is active"
9808                 do_facet $SINGLEMDS lctl --device %$OSC activate
9809         done
9810
9811         for INACTIVE_OSC in $MDS_OSCS; do
9812                 local ost=$(osc_to_ost $INACTIVE_OSC)
9813                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
9814                                lov.*md*.target_obd |
9815                                awk -F: /$ost/'{ print $1 }' | head -n 1)
9816
9817                 mkdir -p $DIR/$tdir
9818                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
9819                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
9820
9821                 echo "Deactivate: " $INACTIVE_OSC
9822                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
9823
9824                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
9825                               osp.$ost*MDT0000.create_count")
9826                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
9827                                   osp.$ost*MDT0000.max_create_count")
9828                 $disable_precreate &&
9829                         do_facet $SINGLEMDS "lctl set_param -n \
9830                                 osp.$ost*MDT0000.max_create_count=0"
9831
9832                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
9833                         [ -f $DIR/$tdir/$idx ] && continue
9834                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
9835                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
9836                                 { cleanup_65k;
9837                                   error "setstripe $idx should succeed"; }
9838                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
9839                 done
9840                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
9841                 rmdir $DIR/$tdir
9842
9843                 do_facet $SINGLEMDS "lctl set_param -n \
9844                         osp.$ost*MDT0000.max_create_count=$max_count"
9845                 do_facet $SINGLEMDS "lctl set_param -n \
9846                         osp.$ost*MDT0000.create_count=$count"
9847                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
9848                 echo $INACTIVE_OSC "is Activate"
9849
9850                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
9851         done
9852 }
9853 run_test 65k "validate manual striping works properly with deactivated OSCs"
9854
9855 test_65l() { # bug 12836
9856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9857
9858         test_mkdir -p $DIR/$tdir/test_dir
9859         $LFS setstripe -c -1 $DIR/$tdir/test_dir
9860         $LFS find -mtime -1 $DIR/$tdir >/dev/null
9861 }
9862 run_test 65l "lfs find on -1 stripe dir ========================"
9863
9864 test_65m() {
9865         local layout=$(save_layout $MOUNT)
9866         $RUNAS $LFS setstripe -c 2 $MOUNT && {
9867                 restore_layout $MOUNT $layout
9868                 error "setstripe should fail by non-root users"
9869         }
9870         true
9871 }
9872 run_test 65m "normal user can't set filesystem default stripe"
9873
9874 test_65n() {
9875         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
9876         [[ $MDS1_VERSION -ge $(version_code 2.12.50) ]] ||
9877                 skip "Need MDS version at least 2.12.50"
9878         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
9879
9880         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
9881         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
9882         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
9883
9884         save_layout_restore_at_exit $MOUNT
9885
9886         # new subdirectory under root directory should not inherit
9887         # the default layout from root
9888         local dir1=$MOUNT/$tdir-1
9889         mkdir $dir1 || error "mkdir $dir1 failed"
9890         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
9891                 error "$dir1 shouldn't have LOV EA"
9892
9893         # delete the default layout on root directory
9894         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
9895
9896         local dir2=$MOUNT/$tdir-2
9897         mkdir $dir2 || error "mkdir $dir2 failed"
9898         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
9899                 error "$dir2 shouldn't have LOV EA"
9900
9901         # set a new striping pattern on root directory
9902         local def_stripe_size=$($LFS getstripe -S $MOUNT)
9903         local new_def_stripe_size=$((def_stripe_size * 2))
9904         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
9905                 error "set stripe size on $MOUNT failed"
9906
9907         # new file created in $dir2 should inherit the new stripe size from
9908         # the filesystem default
9909         local file2=$dir2/$tfile-2
9910         touch $file2 || error "touch $file2 failed"
9911
9912         local file2_stripe_size=$($LFS getstripe -S $file2)
9913         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
9914         {
9915                 echo "file2_stripe_size: '$file2_stripe_size'"
9916                 echo "new_def_stripe_size: '$new_def_stripe_size'"
9917                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
9918         }
9919
9920         local dir3=$MOUNT/$tdir-3
9921         mkdir $dir3 || error "mkdir $dir3 failed"
9922         # $dir3 shouldn't have LOV EA, but "lfs getstripe -d $dir3" should show
9923         # the root layout, which is the actual default layout that will be used
9924         # when new files are created in $dir3.
9925         local dir3_layout=$(get_layout_param $dir3)
9926         local root_dir_layout=$(get_layout_param $MOUNT)
9927         [[ "$dir3_layout" = "$root_dir_layout" ]] ||
9928         {
9929                 echo "dir3_layout: '$dir3_layout'"
9930                 echo "root_dir_layout: '$root_dir_layout'"
9931                 error "$dir3 should show the default layout from $MOUNT"
9932         }
9933
9934         # set OST pool on root directory
9935         local pool=$TESTNAME
9936         pool_add $pool || error "add $pool failed"
9937         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
9938                 error "add targets to $pool failed"
9939
9940         $LFS setstripe -p $pool $MOUNT ||
9941                 error "set OST pool on $MOUNT failed"
9942
9943         # new file created in $dir3 should inherit the pool from
9944         # the filesystem default
9945         local file3=$dir3/$tfile-3
9946         touch $file3 || error "touch $file3 failed"
9947
9948         local file3_pool=$($LFS getstripe -p $file3)
9949         [[ "$file3_pool" = "$pool" ]] ||
9950                 error "$file3 ('$file3_pool') didn't inherit OST pool '$pool'"
9951
9952         local dir4=$MOUNT/$tdir-4
9953         mkdir $dir4 || error "mkdir $dir4 failed"
9954         local dir4_layout=$(get_layout_param $dir4)
9955         root_dir_layout=$(get_layout_param $MOUNT)
9956         echo "$LFS getstripe -d $dir4"
9957         $LFS getstripe -d $dir4
9958         echo "$LFS getstripe -d $MOUNT"
9959         $LFS getstripe -d $MOUNT
9960         [[ "$dir4_layout" = "$root_dir_layout" ]] ||
9961         {
9962                 echo "dir4_layout: '$dir4_layout'"
9963                 echo "root_dir_layout: '$root_dir_layout'"
9964                 error "$dir4 should show the default layout from $MOUNT"
9965         }
9966
9967         # new file created in $dir4 should inherit the pool from
9968         # the filesystem default
9969         local file4=$dir4/$tfile-4
9970         touch $file4 || error "touch $file4 failed"
9971
9972         local file4_pool=$($LFS getstripe -p $file4)
9973         [[ "$file4_pool" = "$pool" ]] ||
9974                 error "$file4 ('$file4_pool') didn't inherit OST pool $pool"
9975
9976         # new subdirectory under non-root directory should inherit
9977         # the default layout from its parent directory
9978         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
9979                 error "set directory layout on $dir4 failed"
9980
9981         local dir5=$dir4/$tdir-5
9982         mkdir $dir5 || error "mkdir $dir5 failed"
9983
9984         dir4_layout=$(get_layout_param $dir4)
9985         local dir5_layout=$(get_layout_param $dir5)
9986         [[ "$dir4_layout" = "$dir5_layout" ]] ||
9987         {
9988                 echo "dir4_layout: '$dir4_layout'"
9989                 echo "dir5_layout: '$dir5_layout'"
9990                 error "$dir5 should inherit the default layout from $dir4"
9991         }
9992
9993         # though subdir under ROOT doesn't inherit default layout, but
9994         # its sub dir/file should be created with default layout.
9995         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
9996         [[ $MDS1_VERSION -ge $(version_code 2.12.59) ]] ||
9997                 skip "Need MDS version at least 2.12.59"
9998
9999         local default_lmv_count=$($LFS getdirstripe -D -c $MOUNT)
10000         local default_lmv_index=$($LFS getdirstripe -D -i $MOUNT)
10001         local default_lmv_hash=$($LFS getdirstripe -D -H $MOUNT)
10002
10003         if [ $default_lmv_hash == "none" ]; then
10004                 stack_trap "$LFS setdirstripe -D -d $MOUNT" EXIT
10005         else
10006                 stack_trap "$LFS setdirstripe -D -i $default_lmv_index \
10007                         -c $default_lmv_count -H $default_lmv_hash $MOUNT" EXIT
10008         fi
10009
10010         $LFS setdirstripe -D -c 2 $MOUNT ||
10011                 error "setdirstripe -D -c 2 failed"
10012         mkdir $MOUNT/$tdir-6 || error "mkdir $tdir-6 failed"
10013         local lmv_count=$($LFS getdirstripe -c $MOUNT/$tdir-6)
10014         [ $lmv_count -eq 2 ] || error "$tdir-6 stripe count $lmv_count"
10015
10016         # $dir4 layout includes pool
10017         $LFS setstripe -S $((new_def_stripe_size * 2)) $dir4
10018         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10019                 error "pool lost on setstripe"
10020         $LFS setstripe -E -1 -S $new_def_stripe_size $dir4
10021         [[ "$pool" = $($LFS getstripe -p -d $dir4) ]] ||
10022                 error "pool lost on compound layout setstripe"
10023 }
10024 run_test 65n "don't inherit default layout from root for new subdirectories"
10025
10026 test_65o() {
10027         (( $MDS1_VERSION >= $(version_code 2.14.57) )) ||
10028                 skip "need MDS version at least 2.14.57"
10029
10030         # set OST pool on root directory
10031         local pool=$TESTNAME
10032
10033         pool_add $pool || error "add $pool failed"
10034         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
10035                 error "add targets to $pool failed"
10036
10037         local dir1=$MOUNT/$tdir
10038
10039         mkdir $dir1 || error "mkdir $dir1 failed"
10040
10041         # set a new striping pattern on root directory
10042         local def_stripe_size=$($LFS getstripe -S $MOUNT)
10043
10044         $LFS setstripe -p $pool $dir1 ||
10045                 error "set directory layout on $dir1 failed"
10046
10047         # $dir1 layout includes pool
10048         $LFS setstripe -S $((def_stripe_size * 2)) $dir1
10049         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10050                 error "pool lost on setstripe"
10051         $LFS setstripe -E 1M -L mdt -E -1 -c 1 $dir1
10052         $LFS getstripe $dir1
10053         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10054                 error "pool lost on compound layout setstripe"
10055
10056         $LFS setdirstripe -i 0 -c 2 $dir1/dir2 ||
10057                 error "setdirstripe failed on sub-dir with inherited pool"
10058         $LFS getstripe $dir1/dir2
10059         [[ "$pool" = $($LFS getstripe -p -d $dir1/dir2) ]] ||
10060                 error "pool lost on compound layout setdirstripe"
10061
10062         $LFS setstripe -E -1 -c 1 $dir1
10063         $LFS getstripe -d $dir1
10064         [[ "$pool" = $($LFS getstripe -p -d $dir1) ]] ||
10065                 error "pool lost on setstripe"
10066 }
10067 run_test 65o "pool inheritance for mdt component"
10068
10069 test_65p () { # LU-16152
10070         local src_dir=$DIR/$tdir/src_dir
10071         local dst_dir=$DIR/$tdir/dst_dir
10072         local yaml_file=$DIR/$tdir/layout.yaml
10073         local border
10074
10075         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
10076                 skip "Need at least version 2.15.51"
10077
10078         test_mkdir -p $src_dir
10079         $LFS setstripe -E 2048M -c 4 -E EOF -c 8 $src_dir ||
10080                 error "failed to setstripe"
10081         $LFS getstripe --yaml -d $src_dir > $yaml_file ||
10082                 error "failed to getstripe"
10083
10084         test_mkdir -p $dst_dir
10085         $LFS setstripe --yaml $yaml_file $dst_dir ||
10086                 error "failed to setstripe with yaml file"
10087         border=$($LFS getstripe -d $dst_dir |
10088                 awk '/lcme_extent.e_end:/ { print $2; exit; }') ||
10089                 error "failed to getstripe"
10090
10091         # 2048M is 0x80000000, or 2147483648
10092         (( $border == 2147483648 )) ||
10093                 error "failed to handle huge number in yaml layout"
10094 }
10095 run_test 65p "setstripe with yaml file and huge number"
10096
10097 # bug 2543 - update blocks count on client
10098 test_66() {
10099         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10100
10101         local COUNT=${COUNT:-8}
10102         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
10103         sync; sync_all_data; sync; sync_all_data
10104         cancel_lru_locks osc
10105         local BLOCKS=$(ls -s --block-size=1k $DIR/f66 | awk '{ print $1 }')
10106         (( BLOCKS >= COUNT )) || error "$DIR/f66 blocks $BLOCKS < $COUNT"
10107 }
10108 run_test 66 "update inode blocks count on client ==============="
10109
10110 meminfo() {
10111         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
10112 }
10113
10114 swap_used() {
10115         swapon -s | awk '($1 == "'$1'") { print $4 }'
10116 }
10117
10118 # bug5265, obdfilter oa2dentry return -ENOENT
10119 # #define OBD_FAIL_SRV_ENOENT 0x217
10120 test_69() {
10121         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10122         remote_ost_nodsh && skip "remote OST with nodsh"
10123
10124         f="$DIR/$tfile"
10125         $LFS setstripe -c 1 -i 0 $f
10126
10127         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
10128
10129         do_facet ost1 lctl set_param fail_loc=0x217
10130         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
10131         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
10132
10133         do_facet ost1 lctl set_param fail_loc=0
10134         $DIRECTIO write $f 0 2 || error "write error"
10135
10136         cancel_lru_locks osc
10137         $DIRECTIO read $f 0 1 || error "read error"
10138
10139         do_facet ost1 lctl set_param fail_loc=0x217
10140         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
10141
10142         do_facet ost1 lctl set_param fail_loc=0
10143         rm -f $f
10144 }
10145 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
10146
10147 test_71() {
10148         test_mkdir $DIR/$tdir
10149         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
10150         bash rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
10151 }
10152 run_test 71 "Running dbench on lustre (don't segment fault) ===="
10153
10154 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
10155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10156         [ "$RUNAS_ID" = "$UID" ] &&
10157                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10158         # Check that testing environment is properly set up. Skip if not
10159         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
10160                 skip_env "User $RUNAS_ID does not exist - skipping"
10161
10162         touch $DIR/$tfile
10163         chmod 777 $DIR/$tfile
10164         chmod ug+s $DIR/$tfile
10165         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
10166                 error "$RUNAS dd $DIR/$tfile failed"
10167         # See if we are still setuid/sgid
10168         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10169                 error "S/gid is not dropped on write"
10170         # Now test that MDS is updated too
10171         cancel_lru_locks mdc
10172         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
10173                 error "S/gid is not dropped on MDS"
10174         rm -f $DIR/$tfile
10175 }
10176 run_test 72a "Test that remove suid works properly (bug5695) ===="
10177
10178 test_72b() { # bug 24226 -- keep mode setting when size is not changing
10179         local perm
10180
10181         [ "$RUNAS_ID" = "$UID" ] &&
10182                 skip_env "RUNAS_ID = UID = $UID -- skipping"
10183         [ "$RUNAS_ID" -eq 0 ] &&
10184                 skip_env "RUNAS_ID = 0 -- skipping"
10185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10186         # Check that testing environment is properly set up. Skip if not
10187         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
10188                 skip_env "User $RUNAS_ID does not exist - skipping"
10189
10190         touch $DIR/${tfile}-f{g,u}
10191         test_mkdir $DIR/${tfile}-dg
10192         test_mkdir $DIR/${tfile}-du
10193         chmod 770 $DIR/${tfile}-{f,d}{g,u}
10194         chmod g+s $DIR/${tfile}-{f,d}g
10195         chmod u+s $DIR/${tfile}-{f,d}u
10196         for perm in 777 2777 4777; do
10197                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
10198                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
10199                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
10200                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
10201         done
10202         true
10203 }
10204 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
10205
10206 # bug 3462 - multiple simultaneous MDC requests
10207 test_73() {
10208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10209
10210         test_mkdir $DIR/d73-1
10211         test_mkdir $DIR/d73-2
10212         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
10213         pid1=$!
10214
10215         lctl set_param fail_loc=0x80000129
10216         $MULTIOP $DIR/d73-1/f73-2 Oc &
10217         sleep 1
10218         lctl set_param fail_loc=0
10219
10220         $MULTIOP $DIR/d73-2/f73-3 Oc &
10221         pid3=$!
10222
10223         kill -USR1 $pid1
10224         wait $pid1 || return 1
10225
10226         sleep 25
10227
10228         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
10229         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
10230         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
10231
10232         rm -rf $DIR/d73-*
10233 }
10234 run_test 73 "multiple MDC requests (should not deadlock)"
10235
10236 test_74a() { # bug 6149, 6184
10237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10238
10239         touch $DIR/f74a
10240         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10241         #
10242         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10243         # will spin in a tight reconnection loop
10244         $LCTL set_param fail_loc=0x8000030e
10245         # get any lock that won't be difficult - lookup works.
10246         ls $DIR/f74a
10247         $LCTL set_param fail_loc=0
10248         rm -f $DIR/f74a
10249         true
10250 }
10251 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
10252
10253 test_74b() { # bug 13310
10254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10255
10256         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
10257         #
10258         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
10259         # will spin in a tight reconnection loop
10260         $LCTL set_param fail_loc=0x8000030e
10261         # get a "difficult" lock
10262         touch $DIR/f74b
10263         $LCTL set_param fail_loc=0
10264         rm -f $DIR/f74b
10265         true
10266 }
10267 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
10268
10269 test_74c() {
10270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10271
10272         #define OBD_FAIL_LDLM_NEW_LOCK
10273         $LCTL set_param fail_loc=0x319
10274         touch $DIR/$tfile && error "touch successful"
10275         $LCTL set_param fail_loc=0
10276         true
10277 }
10278 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
10279
10280 slab_lic=/sys/kernel/slab/lustre_inode_cache
10281 num_objects() {
10282         [ -f $slab_lic/shrink ] && echo 1 > $slab_lic/shrink
10283         [ -f $slab_lic/objects ] && awk '{ print $1 }' $slab_lic/objects ||
10284                 awk '/lustre_inode_cache/ { print $2; exit }' /proc/slabinfo
10285 }
10286
10287 test_76a() { # Now for b=20433, added originally in b=1443
10288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10289
10290         cancel_lru_locks osc
10291         # there may be some slab objects cached per core
10292         local cpus=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
10293         local before=$(num_objects)
10294         local count=$((512 * cpus))
10295         [ "$SLOW" = "no" ] && count=$((128 * cpus))
10296         local margin=$((count / 10))
10297         if [[ -f $slab_lic/aliases ]]; then
10298                 local aliases=$(cat $slab_lic/aliases)
10299                 (( aliases > 0 )) && margin=$((margin * aliases))
10300         fi
10301
10302         echo "before slab objects: $before"
10303         for i in $(seq $count); do
10304                 touch $DIR/$tfile
10305                 rm -f $DIR/$tfile
10306         done
10307         cancel_lru_locks osc
10308         local after=$(num_objects)
10309         echo "created: $count, after slab objects: $after"
10310         # shared slab counts are not very accurate, allow significant margin
10311         # the main goal is that the cache growth is not permanently > $count
10312         while (( after > before + margin )); do
10313                 sleep 1
10314                 after=$(num_objects)
10315                 wait=$((wait + 1))
10316                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10317                 if (( wait > 60 )); then
10318                         error "inode slab grew from $before+$margin to $after"
10319                 fi
10320         done
10321 }
10322 run_test 76a "confirm clients recycle inodes properly ===="
10323
10324 test_76b() {
10325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10326         [ $CLIENT_VERSION -ge $(version_code 2.13.55) ] || skip "not supported"
10327
10328         local count=512
10329         local before=$(num_objects)
10330
10331         for i in $(seq $count); do
10332                 mkdir $DIR/$tdir
10333                 rmdir $DIR/$tdir
10334         done
10335
10336         local after=$(num_objects)
10337         local wait=0
10338
10339         while (( after > before )); do
10340                 sleep 1
10341                 after=$(num_objects)
10342                 wait=$((wait + 1))
10343                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
10344                 if (( wait > 60 )); then
10345                         error "inode slab grew from $before to $after"
10346                 fi
10347         done
10348
10349         echo "slab objects before: $before, after: $after"
10350 }
10351 run_test 76b "confirm clients recycle directory inodes properly ===="
10352
10353 export ORIG_CSUM=""
10354 set_checksums()
10355 {
10356         # Note: in sptlrpc modes which enable its own bulk checksum, the
10357         # original crc32_le bulk checksum will be automatically disabled,
10358         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
10359         # will be checked by sptlrpc code against sptlrpc bulk checksum.
10360         # In this case set_checksums() will not be no-op, because sptlrpc
10361         # bulk checksum will be enabled all through the test.
10362
10363         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
10364         lctl set_param -n osc.*.checksums $1
10365         return 0
10366 }
10367
10368 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10369                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
10370 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
10371                              tr -d [] | head -n1)}
10372 set_checksum_type()
10373 {
10374         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
10375         rc=$?
10376         log "set checksum type to $1, rc = $rc"
10377         return $rc
10378 }
10379
10380 get_osc_checksum_type()
10381 {
10382         # arugment 1: OST name, like OST0000
10383         ost=$1
10384         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
10385                         sed 's/.*\[\(.*\)\].*/\1/g')
10386         rc=$?
10387         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
10388         echo $checksum_type
10389 }
10390
10391 F77_TMP=$TMP/f77-temp
10392 F77SZ=8
10393 setup_f77() {
10394         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
10395                 error "error writing to $F77_TMP"
10396 }
10397
10398 test_77a() { # bug 10889
10399         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10400         $GSS && skip_env "could not run with gss"
10401
10402         [ ! -f $F77_TMP ] && setup_f77
10403         set_checksums 1
10404         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
10405         set_checksums 0
10406         rm -f $DIR/$tfile
10407 }
10408 run_test 77a "normal checksum read/write operation"
10409
10410 test_77b() { # bug 10889
10411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10412         $GSS && skip_env "could not run with gss"
10413
10414         [ ! -f $F77_TMP ] && setup_f77
10415         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10416         $LCTL set_param fail_loc=0x80000409
10417         set_checksums 1
10418
10419         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10420                 error "dd error: $?"
10421         $LCTL set_param fail_loc=0
10422
10423         for algo in $CKSUM_TYPES; do
10424                 cancel_lru_locks osc
10425                 set_checksum_type $algo
10426                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10427                 $LCTL set_param fail_loc=0x80000408
10428                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
10429                 $LCTL set_param fail_loc=0
10430         done
10431         set_checksums 0
10432         set_checksum_type $ORIG_CSUM_TYPE
10433         rm -f $DIR/$tfile
10434 }
10435 run_test 77b "checksum error on client write, read"
10436
10437 cleanup_77c() {
10438         trap 0
10439         set_checksums 0
10440         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
10441         $check_ost &&
10442                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
10443         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
10444         $check_ost && [ -n "$ost_file_prefix" ] &&
10445                 do_facet ost1 rm -f ${ost_file_prefix}\*
10446 }
10447
10448 test_77c() {
10449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10450         $GSS && skip_env "could not run with gss"
10451         remote_ost_nodsh && skip "remote OST with nodsh"
10452
10453         local bad1
10454         local osc_file_prefix
10455         local osc_file
10456         local check_ost=false
10457         local ost_file_prefix
10458         local ost_file
10459         local orig_cksum
10460         local dump_cksum
10461         local fid
10462
10463         # ensure corruption will occur on first OSS/OST
10464         $LFS setstripe -i 0 $DIR/$tfile
10465
10466         [ ! -f $F77_TMP ] && setup_f77
10467         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
10468                 error "dd write error: $?"
10469         fid=$($LFS path2fid $DIR/$tfile)
10470
10471         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
10472         then
10473                 check_ost=true
10474                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
10475                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
10476         else
10477                 echo "OSS do not support bulk pages dump upon error"
10478         fi
10479
10480         osc_file_prefix=$($LCTL get_param -n debug_path)
10481         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
10482
10483         trap cleanup_77c EXIT
10484
10485         set_checksums 1
10486         # enable bulk pages dump upon error on Client
10487         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
10488         # enable bulk pages dump upon error on OSS
10489         $check_ost &&
10490                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
10491
10492         # flush Client cache to allow next read to reach OSS
10493         cancel_lru_locks osc
10494
10495         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
10496         $LCTL set_param fail_loc=0x80000408
10497         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
10498         $LCTL set_param fail_loc=0
10499
10500         rm -f $DIR/$tfile
10501
10502         # check cksum dump on Client
10503         osc_file=$(ls ${osc_file_prefix}*)
10504         [ -n "$osc_file" ] || error "no checksum dump file on Client"
10505         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
10506         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
10507         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
10508         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
10509                      cksum)
10510         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
10511         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10512                 error "dump content does not match on Client"
10513
10514         $check_ost || skip "No need to check cksum dump on OSS"
10515
10516         # check cksum dump on OSS
10517         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
10518         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
10519         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
10520         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
10521         [[ "$orig_cksum" == "$dump_cksum" ]] ||
10522                 error "dump content does not match on OSS"
10523
10524         cleanup_77c
10525 }
10526 run_test 77c "checksum error on client read with debug"
10527
10528 test_77d() { # bug 10889
10529         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10530         $GSS && skip_env "could not run with gss"
10531
10532         stack_trap "rm -f $DIR/$tfile"
10533         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10534         $LCTL set_param fail_loc=0x80000409
10535         set_checksums 1
10536         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10537                 error "direct write: rc=$?"
10538         $LCTL set_param fail_loc=0
10539         set_checksums 0
10540
10541         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
10542         $LCTL set_param fail_loc=0x80000408
10543         set_checksums 1
10544         cancel_lru_locks osc
10545         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
10546                 error "direct read: rc=$?"
10547         $LCTL set_param fail_loc=0
10548         set_checksums 0
10549 }
10550 run_test 77d "checksum error on OST direct write, read"
10551
10552 test_77f() { # bug 10889
10553         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10554         $GSS && skip_env "could not run with gss"
10555
10556         set_checksums 1
10557         stack_trap "rm -f $DIR/$tfile"
10558         for algo in $CKSUM_TYPES; do
10559                 cancel_lru_locks osc
10560                 set_checksum_type $algo
10561                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
10562                 $LCTL set_param fail_loc=0x409
10563                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
10564                         error "direct write succeeded"
10565                 $LCTL set_param fail_loc=0
10566         done
10567         set_checksum_type $ORIG_CSUM_TYPE
10568         set_checksums 0
10569 }
10570 run_test 77f "repeat checksum error on write (expect error)"
10571
10572 test_77g() { # bug 10889
10573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10574         $GSS && skip_env "could not run with gss"
10575         remote_ost_nodsh && skip "remote OST with nodsh"
10576
10577         [ ! -f $F77_TMP ] && setup_f77
10578
10579         local file=$DIR/$tfile
10580         stack_trap "rm -f $file" EXIT
10581
10582         $LFS setstripe -c 1 -i 0 $file
10583         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
10584         do_facet ost1 lctl set_param fail_loc=0x8000021a
10585         set_checksums 1
10586         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
10587                 error "write error: rc=$?"
10588         do_facet ost1 lctl set_param fail_loc=0
10589         set_checksums 0
10590
10591         cancel_lru_locks osc
10592         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
10593         do_facet ost1 lctl set_param fail_loc=0x8000021b
10594         set_checksums 1
10595         cmp $F77_TMP $file || error "file compare failed"
10596         do_facet ost1 lctl set_param fail_loc=0
10597         set_checksums 0
10598 }
10599 run_test 77g "checksum error on OST write, read"
10600
10601 test_77k() { # LU-10906
10602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10603         $GSS && skip_env "could not run with gss"
10604
10605         local cksum_param="osc.$FSNAME*.checksums"
10606         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
10607         local checksum
10608         local i
10609
10610         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
10611         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM || true"
10612         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM"
10613
10614         for i in 0 1; do
10615                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
10616                         error "failed to set checksum=$i on MGS"
10617                 wait_update $HOSTNAME "$get_checksum" $i
10618                 #remount
10619                 echo "remount client, checksum should be $i"
10620                 remount_client $MOUNT || error "failed to remount client"
10621                 checksum=$(eval $get_checksum)
10622                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10623         done
10624         # remove persistent param to avoid races with checksum mountopt below
10625         do_facet mgs $LCTL set_param -P -d $cksum_param ||
10626                 error "failed to delete checksum on MGS"
10627
10628         for opt in "checksum" "nochecksum"; do
10629                 #remount with mount option
10630                 echo "remount client with option $opt, checksum should be $i"
10631                 umount_client $MOUNT || error "failed to umount client"
10632                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
10633                         error "failed to mount client with option '$opt'"
10634                 checksum=$(eval $get_checksum)
10635                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
10636                 i=$((i - 1))
10637         done
10638
10639         remount_client $MOUNT || error "failed to remount client"
10640 }
10641 run_test 77k "enable/disable checksum correctly"
10642
10643 test_77l() {
10644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10645         $GSS && skip_env "could not run with gss"
10646
10647         set_checksums 1
10648         stack_trap "set_checksums $ORIG_CSUM" EXIT
10649         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10650
10651         set_checksum_type invalid && error "unexpected success of invalid checksum type"
10652
10653         $LFS setstripe -c 1 -i 0 $DIR/$tfile
10654         for algo in $CKSUM_TYPES; do
10655                 set_checksum_type $algo || error "fail to set checksum type $algo"
10656                 osc_algo=$(get_osc_checksum_type OST0000)
10657                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
10658
10659                 # no locks, no reqs to let the connection idle
10660                 cancel_lru_locks osc
10661                 lru_resize_disable osc
10662                 wait_osc_import_state client ost1 IDLE
10663
10664                 # ensure ost1 is connected
10665                 stat $DIR/$tfile >/dev/null || error "can't stat"
10666                 wait_osc_import_state client ost1 FULL
10667
10668                 osc_algo=$(get_osc_checksum_type OST0000)
10669                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
10670         done
10671         return 0
10672 }
10673 run_test 77l "preferred checksum type is remembered after reconnected"
10674
10675 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
10676 rm -f $F77_TMP
10677 unset F77_TMP
10678
10679 test_77m() {
10680         (( $CLIENT_VERSION >= $(version_code 2.14.52) )) ||
10681                 skip "Need at least version 2.14.52"
10682         local param=checksum_speed
10683
10684         $LCTL get_param $param || error "reading $param failed"
10685
10686         csum_speeds=$($LCTL get_param -n $param)
10687
10688         [[ "$csum_speeds" =~ "adler32" && "$csum_speeds" =~ "crc32" ]] ||
10689                 error "known checksum types are missing"
10690 }
10691 run_test 77m "Verify checksum_speed is correctly read"
10692
10693 check_filefrag_77n() {
10694         local nr_ext=0
10695         local starts=()
10696         local ends=()
10697
10698         while read extidx a b start end rest; do
10699                 if [[ "${extidx}" =~ ^[0-9]+: ]]; then
10700                         nr_ext=$(( $nr_ext + 1 ))
10701                         starts+=( ${start%..} )
10702                         ends+=( ${end%:} )
10703                 fi
10704         done < <( filefrag -sv $1 )
10705
10706         [[ $nr_ext -eq 2 ]] && [[ "${starts[-1]}" == $(( ${ends[0]} + 1 )) ]] && return 0
10707         return 1
10708 }
10709
10710 test_77n() {
10711         [[ "$CKSUM_TYPES" =~ t10 ]] || skip "no T10 checksum support on osc"
10712
10713         touch $DIR/$tfile
10714         $TRUNCATE $DIR/$tfile 0
10715         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=0
10716         dd if=/dev/urandom of=$DIR/$tfile bs=4k conv=notrunc count=1 seek=2
10717         check_filefrag_77n $DIR/$tfile ||
10718                 skip "$tfile blocks not contiguous around hole"
10719
10720         set_checksums 1
10721         stack_trap "set_checksums $ORIG_CSUM" EXIT
10722         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
10723         stack_trap "rm -f $DIR/$tfile"
10724
10725         for algo in $CKSUM_TYPES; do
10726                 if [[ "$algo" =~ ^t10 ]]; then
10727                         set_checksum_type $algo ||
10728                                 error "fail to set checksum type $algo"
10729                         dd if=$DIR/$tfile of=/dev/null bs=12k count=1 iflag=direct ||
10730                                 error "fail to read $tfile with $algo"
10731                 fi
10732         done
10733         rm -f $DIR/$tfile
10734         return 0
10735 }
10736 run_test 77n "Verify read from a hole inside contiguous blocks with T10PI"
10737
10738 test_77o() {
10739         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
10740                 skip "Need MDS version at least 2.14.55"
10741         (( $OST1_VERSION >= $(version_code 2.14.55) )) ||
10742                 skip "Need OST version at least 2.14.55"
10743         local ofd=obdfilter
10744         local mdt=mdt
10745
10746         # print OST checksum_type
10747         echo "$ofd.$FSNAME-*.checksum_type:"
10748         do_nodes $(comma_list $(osts_nodes)) \
10749                 $LCTL get_param -n $ofd.$FSNAME-*.checksum_type
10750
10751         # print MDT checksum_type
10752         echo "$mdt.$FSNAME-*.checksum_type:"
10753         do_nodes $(comma_list $(mdts_nodes)) \
10754                 $LCTL get_param -n $mdt.$FSNAME-*.checksum_type
10755
10756         local o_count=$(do_nodes $(comma_list $(osts_nodes)) \
10757                    $LCTL get_param -n $ofd.$FSNAME-*.checksum_type | wc -l)
10758
10759         (( $o_count == $OSTCOUNT )) ||
10760                 error "found $o_count checksums, not \$MDSCOUNT=$OSTCOUNT"
10761
10762         local m_count=$(do_nodes $(comma_list $(mdts_nodes)) \
10763                    $LCTL get_param -n $mdt.$FSNAME-*.checksum_type | wc -l)
10764
10765         (( $m_count == $MDSCOUNT )) ||
10766                 error "found $m_count checksums, not \$MDSCOUNT=$MDSCOUNT"
10767 }
10768 run_test 77o "Verify checksum_type for server (mdt and ofd(obdfilter))"
10769
10770 cleanup_test_78() {
10771         trap 0
10772         rm -f $DIR/$tfile
10773 }
10774
10775 test_78() { # bug 10901
10776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10777         remote_ost || skip_env "local OST"
10778
10779         NSEQ=5
10780         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
10781         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
10782         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
10783         echo "MemTotal: $MEMTOTAL"
10784
10785         # reserve 256MB of memory for the kernel and other running processes,
10786         # and then take 1/2 of the remaining memory for the read/write buffers.
10787         if [ $MEMTOTAL -gt 512 ] ;then
10788                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
10789         else
10790                 # for those poor memory-starved high-end clusters...
10791                 MEMTOTAL=$((MEMTOTAL / 2))
10792         fi
10793         echo "Mem to use for directio: $MEMTOTAL"
10794
10795         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
10796         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
10797         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
10798         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
10799                 head -n1)
10800         echo "Smallest OST: $SMALLESTOST"
10801         [[ $SMALLESTOST -lt 10240 ]] &&
10802                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
10803
10804         trap cleanup_test_78 EXIT
10805
10806         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
10807                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
10808
10809         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
10810         echo "File size: $F78SIZE"
10811         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
10812         for i in $(seq 1 $NSEQ); do
10813                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
10814                 echo directIO rdwr round $i of $NSEQ
10815                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
10816         done
10817
10818         cleanup_test_78
10819 }
10820 run_test 78 "handle large O_DIRECT writes correctly ============"
10821
10822 test_79() { # bug 12743
10823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10824
10825         wait_delete_completed
10826
10827         BKTOTAL=$(calc_osc_kbytes kbytestotal)
10828         BKFREE=$(calc_osc_kbytes kbytesfree)
10829         BKAVAIL=$(calc_osc_kbytes kbytesavail)
10830
10831         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
10832         DFTOTAL=`echo $STRING | cut -d, -f1`
10833         DFUSED=`echo $STRING  | cut -d, -f2`
10834         DFAVAIL=`echo $STRING | cut -d, -f3`
10835         DFFREE=$(($DFTOTAL - $DFUSED))
10836
10837         ALLOWANCE=$((64 * $OSTCOUNT))
10838
10839         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
10840            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
10841                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
10842         fi
10843         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
10844            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
10845                 error "df free($DFFREE) mismatch OST free($BKFREE)"
10846         fi
10847         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
10848            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
10849                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
10850         fi
10851 }
10852 run_test 79 "df report consistency check ======================="
10853
10854 test_80() { # bug 10718
10855         remote_ost_nodsh && skip "remote OST with nodsh"
10856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10857
10858         # relax strong synchronous semantics for slow backends like ZFS
10859         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
10860                 local soc="obdfilter.*.sync_lock_cancel"
10861                 local save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10862
10863                 # "sync_on_lock_cancel" was broken by v2_11_55_0-26-g7059644e9a
10864                 if [ -z "$save" ]; then
10865                         soc="obdfilter.*.sync_on_lock_cancel"
10866                         save=$(do_facet ost1 $LCTL get_param -n $soc | head -n1)
10867                 fi
10868
10869                 if [ "$save" != "never" ]; then
10870                         local hosts=$(comma_list $(osts_nodes))
10871
10872                         do_nodes $hosts $LCTL set_param $soc=never
10873                         stack_trap "do_nodes $hosts $LCTL set_param $soc=$save"
10874                 fi
10875         fi
10876
10877         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
10878         sync; sleep 1; sync
10879         local before=$(date +%s)
10880         cancel_lru_locks osc
10881         local after=$(date +%s)
10882         local diff=$((after - before))
10883         [ $diff -le 1 ] || error "elapsed for 1M@1T = $diff"
10884
10885         rm -f $DIR/$tfile
10886 }
10887 run_test 80 "Page eviction is equally fast at high offsets too"
10888
10889 test_81a() { # LU-456
10890         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10891         remote_ost_nodsh && skip "remote OST with nodsh"
10892
10893         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10894         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
10895         do_facet ost1 lctl set_param fail_loc=0x80000228
10896
10897         # write should trigger a retry and success
10898         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10899         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10900         RC=$?
10901         if [ $RC -ne 0 ] ; then
10902                 error "write should success, but failed for $RC"
10903         fi
10904 }
10905 run_test 81a "OST should retry write when get -ENOSPC ==============="
10906
10907 test_81b() { # LU-456
10908         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10909         remote_ost_nodsh && skip "remote OST with nodsh"
10910
10911         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
10912         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
10913         do_facet ost1 lctl set_param fail_loc=0x228
10914
10915         # write should retry several times and return -ENOSPC finally
10916         $LFS setstripe -i 0 -c 1 $DIR/$tfile
10917         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10918         RC=$?
10919         ENOSPC=28
10920         if [ $RC -ne $ENOSPC ] ; then
10921                 error "dd should fail for -ENOSPC, but succeed."
10922         fi
10923 }
10924 run_test 81b "OST should return -ENOSPC when retry still fails ======="
10925
10926 test_99() {
10927         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
10928
10929         test_mkdir $DIR/$tdir.cvsroot
10930         chown $RUNAS_ID $DIR/$tdir.cvsroot
10931
10932         cd $TMP
10933         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
10934
10935         cd /etc/init.d
10936         # some versions of cvs import exit(1) when asked to import links or
10937         # files they can't read.  ignore those files.
10938         local toignore=$(find . -type l -printf '-I %f\n' -o \
10939                          ! -perm /4 -printf '-I %f\n')
10940         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
10941                 $tdir.reposname vtag rtag
10942
10943         cd $DIR
10944         test_mkdir $DIR/$tdir.reposname
10945         chown $RUNAS_ID $DIR/$tdir.reposname
10946         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
10947
10948         cd $DIR/$tdir.reposname
10949         $RUNAS touch foo99
10950         $RUNAS cvs add -m 'addmsg' foo99
10951         $RUNAS cvs update
10952         $RUNAS cvs commit -m 'nomsg' foo99
10953         rm -fr $DIR/$tdir.cvsroot
10954 }
10955 run_test 99 "cvs strange file/directory operations"
10956
10957 test_100() {
10958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10959         [[ "$NETTYPE" =~ tcp ]] ||
10960                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
10961         remote_ost_nodsh && skip "remote OST with nodsh"
10962         remote_mds_nodsh && skip "remote MDS with nodsh"
10963         remote_servers ||
10964                 skip "useless for local single node setup"
10965
10966         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
10967                 [ "$PROT" != "tcp" ] && continue
10968                 RPORT=$(echo $REMOTE | cut -d: -f2)
10969                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
10970
10971                 rc=0
10972                 LPORT=`echo $LOCAL | cut -d: -f2`
10973                 if [ $LPORT -ge 1024 ]; then
10974                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
10975                         netstat -tna
10976                         error_exit "local: $LPORT > 1024, remote: $RPORT"
10977                 fi
10978         done
10979         [ "$rc" = 0 ] || error_exit "privileged port not found" )
10980 }
10981 run_test 100 "check local port using privileged port ==========="
10982
10983 function get_named_value()
10984 {
10985     local tag=$1
10986
10987     grep -w "$tag" | sed "s/^$tag  *\([0-9]*\)  *.*/\1/"
10988 }
10989
10990 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
10991                    awk '/^max_cached_mb/ { print $2 }')
10992
10993 cleanup_101a() {
10994         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
10995         trap 0
10996 }
10997
10998 test_101a() {
10999         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11000
11001         local s
11002         local discard
11003         local nreads=10000
11004         local cache_limit=32
11005
11006         $LCTL set_param -n osc.*-osc*.rpc_stats=0
11007         trap cleanup_101a EXIT
11008         $LCTL set_param -n llite.*.read_ahead_stats=0
11009         $LCTL set_param -n llite.*.max_cached_mb=$cache_limit
11010
11011         #
11012         # randomly read 10000 of 64K chunks from file 3x 32MB in size
11013         #
11014         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
11015         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
11016
11017         discard=0
11018         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
11019                    get_named_value 'read.but.discarded'); do
11020                         discard=$(($discard + $s))
11021         done
11022         cleanup_101a
11023
11024         $LCTL get_param osc.*-osc*.rpc_stats
11025         $LCTL get_param llite.*.read_ahead_stats
11026
11027         # Discard is generally zero, but sometimes a few random reads line up
11028         # and trigger larger readahead, which is wasted & leads to discards.
11029         if [[ $(($discard)) -gt $nreads ]]; then
11030                 error "too many ($discard) discarded pages"
11031         fi
11032         rm -f $DIR/$tfile || true
11033 }
11034 run_test 101a "check read-ahead for random reads"
11035
11036 setup_test101bc() {
11037         test_mkdir $DIR/$tdir
11038         local ssize=$1
11039         local FILE_LENGTH=$2
11040         STRIPE_OFFSET=0
11041
11042         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
11043
11044         local list=$(comma_list $(osts_nodes))
11045         set_osd_param $list '' read_cache_enable 0
11046         set_osd_param $list '' writethrough_cache_enable 0
11047
11048         trap cleanup_test101bc EXIT
11049         # prepare the read-ahead file
11050         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
11051
11052         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
11053                                 count=$FILE_SIZE_MB 2> /dev/null
11054
11055 }
11056
11057 cleanup_test101bc() {
11058         trap 0
11059         rm -rf $DIR/$tdir
11060         rm -f $DIR/$tfile
11061
11062         local list=$(comma_list $(osts_nodes))
11063         set_osd_param $list '' read_cache_enable 1
11064         set_osd_param $list '' writethrough_cache_enable 1
11065 }
11066
11067 calc_total() {
11068         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
11069 }
11070
11071 ra_check_101() {
11072         local read_size=$1
11073         local stripe_size=$2
11074         local stride_length=$((stripe_size / read_size))
11075         local stride_width=$((stride_length * OSTCOUNT))
11076         local discard_limit=$(( ((stride_length - 1) * 3 / stride_width) *
11077                                 (stride_width - stride_length) ))
11078         local discard=$($LCTL get_param -n llite.*.read_ahead_stats |
11079                   get_named_value 'read.but.discarded' | calc_total)
11080
11081         if [[ $discard -gt $discard_limit ]]; then
11082                 $LCTL get_param llite.*.read_ahead_stats
11083                 error "($discard limit ${discard_limit}) discarded pages with size (${read_size})"
11084         else
11085                 echo "Read-ahead success for size ${read_size}"
11086         fi
11087 }
11088
11089 test_101b() {
11090         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11091         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11092
11093         local STRIPE_SIZE=1048576
11094         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
11095
11096         if [ $SLOW == "yes" ]; then
11097                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
11098         else
11099                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
11100         fi
11101
11102         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
11103
11104         # prepare the read-ahead file
11105         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11106         cancel_lru_locks osc
11107         for BIDX in 2 4 8 16 32 64 128 256
11108         do
11109                 local BSIZE=$((BIDX*4096))
11110                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
11111                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
11112                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
11113                 $LCTL set_param -n llite.*.read_ahead_stats=0
11114                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
11115                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
11116                 cancel_lru_locks osc
11117                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
11118         done
11119         cleanup_test101bc
11120         true
11121 }
11122 run_test 101b "check stride-io mode read-ahead ================="
11123
11124 test_101c() {
11125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11126
11127         local STRIPE_SIZE=1048576
11128         local FILE_LENGTH=$((STRIPE_SIZE*100))
11129         local nreads=10000
11130         local rsize=65536
11131         local osc_rpc_stats
11132
11133         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
11134
11135         cancel_lru_locks osc
11136         $LCTL set_param osc.*.rpc_stats=0
11137         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
11138         $LCTL get_param osc.*.rpc_stats
11139         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
11140                 local stats=$($LCTL get_param -n $osc_rpc_stats)
11141                 local lines=$(echo "$stats" | awk 'END {print NR;}')
11142                 local size
11143
11144                 if [ $lines -le 20 ]; then
11145                         echo "continue debug"
11146                         continue
11147                 fi
11148                 for size in 1 2 4 8; do
11149                         local rpc=$(echo "$stats" |
11150                                     awk '($1 == "'$size':") {print $2; exit; }')
11151                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
11152                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
11153                 done
11154                 echo "$osc_rpc_stats check passed!"
11155         done
11156         cleanup_test101bc
11157         true
11158 }
11159 run_test 101c "check stripe_size aligned read-ahead"
11160
11161 test_101d() {
11162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11163
11164         local file=$DIR/$tfile
11165         local sz_MB=${FILESIZE_101d:-80}
11166         local ra_MB=${READAHEAD_MB:-40}
11167
11168         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
11169         [ $free_MB -lt $sz_MB ] &&
11170                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
11171
11172         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
11173         $LFS setstripe -c -1 $file || error "setstripe failed"
11174
11175         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
11176         echo Cancel LRU locks on lustre client to flush the client cache
11177         cancel_lru_locks osc
11178
11179         echo Disable read-ahead
11180         local old_RA=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11181         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11182         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb=$old_RA" EXIT
11183         $LCTL get_param -n llite.*.max_read_ahead_mb
11184
11185         echo "Reading the test file $file with read-ahead disabled"
11186         local sz_KB=$((sz_MB * 1024 / 4))
11187         # 10485760 bytes transferred in 0.000938 secs (11179579337 bytes/sec)
11188         # 104857600 bytes (105 MB) copied, 0.00876352 s, 12.0 GB/s
11189         local raOFF=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11190                       sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11191
11192         echo "Cancel LRU locks on lustre client to flush the client cache"
11193         cancel_lru_locks osc
11194         echo Enable read-ahead with ${ra_MB}MB
11195         $LCTL set_param -n llite.*.max_read_ahead_mb=$ra_MB
11196
11197         echo "Reading the test file $file with read-ahead enabled"
11198         local raON=$(LANG=C dd if=$file of=/dev/null bs=4k count=$sz_KB |&
11199                      sed -e '/records/d' -e 's/.* \([0-9]*\.[0-9]*\) *s.*/\1/')
11200
11201         echo "read-ahead disabled time read $raOFF"
11202         echo "read-ahead enabled time read $raON"
11203
11204         rm -f $file
11205         wait_delete_completed
11206
11207         # use awk for this check instead of bash because it handles decimals
11208         awk "{ exit !($raOFF < 1.0 || $raOFF > $raON) }" <<<"ignore_me" ||
11209                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
11210 }
11211 run_test 101d "file read with and without read-ahead enabled"
11212
11213 test_101e() {
11214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11215
11216         local file=$DIR/$tfile
11217         local size_KB=500  #KB
11218         local count=100
11219         local bsize=1024
11220
11221         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
11222         local need_KB=$((count * size_KB))
11223         [[ $free_KB -le $need_KB ]] &&
11224                 skip_env "Need free space $need_KB, have $free_KB"
11225
11226         echo "Creating $count ${size_KB}K test files"
11227         for ((i = 0; i < $count; i++)); do
11228                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
11229         done
11230
11231         echo "Cancel LRU locks on lustre client to flush the client cache"
11232         cancel_lru_locks $OSC
11233
11234         echo "Reset readahead stats"
11235         $LCTL set_param -n llite.*.read_ahead_stats=0
11236
11237         for ((i = 0; i < $count; i++)); do
11238                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
11239         done
11240
11241         $LCTL get_param llite.*.max_cached_mb
11242         $LCTL get_param llite.*.read_ahead_stats
11243         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11244                      get_named_value 'misses' | calc_total)
11245
11246         for ((i = 0; i < $count; i++)); do
11247                 rm -rf $file.$i 2>/dev/null
11248         done
11249
11250         #10000 means 20% reads are missing in readahead
11251         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
11252 }
11253 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
11254
11255 test_101f() {
11256         which iozone || skip_env "no iozone installed"
11257
11258         local old_debug=$($LCTL get_param debug)
11259         old_debug=${old_debug#*=}
11260         $LCTL set_param debug="reada mmap"
11261
11262         # create a test file
11263         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
11264
11265         echo Cancel LRU locks on lustre client to flush the client cache
11266         cancel_lru_locks osc
11267
11268         echo Reset readahead stats
11269         $LCTL set_param -n llite.*.read_ahead_stats=0
11270
11271         echo mmap read the file with small block size
11272         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
11273                 > /dev/null 2>&1
11274
11275         echo checking missing pages
11276         $LCTL get_param llite.*.read_ahead_stats
11277         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11278                         get_named_value 'misses' | calc_total)
11279
11280         $LCTL set_param debug="$old_debug"
11281         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
11282         rm -f $DIR/$tfile
11283 }
11284 run_test 101f "check mmap read performance"
11285
11286 test_101g_brw_size_test() {
11287         local mb=$1
11288         local pages=$((mb * 1048576 / PAGE_SIZE))
11289         local file=$DIR/$tfile
11290
11291         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
11292                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
11293         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
11294                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
11295                         return 2
11296         done
11297
11298         stack_trap "rm -f $file" EXIT
11299         $LCTL set_param -n osc.*.rpc_stats=0
11300
11301         # 10 RPCs should be enough for the test
11302         local count=10
11303         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
11304                 { error "dd write ${mb} MB blocks failed"; return 3; }
11305         cancel_lru_locks osc
11306         dd of=/dev/null if=$file bs=${mb}M count=$count ||
11307                 { error "dd write ${mb} MB blocks failed"; return 4; }
11308
11309         # calculate number of full-sized read and write RPCs
11310         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
11311                 sed -n '/pages per rpc/,/^$/p' |
11312                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
11313                 END { print reads,writes }'))
11314         # allow one extra full-sized read RPC for async readahead
11315         [[ ${rpcs[0]} == $count || ${rpcs[0]} == $((count + 1)) ]] ||
11316                 { error "${rpcs[0]} != $count read RPCs"; return 5; }
11317         [[ ${rpcs[1]} == $count ]] ||
11318                 { error "${rpcs[1]} != $count write RPCs"; return 6; }
11319 }
11320
11321 test_101g() {
11322         remote_ost_nodsh && skip "remote OST with nodsh"
11323
11324         local rpcs
11325         local osts=$(get_facets OST)
11326         local list=$(comma_list $(osts_nodes))
11327         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
11328         local brw_size="obdfilter.*.brw_size"
11329
11330         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11331
11332         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
11333
11334         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
11335                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
11336                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
11337            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
11338                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
11339                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
11340
11341                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
11342                         suffix="M"
11343
11344                 if [[ $orig_mb -lt 16 ]]; then
11345                         save_lustre_params $osts "$brw_size" > $p
11346                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
11347                                 error "set 16MB RPC size failed"
11348
11349                         echo "remount client to enable new RPC size"
11350                         remount_client $MOUNT || error "remount_client failed"
11351                 fi
11352
11353                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
11354                 # should be able to set brw_size=12, but no rpc_stats for that
11355                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
11356         fi
11357
11358         test_101g_brw_size_test 4 || error "4MB RPC test failed"
11359
11360         if [[ $orig_mb -lt 16 ]]; then
11361                 restore_lustre_params < $p
11362                 remount_client $MOUNT || error "remount_client restore failed"
11363         fi
11364
11365         rm -f $p $DIR/$tfile
11366 }
11367 run_test 101g "Big bulk(4/16 MiB) readahead"
11368
11369 test_101h() {
11370         $LFS setstripe -i 0 -c 1 $DIR/$tfile
11371
11372         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
11373                 error "dd 70M file failed"
11374         echo Cancel LRU locks on lustre client to flush the client cache
11375         cancel_lru_locks osc
11376
11377         echo "Reset readahead stats"
11378         $LCTL set_param -n llite.*.read_ahead_stats 0
11379
11380         echo "Read 10M of data but cross 64M bundary"
11381         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
11382         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11383                      get_named_value 'misses' | calc_total)
11384         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
11385         rm -f $p $DIR/$tfile
11386 }
11387 run_test 101h "Readahead should cover current read window"
11388
11389 test_101i() {
11390         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 ||
11391                 error "dd 10M file failed"
11392
11393         local max_per_file_mb=$($LCTL get_param -n \
11394                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
11395         cancel_lru_locks osc
11396         stack_trap "$LCTL set_param llite.*.max_read_ahead_per_file_mb=$max_per_file_mb"
11397         $LCTL set_param llite.*.max_read_ahead_per_file_mb=1 ||
11398                 error "set max_read_ahead_per_file_mb to 1 failed"
11399
11400         echo "Reset readahead stats"
11401         $LCTL set_param llite.*.read_ahead_stats=0
11402
11403         dd if=$DIR/$tfile of=/dev/null bs=2M
11404
11405         $LCTL get_param llite.*.read_ahead_stats
11406         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11407                      awk '/misses/ { print $2 }')
11408         [ $miss -eq 5 ] || error "expected misses 5 but got $miss"
11409         rm -f $DIR/$tfile
11410 }
11411 run_test 101i "allow current readahead to exceed reservation"
11412
11413 test_101j() {
11414         $LFS setstripe -i 0 -c 1 $DIR/$tfile ||
11415                 error "setstripe $DIR/$tfile failed"
11416         local file_size=$((1048576 * 16))
11417         local old_ra=$($LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1)
11418         stack_trap "$LCTL set_param -n llite.*.max_read_ahead_mb $old_ra" EXIT
11419
11420         echo Disable read-ahead
11421         $LCTL set_param -n llite.*.max_read_ahead_mb=0
11422
11423         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$(($file_size / 1048576))
11424         for blk in $PAGE_SIZE 1048576 $file_size; do
11425                 cancel_lru_locks osc
11426                 echo "Reset readahead stats"
11427                 $LCTL set_param -n llite.*.read_ahead_stats=0
11428                 local count=$(($file_size / $blk))
11429                 dd if=$DIR/$tfile bs=$blk count=$count of=/dev/null
11430                 local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
11431                              get_named_value 'failed.to.fast.read' | calc_total)
11432                 $LCTL get_param -n llite.*.read_ahead_stats
11433                 [ $miss -eq $count ] || error "expected $count got $miss"
11434         done
11435
11436         rm -f $p $DIR/$tfile
11437 }
11438 run_test 101j "A complete read block should be submitted when no RA"
11439
11440 test_readahead_base() {
11441         local file=$DIR/$tfile
11442         local size=$1
11443         local iosz
11444         local ramax
11445         local ranum
11446
11447         $LCTL set_param -n llite.*.read_ahead_stats=0
11448         # The first page is not accounted into readahead
11449         ramax=$(((size + PAGE_SIZE - 1) / PAGE_SIZE - 1))
11450         iosz=$(((size + 1048575) / 1048576 * 1048576))
11451         echo "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11452
11453         $LCTL mark  "Test readahead: size=$size ramax=$ramx iosz=$iosz"
11454         fallocate -l $size $file || error "failed to fallocate $file"
11455         cancel_lru_locks osc
11456         $MULTIOP $file or${iosz}c || error "failed to read $file"
11457         $LCTL get_param -n llite.*.read_ahead_stats
11458         ranum=$($LCTL get_param -n llite.*.read_ahead_stats |
11459                 awk '/readahead.pages/ { print $7 }' | calc_total)
11460         (( $ranum <= $ramax )) ||
11461                 error "read-ahead pages is $ranum more than $ramax"
11462         rm -rf $file || error "failed to remove $file"
11463 }
11464
11465 test_101m()
11466 {
11467         local file=$DIR/$tfile
11468         local ramax
11469         local ranum
11470         local size
11471         local iosz
11472
11473         check_set_fallocate_or_skip
11474         stack_trap "rm -f $file" EXIT
11475
11476         test_readahead_base 4096
11477
11478         # file size: 16K = 16384
11479         test_readahead_base 16384
11480         test_readahead_base 16385
11481         test_readahead_base 16383
11482
11483         # file size: 1M + 1 = 1048576 + 1
11484         test_readahead_base 1048577
11485         # file size: 1M + 16K
11486         test_readahead_base $((1048576 + 16384))
11487
11488         # file size: stripe_size * (stripe_count - 1) + 16K
11489         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11490         test_readahead_base $((1048576 * (OSTCOUNT - 1) + 16384))
11491         # file size: stripe_size * stripe_count + 16K
11492         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11493         test_readahead_base $((1048576 * OSTCOUNT + 16384))
11494         # file size: 2 * stripe_size * stripe_count + 16K
11495         $LFS setstripe -c -1 $file || error "failed to setstripe $file"
11496         test_readahead_base $((2 * 1048576 * OSTCOUNT + 16384))
11497 }
11498 run_test 101m "read ahead for small file and last stripe of the file"
11499
11500 setup_test102() {
11501         test_mkdir $DIR/$tdir
11502         chown $RUNAS_ID $DIR/$tdir
11503         STRIPE_SIZE=65536
11504         STRIPE_OFFSET=1
11505         STRIPE_COUNT=$OSTCOUNT
11506         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
11507
11508         trap cleanup_test102 EXIT
11509         cd $DIR
11510         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
11511         cd $DIR/$tdir
11512         for num in 1 2 3 4; do
11513                 for count in $(seq 1 $STRIPE_COUNT); do
11514                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
11515                                 local size=`expr $STRIPE_SIZE \* $num`
11516                                 local file=file"$num-$idx-$count"
11517                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
11518                         done
11519                 done
11520         done
11521
11522         cd $DIR
11523         $1 tar cf $TMP/f102.tar $tdir --xattrs
11524 }
11525
11526 cleanup_test102() {
11527         trap 0
11528         rm -f $TMP/f102.tar
11529         rm -rf $DIR/d0.sanity/d102
11530 }
11531
11532 test_102a() {
11533         [ "$UID" != 0 ] && skip "must run as root"
11534         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
11535                 skip_env "must have user_xattr"
11536
11537         [ -z "$(which setfattr 2>/dev/null)" ] &&
11538                 skip_env "could not find setfattr"
11539
11540         local testfile=$DIR/$tfile
11541
11542         touch $testfile
11543         echo "set/get xattr..."
11544         setfattr -n trusted.name1 -v value1 $testfile ||
11545                 error "setfattr -n trusted.name1=value1 $testfile failed"
11546         getfattr -n trusted.name1 $testfile 2> /dev/null |
11547           grep "trusted.name1=.value1" ||
11548                 error "$testfile missing trusted.name1=value1"
11549
11550         setfattr -n user.author1 -v author1 $testfile ||
11551                 error "setfattr -n user.author1=author1 $testfile failed"
11552         getfattr -n user.author1 $testfile 2> /dev/null |
11553           grep "user.author1=.author1" ||
11554                 error "$testfile missing trusted.author1=author1"
11555
11556         echo "listxattr..."
11557         setfattr -n trusted.name2 -v value2 $testfile ||
11558                 error "$testfile unable to set trusted.name2"
11559         setfattr -n trusted.name3 -v value3 $testfile ||
11560                 error "$testfile unable to set trusted.name3"
11561         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
11562             grep "trusted.name" | wc -l) -eq 3 ] ||
11563                 error "$testfile missing 3 trusted.name xattrs"
11564
11565         setfattr -n user.author2 -v author2 $testfile ||
11566                 error "$testfile unable to set user.author2"
11567         setfattr -n user.author3 -v author3 $testfile ||
11568                 error "$testfile unable to set user.author3"
11569         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
11570             grep "user.author" | wc -l) -eq 3 ] ||
11571                 error "$testfile missing 3 user.author xattrs"
11572
11573         echo "remove xattr..."
11574         setfattr -x trusted.name1 $testfile ||
11575                 error "$testfile error deleting trusted.name1"
11576         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
11577                 error "$testfile did not delete trusted.name1 xattr"
11578
11579         setfattr -x user.author1 $testfile ||
11580                 error "$testfile error deleting user.author1"
11581         echo "set lustre special xattr ..."
11582         $LFS setstripe -c1 $testfile
11583         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
11584                 awk -F "=" '/trusted.lov/ { print $2 }' )
11585         setfattr -n "trusted.lov" -v $lovea $testfile ||
11586                 error "$testfile doesn't ignore setting trusted.lov again"
11587         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
11588                 error "$testfile allow setting invalid trusted.lov"
11589         rm -f $testfile
11590 }
11591 run_test 102a "user xattr test =================================="
11592
11593 check_102b_layout() {
11594         local layout="$*"
11595         local testfile=$DIR/$tfile
11596
11597         echo "test layout '$layout'"
11598         $LFS setstripe $layout $testfile || error "setstripe failed"
11599         $LFS getstripe -y $testfile
11600
11601         echo "get/set/list trusted.lov xattr ..." # b=10930
11602         local value=$(getfattr -n trusted.lov -e hex $testfile | grep trusted)
11603         [[ "$value" =~ "trusted.lov" ]] ||
11604                 error "can't get trusted.lov from $testfile"
11605         local stripe_count_orig=$($LFS getstripe -c $testfile) ||
11606                 error "getstripe failed"
11607
11608         $MCREATE $testfile.2 || error "mcreate $testfile.2 failed"
11609
11610         value=$(cut -d= -f2 <<<$value)
11611         # LU-13168: truncated xattr should fail if short lov_user_md header
11612         [ $CLIENT_VERSION -lt $(version_code 2.13.53) ] &&
11613                 lens="${#value}" || lens="$(seq 4 2 ${#value})"
11614         for len in $lens; do
11615                 echo "setfattr $len $testfile.2"
11616                 setfattr -n trusted.lov -v ${value:0:$len} $testfile.2 &&
11617                         [ $len -lt 66 ] && error "short xattr len=$len worked"
11618         done
11619         local stripe_size=$($LFS getstripe -S $testfile.2)
11620         local stripe_count=$($LFS getstripe -c $testfile.2)
11621         [[ $stripe_size -eq 65536 ]] ||
11622                 error "stripe size $stripe_size != 65536"
11623         [[ $stripe_count -eq $stripe_count_orig ]] ||
11624                 error "stripe count $stripe_count != $stripe_count_orig"
11625         rm $testfile $testfile.2
11626 }
11627
11628 test_102b() {
11629         [ -z "$(which setfattr 2>/dev/null)" ] &&
11630                 skip_env "could not find setfattr"
11631         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11632
11633         # check plain layout
11634         check_102b_layout -S 65536 -i 1 -c $OSTCOUNT
11635
11636         # and also check composite layout
11637         check_102b_layout -E 1M -S 65536 -i 1 -c $OSTCOUNT -Eeof -S4M
11638
11639 }
11640 run_test 102b "getfattr/setfattr for trusted.lov EAs"
11641
11642 test_102c() {
11643         [ -z "$(which setfattr 2>/dev/null)" ] &&
11644                 skip_env "could not find setfattr"
11645         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11646
11647         # b10930: get/set/list lustre.lov xattr
11648         echo "get/set/list lustre.lov xattr ..."
11649         test_mkdir $DIR/$tdir
11650         chown $RUNAS_ID $DIR/$tdir
11651         local testfile=$DIR/$tdir/$tfile
11652         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
11653                 error "setstripe failed"
11654         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
11655                 error "getstripe failed"
11656         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
11657         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
11658
11659         local testfile2=${testfile}2
11660         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
11661                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
11662
11663         $RUNAS $MCREATE $testfile2
11664         $RUNAS setfattr -n lustre.lov -v $value $testfile2
11665         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
11666         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
11667         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
11668         [ $stripe_count -eq $STRIPECOUNT ] ||
11669                 error "stripe count $stripe_count != $STRIPECOUNT"
11670 }
11671 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
11672
11673 compare_stripe_info1() {
11674         local stripe_index_all_zero=true
11675
11676         for num in 1 2 3 4; do
11677                 for count in $(seq 1 $STRIPE_COUNT); do
11678                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
11679                                 local size=$((STRIPE_SIZE * num))
11680                                 local file=file"$num-$offset-$count"
11681                                 stripe_size=$($LFS getstripe -S $PWD/$file)
11682                                 [[ $stripe_size -ne $size ]] &&
11683                                     error "$file: size $stripe_size != $size"
11684                                 stripe_count=$($LFS getstripe -c $PWD/$file)
11685                                 # allow fewer stripes to be created, ORI-601
11686                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
11687                                     error "$file: count $stripe_count != $count"
11688                                 stripe_index=$($LFS getstripe -i $PWD/$file)
11689                                 [[ $stripe_index -ne 0 ]] &&
11690                                         stripe_index_all_zero=false
11691                         done
11692                 done
11693         done
11694         $stripe_index_all_zero &&
11695                 error "all files are being extracted starting from OST index 0"
11696         return 0
11697 }
11698
11699 have_xattrs_include() {
11700         tar --help | grep -q xattrs-include &&
11701                 echo --xattrs-include="lustre.*"
11702 }
11703
11704 test_102d() {
11705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11706         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11707
11708         XINC=$(have_xattrs_include)
11709         setup_test102
11710         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11711         cd $DIR/$tdir/$tdir
11712         compare_stripe_info1
11713 }
11714 run_test 102d "tar restore stripe info from tarfile,not keep osts"
11715
11716 test_102f() {
11717         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11718         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11719
11720         XINC=$(have_xattrs_include)
11721         setup_test102
11722         test_mkdir $DIR/$tdir.restore
11723         cd $DIR
11724         tar cf - --xattrs $tdir | tar xf - \
11725                 -C $DIR/$tdir.restore --xattrs $XINC
11726         cd $DIR/$tdir.restore/$tdir
11727         compare_stripe_info1
11728 }
11729 run_test 102f "tar copy files, not keep osts"
11730
11731 grow_xattr() {
11732         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
11733                 skip "must have user_xattr"
11734         [ -z "$(which setfattr 2>/dev/null)" ] &&
11735                 skip_env "could not find setfattr"
11736         [ -z "$(which getfattr 2>/dev/null)" ] &&
11737                 skip_env "could not find getfattr"
11738
11739         local xsize=${1:-1024}  # in bytes
11740         local file=$DIR/$tfile
11741         local value="$(generate_string $xsize)"
11742         local xbig=trusted.big
11743         local toobig=$2
11744
11745         touch $file
11746         log "save $xbig on $file"
11747         if [ -z "$toobig" ]
11748         then
11749                 setfattr -n $xbig -v $value $file ||
11750                         error "saving $xbig on $file failed"
11751         else
11752                 setfattr -n $xbig -v $value $file &&
11753                         error "saving $xbig on $file succeeded"
11754                 return 0
11755         fi
11756
11757         local orig=$(get_xattr_value $xbig $file)
11758         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
11759
11760         local xsml=trusted.sml
11761         log "save $xsml on $file"
11762         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
11763
11764         local new=$(get_xattr_value $xbig $file)
11765         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
11766
11767         log "grow $xsml on $file"
11768         setfattr -n $xsml -v "$value" $file ||
11769                 error "growing $xsml on $file failed"
11770
11771         new=$(get_xattr_value $xbig $file)
11772         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
11773         log "$xbig still valid after growing $xsml"
11774
11775         rm -f $file
11776 }
11777
11778 test_102h() { # bug 15777
11779         grow_xattr 1024
11780 }
11781 run_test 102h "grow xattr from inside inode to external block"
11782
11783 test_102ha() {
11784         large_xattr_enabled || skip_env "ea_inode feature disabled"
11785
11786         echo "setting xattr of max xattr size: $(max_xattr_size)"
11787         grow_xattr $(max_xattr_size)
11788
11789         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
11790         echo "This should fail:"
11791         grow_xattr $(($(max_xattr_size) + 10)) 1
11792 }
11793 run_test 102ha "grow xattr from inside inode to external inode"
11794
11795 test_102i() { # bug 17038
11796         [ -z "$(which getfattr 2>/dev/null)" ] &&
11797                 skip "could not find getfattr"
11798
11799         touch $DIR/$tfile
11800         ln -s $DIR/$tfile $DIR/${tfile}link
11801         getfattr -n trusted.lov $DIR/$tfile ||
11802                 error "lgetxattr on $DIR/$tfile failed"
11803         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
11804                 grep -i "no such attr" ||
11805                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
11806         rm -f $DIR/$tfile $DIR/${tfile}link
11807 }
11808 run_test 102i "lgetxattr test on symbolic link ============"
11809
11810 test_102j() {
11811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11812         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11813
11814         XINC=$(have_xattrs_include)
11815         setup_test102 "$RUNAS"
11816         chown $RUNAS_ID $DIR/$tdir
11817         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
11818         cd $DIR/$tdir/$tdir
11819         compare_stripe_info1 "$RUNAS"
11820 }
11821 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
11822
11823 test_102k() {
11824         [ -z "$(which setfattr 2>/dev/null)" ] &&
11825                 skip "could not find setfattr"
11826
11827         touch $DIR/$tfile
11828         # b22187 just check that does not crash for regular file.
11829         setfattr -n trusted.lov $DIR/$tfile
11830         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
11831         local test_kdir=$DIR/$tdir
11832         test_mkdir $test_kdir
11833         local default_size=$($LFS getstripe -S $test_kdir)
11834         local default_count=$($LFS getstripe -c $test_kdir)
11835         local default_offset=$($LFS getstripe -i $test_kdir)
11836         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
11837                 error 'dir setstripe failed'
11838         setfattr -n trusted.lov $test_kdir
11839         local stripe_size=$($LFS getstripe -S $test_kdir)
11840         local stripe_count=$($LFS getstripe -c $test_kdir)
11841         local stripe_offset=$($LFS getstripe -i $test_kdir)
11842         [ $stripe_size -eq $default_size ] ||
11843                 error "stripe size $stripe_size != $default_size"
11844         [ $stripe_count -eq $default_count ] ||
11845                 error "stripe count $stripe_count != $default_count"
11846         [ $stripe_offset -eq $default_offset ] ||
11847                 error "stripe offset $stripe_offset != $default_offset"
11848         rm -rf $DIR/$tfile $test_kdir
11849 }
11850 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
11851
11852 test_102l() {
11853         [ -z "$(which getfattr 2>/dev/null)" ] &&
11854                 skip "could not find getfattr"
11855
11856         # LU-532 trusted. xattr is invisible to non-root
11857         local testfile=$DIR/$tfile
11858
11859         touch $testfile
11860
11861         echo "listxattr as user..."
11862         chown $RUNAS_ID $testfile
11863         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
11864             grep -q "trusted" &&
11865                 error "$testfile trusted xattrs are user visible"
11866
11867         return 0;
11868 }
11869 run_test 102l "listxattr size test =================================="
11870
11871 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
11872         local path=$DIR/$tfile
11873         touch $path
11874
11875         listxattr_size_check $path || error "listattr_size_check $path failed"
11876 }
11877 run_test 102m "Ensure listxattr fails on small bufffer ========"
11878
11879 cleanup_test102
11880
11881 getxattr() { # getxattr path name
11882         # Return the base64 encoding of the value of xattr name on path.
11883         local path=$1
11884         local name=$2
11885
11886         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
11887         # file: $path
11888         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11889         #
11890         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
11891
11892         getfattr --absolute-names --encoding=base64 --name=$name $path |
11893                 awk -F= -v name=$name '$1 == name {
11894                         print substr($0, index($0, "=") + 1);
11895         }'
11896 }
11897
11898 test_102n() { # LU-4101 mdt: protect internal xattrs
11899         [ -z "$(which setfattr 2>/dev/null)" ] &&
11900                 skip "could not find setfattr"
11901         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
11902         then
11903                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
11904         fi
11905
11906         local file0=$DIR/$tfile.0
11907         local file1=$DIR/$tfile.1
11908         local xattr0=$TMP/$tfile.0
11909         local xattr1=$TMP/$tfile.1
11910         local namelist="lov lma lmv link fid version som hsm"
11911         local name
11912         local value
11913
11914         rm -rf $file0 $file1 $xattr0 $xattr1
11915         touch $file0 $file1
11916
11917         # Get 'before' xattrs of $file1.
11918         getfattr --absolute-names --dump --match=- $file1 > $xattr0
11919
11920         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
11921                 namelist+=" lfsck_namespace"
11922         for name in $namelist; do
11923                 # Try to copy xattr from $file0 to $file1.
11924                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11925
11926                 setfattr --name=trusted.$name --value="$value" $file1 ||
11927                         error "setxattr 'trusted.$name' failed"
11928
11929                 # Try to set a garbage xattr.
11930                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11931
11932                 if [[ x$name == "xlov" ]]; then
11933                         setfattr --name=trusted.lov --value="$value" $file1 &&
11934                         error "setxattr invalid 'trusted.lov' success"
11935                 else
11936                         setfattr --name=trusted.$name --value="$value" $file1 ||
11937                                 error "setxattr invalid 'trusted.$name' failed"
11938                 fi
11939
11940                 # Try to remove the xattr from $file1. We don't care if this
11941                 # appears to succeed or fail, we just don't want there to be
11942                 # any changes or crashes.
11943                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11944         done
11945
11946         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
11947         then
11948                 name="lfsck_ns"
11949                 # Try to copy xattr from $file0 to $file1.
11950                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
11951
11952                 setfattr --name=trusted.$name --value="$value" $file1 ||
11953                         error "setxattr 'trusted.$name' failed"
11954
11955                 # Try to set a garbage xattr.
11956                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
11957
11958                 setfattr --name=trusted.$name --value="$value" $file1 ||
11959                         error "setxattr 'trusted.$name' failed"
11960
11961                 # Try to remove the xattr from $file1. We don't care if this
11962                 # appears to succeed or fail, we just don't want there to be
11963                 # any changes or crashes.
11964                 setfattr --remove=$trusted.$name $file1 2> /dev/null
11965         fi
11966
11967         # Get 'after' xattrs of file1.
11968         getfattr --absolute-names --dump --match=- $file1 > $xattr1
11969
11970         if ! diff $xattr0 $xattr1; then
11971                 error "before and after xattrs of '$file1' differ"
11972         fi
11973
11974         rm -rf $file0 $file1 $xattr0 $xattr1
11975
11976         return 0
11977 }
11978 run_test 102n "silently ignore setxattr on internal trusted xattrs"
11979
11980 test_102p() { # LU-4703 setxattr did not check ownership
11981         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
11982                 skip "MDS needs to be at least 2.5.56"
11983
11984         local testfile=$DIR/$tfile
11985
11986         touch $testfile
11987
11988         echo "setfacl as user..."
11989         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
11990         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
11991
11992         echo "setfattr as user..."
11993         setfacl -m "u:$RUNAS_ID:---" $testfile
11994         $RUNAS setfattr -x system.posix_acl_access $testfile
11995         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
11996 }
11997 run_test 102p "check setxattr(2) correctly fails without permission"
11998
11999 test_102q() {
12000         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
12001                 skip "MDS needs to be at least 2.6.92"
12002
12003         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
12004 }
12005 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
12006
12007 test_102r() {
12008         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
12009                 skip "MDS needs to be at least 2.6.93"
12010
12011         touch $DIR/$tfile || error "touch"
12012         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
12013         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
12014         rm $DIR/$tfile || error "rm"
12015
12016         #normal directory
12017         mkdir -p $DIR/$tdir || error "mkdir"
12018         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12019         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12020         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12021                 error "$testfile error deleting user.author1"
12022         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12023                 grep "user.$(basename $tdir)" &&
12024                 error "$tdir did not delete user.$(basename $tdir)"
12025         rmdir $DIR/$tdir || error "rmdir"
12026
12027         #striped directory
12028         test_mkdir $DIR/$tdir
12029         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
12030         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
12031         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
12032                 error "$testfile error deleting user.author1"
12033         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
12034                 grep "user.$(basename $tdir)" &&
12035                 error "$tdir did not delete user.$(basename $tdir)"
12036         rmdir $DIR/$tdir || error "rm striped dir"
12037 }
12038 run_test 102r "set EAs with empty values"
12039
12040 test_102s() {
12041         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12042                 skip "MDS needs to be at least 2.11.52"
12043
12044         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12045
12046         save_lustre_params client "llite.*.xattr_cache" > $save
12047
12048         for cache in 0 1; do
12049                 lctl set_param llite.*.xattr_cache=$cache
12050
12051                 rm -f $DIR/$tfile
12052                 touch $DIR/$tfile || error "touch"
12053                 for prefix in lustre security system trusted user; do
12054                         # Note getxattr() may fail with 'Operation not
12055                         # supported' or 'No such attribute' depending
12056                         # on prefix and cache.
12057                         getfattr -n $prefix.n102s $DIR/$tfile &&
12058                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
12059                 done
12060         done
12061
12062         restore_lustre_params < $save
12063 }
12064 run_test 102s "getting nonexistent xattrs should fail"
12065
12066 test_102t() {
12067         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
12068                 skip "MDS needs to be at least 2.11.52"
12069
12070         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12071
12072         save_lustre_params client "llite.*.xattr_cache" > $save
12073
12074         for cache in 0 1; do
12075                 lctl set_param llite.*.xattr_cache=$cache
12076
12077                 for buf_size in 0 256; do
12078                         rm -f $DIR/$tfile
12079                         touch $DIR/$tfile || error "touch"
12080                         setfattr -n user.multiop $DIR/$tfile
12081                         $MULTIOP $DIR/$tfile oa$buf_size ||
12082                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
12083                 done
12084         done
12085
12086         restore_lustre_params < $save
12087 }
12088 run_test 102t "zero length xattr values handled correctly"
12089
12090 run_acl_subtest()
12091 {
12092         local test=$LUSTRE/tests/acl/$1.test
12093         local tmp=$(mktemp -t $1-XXXXXX).test
12094         local bin=$2
12095         local dmn=$3
12096         local grp=$4
12097         local nbd=$5
12098         export LANG=C
12099
12100
12101         local sedusers="-e s/bin/$bin/g -e s/daemon/$dmn/g"
12102         local sedgroups="-e s/:users/:$grp/g"
12103         [[ -z "$nbd" ]] || sedusers+=" -e s/nobody/$nbd/g"
12104
12105         sed $sedusers $sedgroups < $test > $tmp
12106         stack_trap "rm -f $tmp"
12107         [[ -s $tmp ]] || error "sed failed to create test script"
12108
12109         echo "performing $1 with bin='$bin' daemon='$dmn' users='$grp'..."
12110         $LUSTRE/tests/acl/run $tmp || error "run_acl_subtest '$1' failed"
12111 }
12112
12113 test_103a() {
12114         [ "$UID" != 0 ] && skip "must run as root"
12115         $GSS && skip_env "could not run under gss"
12116         [[ "$(lctl get_param -n mdc.*-mdc-*.connect_flags)" =~ "acl" ]] ||
12117                 skip_env "must have acl enabled"
12118         which setfacl || skip_env "could not find setfacl"
12119         remote_mds_nodsh && skip "remote MDS with nodsh"
12120
12121         ACLBIN=${ACLBIN:-"bin"}
12122         ACLDMN=${ACLDMN:-"daemon"}
12123         ACLGRP=${ACLGRP:-"users"}
12124         ACLNBD=${ACLNBD:-"nobody"}
12125
12126         if ! id $ACLBIN ||
12127            [[ "$(id -u $ACLBIN)" != "$(do_facet mds1 id -u $ACLBIN)" ]]; then
12128                 echo "bad 'bin' user '$ACLBIN', using '$USER0'"
12129                 ACLBIN=$USER0
12130                 if ! id $ACLBIN ; then
12131                         cat /etc/passwd
12132                         skip_env "can't find suitable ACL 'bin' $ACLBIN"
12133                 fi
12134         fi
12135         if ! id $ACLDMN || (( $(id -u $ACLDMN) < $(id -u $ACLBIN) )) ||
12136            [[ "$(id -u $ACLDMN)" != "$(do_facet mds1 id -u $ACLDMN)" ]]; then
12137                 echo "bad 'daemon' user '$ACLDMN', using '$USER1'"
12138                 ACLDMN=$USER1
12139                 if ! id $ACLDMN ; then
12140                         cat /etc/passwd
12141                         skip_env "can't find suitable ACL 'daemon' $ACLDMN"
12142                 fi
12143         fi
12144         if ! getent group $ACLGRP; then
12145                 echo "missing 'users' group '$ACLGRP', using '$TSTUSR'"
12146                 ACLGRP="$TSTUSR"
12147                 if ! getent group $ACLGRP; then
12148                         echo "cannot find group '$ACLGRP', adding it"
12149                         cat /etc/group
12150                         add_group 60000 $ACLGRP
12151                 fi
12152         fi
12153
12154         local bingid=$(getent group $ACLBIN | cut -d: -f 3)
12155         local dmngid=$(getent group $ACLDMN | cut -d: -f 3)
12156         local grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12157
12158         if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12159                 echo "group '$ACLGRP' has low gid=$grpgid, use '$TSTUSR'"
12160                 ACLGRP="$TSTUSR"
12161                 if ! getent group $ACLGRP; then
12162                         echo "cannot find group '$ACLGRP', adding it"
12163                         cat /etc/group
12164                         add_group 60000 $ACLGRP
12165                 fi
12166                 grpgid=$(getent group $ACLGRP | cut -d: -f 3)
12167                 if (( $bingid > $grpgid || $dmngid > $grpgid )); then
12168                         cat /etc/group
12169                         skip_env "$ACLGRP gid=$grpgid less than $bingid|$dmngid"
12170                 fi
12171         fi
12172
12173         gpasswd -a $ACLDMN $ACLBIN ||
12174                 error "setting client group failed"             # LU-5641
12175         do_facet mds1 gpasswd -a $ACLDMN $ACLBIN ||
12176                 error "setting MDS group failed"                # LU-5641
12177
12178         declare -a identity_old
12179
12180         for num in $(seq $MDSCOUNT); do
12181                 switch_identity $num true || identity_old[$num]=$?
12182         done
12183
12184         SAVE_UMASK=$(umask)
12185         umask 0022
12186         mkdir -p $DIR/$tdir
12187         cd $DIR/$tdir
12188
12189         run_acl_subtest cp $ACLBIN $ACLDMN $ACLGRP
12190         run_acl_subtest getfacl-noacl $ACLBIN $ACLDMN $ACLGRP
12191         run_acl_subtest misc $ACLBIN $ACLDMN $ACLGRP
12192         run_acl_subtest permissions $ACLBIN $ACLDMN $ACLGRP
12193         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
12194         # CentOS7- uses nobody=99, while newer distros use nobody=65534
12195         if ! id -u $ACLNBD ||
12196            (( $(id -u nobody) != $(do_facet mds1 id -u nobody) )); then
12197                 ACLNBD="nfsnobody"
12198                 if ! id -u $ACLNBD; then
12199                         ACLNBD=""
12200                 fi
12201         fi
12202         if [[ -n "$ACLNBD" ]] && ! getent group $ACLNBD; then
12203                 add_group $(id -u $ACLNBD) $ACLNBD
12204                 if ! getent group $ACLNBD; then
12205                         ACLNBD=""
12206                 fi
12207         fi
12208         if (( $MDS1_VERSION > $(version_code 2.8.55) )) &&
12209            [[ -n "$ACLNBD" ]] && which setfattr; then
12210                 run_acl_subtest permissions_xattr \
12211                         $ACLBIN $ACLDMN $ACLGRP $ACLNBD
12212         elif [[ -z "$ACLNBD" ]]; then
12213                 echo "skip 'permission_xattr' test - missing 'nobody' user/grp"
12214         else
12215                 echo "skip 'permission_xattr' test - missing setfattr command"
12216         fi
12217         run_acl_subtest setfacl $ACLBIN $ACLDMN $ACLGRP
12218
12219         # inheritance test got from HP
12220         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
12221         chmod +x make-tree || error "chmod +x failed"
12222         run_acl_subtest inheritance $ACLBIN $ACLDMN $ACLGRP
12223         rm -f make-tree
12224
12225         echo "LU-974 ignore umask when acl is enabled..."
12226         run_acl_subtest 974 $ACLBIN $ACLDMN $ACLGRP
12227         if [ $MDSCOUNT -ge 2 ]; then
12228                 run_acl_subtest 974_remote $ACLBIN $ACLDMN $ACLGRP
12229         fi
12230
12231         echo "LU-2561 newly created file is same size as directory..."
12232         if [ "$mds1_FSTYPE" != "zfs" ]; then
12233                 run_acl_subtest 2561 $ACLBIN $ACLDMN $ACLGRP
12234         else
12235                 run_acl_subtest 2561_zfs $ACLBIN $ACLDMN $ACLGRP
12236         fi
12237
12238         run_acl_subtest 4924 $ACLBIN $ACLDMN $ACLGRP
12239
12240         cd $SAVE_PWD
12241         umask $SAVE_UMASK
12242
12243         for num in $(seq $MDSCOUNT); do
12244                 if [ "${identity_old[$num]}" = 1 ]; then
12245                         switch_identity $num false || identity_old[$num]=$?
12246                 fi
12247         done
12248 }
12249 run_test 103a "acl test"
12250
12251 test_103b() {
12252         declare -a pids
12253         local U
12254
12255         for U in {0..511}; do
12256                 {
12257                 local O=$(printf "%04o" $U)
12258
12259                 umask $(printf "%04o" $((511 ^ $O)))
12260                 $LFS setstripe -c 1 $DIR/$tfile.s$O
12261                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
12262
12263                 (( $S == ($O & 0666) )) ||
12264                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
12265
12266                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
12267                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
12268                 (( $S == ($O & 0666) )) ||
12269                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
12270
12271                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
12272                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
12273                 (( $S == ($O & 0666) )) ||
12274                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
12275                 rm -f $DIR/$tfile.[smp]$0
12276                 } &
12277                 local pid=$!
12278
12279                 # limit the concurrently running threads to 64. LU-11878
12280                 local idx=$((U % 64))
12281                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
12282                 pids[idx]=$pid
12283         done
12284         wait
12285 }
12286 run_test 103b "umask lfs setstripe"
12287
12288 test_103c() {
12289         mkdir -p $DIR/$tdir
12290         cp -rp $DIR/$tdir $DIR/$tdir.bak
12291
12292         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
12293                 error "$DIR/$tdir shouldn't contain default ACL"
12294         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
12295                 error "$DIR/$tdir.bak shouldn't contain default ACL"
12296         true
12297 }
12298 run_test 103c "'cp -rp' won't set empty acl"
12299
12300 test_103e() {
12301         local numacl
12302         local fileacl
12303         local saved_debug=$($LCTL get_param -n debug)
12304
12305         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
12306                 skip "MDS needs to be at least 2.14.52"
12307
12308         large_xattr_enabled || skip_env "ea_inode feature disabled"
12309
12310         mkdir -p $DIR/$tdir
12311         # add big LOV EA to cause reply buffer overflow earlier
12312         $LFS setstripe -C 1000 $DIR/$tdir
12313         lctl set_param mdc.*-mdc*.stats=clear
12314
12315         $LCTL set_param debug=0
12316         stack_trap "$LCTL set_param debug=\"$saved_debug\"" EXIT
12317         stack_trap "$LCTL get_param mdc.*-mdc*.stats" EXIT
12318
12319         # add a large number of default ACLs (expect 8000+ for 2.13+)
12320         for U in {2..7000}; do
12321                 setfacl -d -m user:$U:rwx $DIR/$tdir ||
12322                         error "Able to add just $U default ACLs"
12323         done
12324         numacl=$(getfacl $DIR/$tdir |& grep -c "default:user")
12325         echo "$numacl default ACLs created"
12326
12327         stat $DIR/$tdir || error "Cannot stat directory"
12328         # check file creation
12329         touch $DIR/$tdir/$tfile ||
12330                 error "failed to create $tfile with $numacl default ACLs"
12331         stat $DIR/$tdir/$tfile  || error "Cannot stat file"
12332         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12333         echo "$fileacl ACLs were inherited"
12334         (( $fileacl == $numacl )) ||
12335                 error "Not all default ACLs were inherited: $numacl != $fileacl"
12336         # check that new ACLs creation adds new ACLs to inherited ACLs
12337         setfacl -m user:19000:rwx $DIR/$tdir/$tfile ||
12338                 error "Cannot set new ACL"
12339         numacl=$((numacl + 1))
12340         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12341         (( $fileacl == $numacl )) ||
12342                 error "failed to add new ACL: $fileacl != $numacl as expected"
12343         # adds more ACLs to a file to reach their maximum at 8000+
12344         numacl=0
12345         for U in {20000..25000}; do
12346                 setfacl -m user:$U:rwx $DIR/$tdir/$tfile || break
12347                 numacl=$((numacl + 1))
12348         done
12349         echo "Added $numacl more ACLs to the file"
12350         fileacl=$(getfacl $DIR/$tdir/$tfile |& grep -c "user:")
12351         echo "Total $fileacl ACLs in file"
12352         stat $DIR/$tdir/$tfile > /dev/null || error "Cannot stat file"
12353         rm -f $DIR/$tdir/$tfile || error "Cannot remove file"
12354         rmdir $DIR/$tdir || error "Cannot remove directory"
12355 }
12356 run_test 103e "inheritance of big amount of default ACLs"
12357
12358 test_103f() {
12359         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
12360                 skip "MDS needs to be at least 2.14.51"
12361
12362         large_xattr_enabled || skip_env "ea_inode feature disabled"
12363
12364         # enable changelog to consume more internal MDD buffers
12365         changelog_register
12366
12367         mkdir -p $DIR/$tdir
12368         # add big LOV EA
12369         $LFS setstripe -C 1000 $DIR/$tdir
12370         setfacl -d -m user:$U:rwx $DIR/$tdir || error "Cannot add default ACLs"
12371         mkdir $DIR/$tdir/inherited || error "failed to create subdirectory"
12372         rmdir $DIR/$tdir/inherited || error "Cannot remove subdirectory"
12373         rmdir $DIR/$tdir || error "Cannot remove directory"
12374 }
12375 run_test 103f "changelog doesn't interfere with default ACLs buffers"
12376
12377 test_104a() {
12378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12379
12380         touch $DIR/$tfile
12381         lfs df || error "lfs df failed"
12382         lfs df -ih || error "lfs df -ih failed"
12383         lfs df -h $DIR || error "lfs df -h $DIR failed"
12384         lfs df -i $DIR || error "lfs df -i $DIR failed"
12385         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
12386         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
12387
12388         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
12389         lctl --device %$OSC deactivate
12390         lfs df || error "lfs df with deactivated OSC failed"
12391         lctl --device %$OSC activate
12392         # wait the osc back to normal
12393         wait_osc_import_ready client ost
12394
12395         lfs df || error "lfs df with reactivated OSC failed"
12396         rm -f $DIR/$tfile
12397 }
12398 run_test 104a "lfs df [-ih] [path] test ========================="
12399
12400 test_104b() {
12401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12402         [ $RUNAS_ID -eq $UID ] &&
12403                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12404
12405         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
12406                         grep "Permission denied" | wc -l)))
12407         if [ $denied_cnt -ne 0 ]; then
12408                 error "lfs check servers test failed"
12409         fi
12410 }
12411 run_test 104b "$RUNAS lfs check servers test ===================="
12412
12413 #
12414 # Verify $1 is within range of $2.
12415 # Success when $1 is within range. That is, when $1 is >= 2% of $2 and
12416 # $1 is <= 2% of $2. Else Fail.
12417 #
12418 value_in_range() {
12419         # Strip all units (M, G, T)
12420         actual=$(echo $1 | tr -d A-Z)
12421         expect=$(echo $2 | tr -d A-Z)
12422
12423         expect_lo=$(($expect * 98 / 100)) # 2% below
12424         expect_hi=$(($expect * 102 / 100)) # 2% above
12425
12426         # permit 2% drift above and below
12427         (( $actual >= $expect_lo && $actual <= $expect_hi ))
12428 }
12429
12430 test_104c() {
12431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12432         [ "$ost1_FSTYPE" == "zfs" ] || skip "zfs only test"
12433
12434         local ost_param="osd-zfs.$FSNAME-OST0000."
12435         local mdt_param="osd-zfs.$FSNAME-MDT0000."
12436         local ofacets=$(get_facets OST)
12437         local mfacets=$(get_facets MDS)
12438         local saved_ost_blocks=
12439         local saved_mdt_blocks=
12440
12441         echo "Before recordsize change"
12442         lfs_df=($($LFS df -h | grep "filesystem_summary:"))
12443         df=($(df -h | grep "$MOUNT"$))
12444
12445         # For checking.
12446         echo "lfs output : ${lfs_df[*]}"
12447         echo "df  output : ${df[*]}"
12448
12449         for facet in ${ofacets//,/ }; do
12450                 if [ -z $saved_ost_blocks ]; then
12451                         saved_ost_blocks=$(do_facet $facet \
12452                                 lctl get_param -n $ost_param.blocksize)
12453                         echo "OST Blocksize: $saved_ost_blocks"
12454                 fi
12455                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12456                 do_facet $facet zfs set recordsize=32768 $ost
12457         done
12458
12459         # BS too small. Sufficient for functional testing.
12460         for facet in ${mfacets//,/ }; do
12461                 if [ -z $saved_mdt_blocks ]; then
12462                         saved_mdt_blocks=$(do_facet $facet \
12463                                 lctl get_param -n $mdt_param.blocksize)
12464                         echo "MDT Blocksize: $saved_mdt_blocks"
12465                 fi
12466                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12467                 do_facet $facet zfs set recordsize=32768 $mdt
12468         done
12469
12470         # Give new values chance to reflect change
12471         sleep 2
12472
12473         echo "After recordsize change"
12474         lfs_df_after=($($LFS df -h | grep "filesystem_summary:"))
12475         df_after=($(df -h | grep "$MOUNT"$))
12476
12477         # For checking.
12478         echo "lfs output : ${lfs_df_after[*]}"
12479         echo "df  output : ${df_after[*]}"
12480
12481         # Verify lfs df
12482         value_in_range ${lfs_df_after[1]%.*} ${lfs_df[1]%.*} ||
12483                 error "lfs_df bytes: ${lfs_df_after[1]%.*} != ${lfs_df[1]%.*}"
12484         value_in_range ${lfs_df_after[2]%.*} ${lfs_df[2]%.*} ||
12485                 error "lfs_df used: ${lfs_df_after[2]%.*} != ${lfs_df[2]%.*}"
12486         value_in_range ${lfs_df_after[3]%.*} ${lfs_df[3]%.*} ||
12487                 error "lfs_df avail: ${lfs_df_after[3]%.*} != ${lfs_df[3]%.*}"
12488
12489         # Verify df
12490         value_in_range ${df_after[1]%.*} ${df[1]%.*} ||
12491                 error "df bytes: ${df_after[1]%.*} != ${df[1]%.*}"
12492         value_in_range ${df_after[2]%.*} ${df[2]%.*} ||
12493                 error "df used: ${df_after[2]%.*} != ${df[2]%.*}"
12494         value_in_range ${df_after[3]%.*} ${df[3]%.*} ||
12495                 error "df avail: ${df_after[3]%.*} != ${df[3]%.*}"
12496
12497         # Restore MDT recordize back to original
12498         for facet in ${mfacets//,/ }; do
12499                 mdt=$(do_facet $facet lctl get_param -n $mdt_param.mntdev)
12500                 do_facet $facet zfs set recordsize=$saved_mdt_blocks $mdt
12501         done
12502
12503         # Restore OST recordize back to original
12504         for facet in ${ofacets//,/ }; do
12505                 ost=$(do_facet $facet lctl get_param -n $ost_param.mntdev)
12506                 do_facet $facet zfs set recordsize=$saved_ost_blocks $ost
12507         done
12508
12509         return 0
12510 }
12511 run_test 104c "Verify df vs lfs_df stays same after recordsize change"
12512
12513 test_104d() {
12514         (( $RUNAS_ID != $UID )) ||
12515                 skip_env "RUNAS_ID = UID = $UID -- skipping"
12516
12517         (( $CLIENT_VERSION >= $(version_code 2.15.51) )) ||
12518                 skip "lustre version doesn't support lctl dl with non-root"
12519
12520         # debugfs only allows root users to access files, so the
12521         # previous move of the "devices" file to debugfs broke
12522         # "lctl dl" for non-root users. The LU-9680 Netlink
12523         # interface again allows non-root users to list devices.
12524         [ "$($RUNAS $LCTL dl | wc -l)" -ge 3 ] ||
12525                 error "lctl dl doesn't work for non root"
12526
12527         ost_count="$($RUNAS $LCTL dl | grep $FSNAME-OST* | wc -l)"
12528         [ "$ost_count" -eq $OSTCOUNT ]  ||
12529                 error "lctl dl reports wrong number of OST devices"
12530
12531         mdt_count="$($RUNAS $LCTL dl | grep $FSNAME-MDT* | wc -l)"
12532         [ "$mdt_count" -eq $MDSCOUNT ]  ||
12533                 error "lctl dl reports wrong number of MDT devices"
12534 }
12535 run_test 104d "$RUNAS lctl dl test"
12536
12537 test_105a() {
12538         # doesn't work on 2.4 kernels
12539         touch $DIR/$tfile
12540         if $(flock_is_enabled); then
12541                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
12542         else
12543                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
12544         fi
12545         rm -f $DIR/$tfile
12546 }
12547 run_test 105a "flock when mounted without -o flock test ========"
12548
12549 test_105b() {
12550         touch $DIR/$tfile
12551         if $(flock_is_enabled); then
12552                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
12553         else
12554                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
12555         fi
12556         rm -f $DIR/$tfile
12557 }
12558 run_test 105b "fcntl when mounted without -o flock test ========"
12559
12560 test_105c() {
12561         touch $DIR/$tfile
12562         if $(flock_is_enabled); then
12563                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
12564         else
12565                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
12566         fi
12567         rm -f $DIR/$tfile
12568 }
12569 run_test 105c "lockf when mounted without -o flock test"
12570
12571 test_105d() { # bug 15924
12572         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12573
12574         test_mkdir $DIR/$tdir
12575         flock_is_enabled || skip_env "mount w/o flock enabled"
12576         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
12577         $LCTL set_param fail_loc=0x80000315
12578         flocks_test 2 $DIR/$tdir
12579 }
12580 run_test 105d "flock race (should not freeze) ========"
12581
12582 test_105e() { # bug 22660 && 22040
12583         flock_is_enabled || skip_env "mount w/o flock enabled"
12584
12585         touch $DIR/$tfile
12586         flocks_test 3 $DIR/$tfile
12587 }
12588 run_test 105e "Two conflicting flocks from same process"
12589
12590 test_106() { #bug 10921
12591         test_mkdir $DIR/$tdir
12592         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
12593         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
12594 }
12595 run_test 106 "attempt exec of dir followed by chown of that dir"
12596
12597 test_107() {
12598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12599
12600         CDIR=`pwd`
12601         local file=core
12602
12603         cd $DIR
12604         rm -f $file
12605
12606         local save_pattern=$(sysctl -n kernel.core_pattern)
12607         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
12608         sysctl -w kernel.core_pattern=$file
12609         sysctl -w kernel.core_uses_pid=0
12610
12611         ulimit -c unlimited
12612         sleep 60 &
12613         SLEEPPID=$!
12614
12615         sleep 1
12616
12617         kill -s 11 $SLEEPPID
12618         wait $SLEEPPID
12619         if [ -e $file ]; then
12620                 size=`stat -c%s $file`
12621                 [ $size -eq 0 ] && error "Fail to create core file $file"
12622         else
12623                 error "Fail to create core file $file"
12624         fi
12625         rm -f $file
12626         sysctl -w kernel.core_pattern=$save_pattern
12627         sysctl -w kernel.core_uses_pid=$save_uses_pid
12628         cd $CDIR
12629 }
12630 run_test 107 "Coredump on SIG"
12631
12632 test_110() {
12633         test_mkdir $DIR/$tdir
12634         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
12635         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
12636                 error "mkdir with 256 char should fail, but did not"
12637         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
12638                 error "create with 255 char failed"
12639         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
12640                 error "create with 256 char should fail, but did not"
12641
12642         ls -l $DIR/$tdir
12643         rm -rf $DIR/$tdir
12644 }
12645 run_test 110 "filename length checking"
12646
12647 test_116a() { # was previously test_116()
12648         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12649         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
12650         remote_mds_nodsh && skip "remote MDS with nodsh"
12651
12652         echo -n "Free space priority "
12653         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
12654                 head -n1
12655         declare -a AVAIL
12656         free_min_max
12657
12658         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
12659         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
12660         stack_trap simple_cleanup_common
12661
12662         # Check if we need to generate uneven OSTs
12663         test_mkdir -p $DIR/$tdir/OST${MINI}
12664         local FILL=$((MINV / 4))
12665         local DIFF=$((MAXV - MINV))
12666         local DIFF2=$((DIFF * 100 / MINV))
12667
12668         local threshold=$(do_facet $SINGLEMDS \
12669                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
12670         threshold=${threshold%%%}
12671         echo -n "Check for uneven OSTs: "
12672         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
12673
12674         if [[ $DIFF2 -gt $threshold ]]; then
12675                 echo "ok"
12676                 echo "Don't need to fill OST$MINI"
12677         else
12678                 # generate uneven OSTs. Write 2% over the QOS threshold value
12679                 echo "no"
12680                 DIFF=$((threshold - DIFF2 + 2))
12681                 DIFF2=$((MINV * DIFF / 100))
12682                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
12683                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
12684                         error "setstripe failed"
12685                 DIFF=$((DIFF2 / 2048))
12686                 i=0
12687                 while [ $i -lt $DIFF ]; do
12688                         i=$((i + 1))
12689                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
12690                                 bs=2M count=1 2>/dev/null
12691                         echo -n .
12692                 done
12693                 echo .
12694                 sync
12695                 sleep_maxage
12696                 free_min_max
12697         fi
12698
12699         DIFF=$((MAXV - MINV))
12700         DIFF2=$((DIFF * 100 / MINV))
12701         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
12702         if [ $DIFF2 -gt $threshold ]; then
12703                 echo "ok"
12704         else
12705                 skip "QOS imbalance criteria not met"
12706         fi
12707
12708         MINI1=$MINI
12709         MINV1=$MINV
12710         MAXI1=$MAXI
12711         MAXV1=$MAXV
12712
12713         # now fill using QOS
12714         $LFS setstripe -c 1 $DIR/$tdir
12715         FILL=$((FILL / 200))
12716         if [ $FILL -gt 600 ]; then
12717                 FILL=600
12718         fi
12719         echo "writing $FILL files to QOS-assigned OSTs"
12720         i=0
12721         while [ $i -lt $FILL ]; do
12722                 i=$((i + 1))
12723                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
12724                         count=1 2>/dev/null
12725                 echo -n .
12726         done
12727         echo "wrote $i 200k files"
12728         sync
12729         sleep_maxage
12730
12731         echo "Note: free space may not be updated, so measurements might be off"
12732         free_min_max
12733         DIFF2=$((MAXV - MINV))
12734         echo "free space delta: orig $DIFF final $DIFF2"
12735         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
12736         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
12737         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
12738         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
12739         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
12740         if [[ $DIFF -gt 0 ]]; then
12741                 FILL=$((DIFF2 * 100 / DIFF - 100))
12742                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
12743         fi
12744
12745         # Figure out which files were written where
12746         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12747                awk '/'$MINI1': / {print $2; exit}')
12748         echo $UUID
12749         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12750         echo "$MINC files created on smaller OST $MINI1"
12751         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
12752                awk '/'$MAXI1': / {print $2; exit}')
12753         echo $UUID
12754         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
12755         echo "$MAXC files created on larger OST $MAXI1"
12756         if [[ $MINC -gt 0 ]]; then
12757                 FILL=$((MAXC * 100 / MINC - 100))
12758                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
12759         fi
12760         [[ $MAXC -gt $MINC ]] ||
12761                 error_ignore LU-9 "stripe QOS didn't balance free space"
12762 }
12763 run_test 116a "stripe QOS: free space balance ==================="
12764
12765 test_116b() { # LU-2093
12766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12767         remote_mds_nodsh && skip "remote MDS with nodsh"
12768
12769 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
12770         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
12771                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
12772         [ -z "$old_rr" ] && skip "no QOS"
12773         do_facet $SINGLEMDS lctl set_param \
12774                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
12775         mkdir -p $DIR/$tdir
12776         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
12777         createmany -o $DIR/$tdir/f- 20 || error "can't create"
12778         do_facet $SINGLEMDS lctl set_param fail_loc=0
12779         rm -rf $DIR/$tdir
12780         do_facet $SINGLEMDS lctl set_param \
12781                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
12782 }
12783 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
12784
12785 test_117() # bug 10891
12786 {
12787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12788
12789         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
12790         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
12791         lctl set_param fail_loc=0x21e
12792         > $DIR/$tfile || error "truncate failed"
12793         lctl set_param fail_loc=0
12794         echo "Truncate succeeded."
12795         rm -f $DIR/$tfile
12796 }
12797 run_test 117 "verify osd extend =========="
12798
12799 NO_SLOW_RESENDCOUNT=4
12800 export OLD_RESENDCOUNT=""
12801 set_resend_count () {
12802         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
12803         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
12804         lctl set_param -n $PROC_RESENDCOUNT $1
12805         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
12806 }
12807
12808 # for reduce test_118* time (b=14842)
12809 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12810
12811 # Reset async IO behavior after error case
12812 reset_async() {
12813         FILE=$DIR/reset_async
12814
12815         # Ensure all OSCs are cleared
12816         $LFS setstripe -c -1 $FILE
12817         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
12818         sync
12819         rm $FILE
12820 }
12821
12822 test_118a() #bug 11710
12823 {
12824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12825
12826         reset_async
12827
12828         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12829         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12830         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
12831
12832         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12833                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12834                 return 1;
12835         fi
12836         rm -f $DIR/$tfile
12837 }
12838 run_test 118a "verify O_SYNC works =========="
12839
12840 test_118b()
12841 {
12842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12843         remote_ost_nodsh && skip "remote OST with nodsh"
12844
12845         reset_async
12846
12847         #define OBD_FAIL_SRV_ENOENT 0x217
12848         set_nodes_failloc "$(osts_nodes)" 0x217
12849         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12850         RC=$?
12851         set_nodes_failloc "$(osts_nodes)" 0
12852         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12853         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12854                     grep -c writeback)
12855
12856         if [[ $RC -eq 0 ]]; then
12857                 error "Must return error due to dropped pages, rc=$RC"
12858                 return 1;
12859         fi
12860
12861         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12862                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12863                 return 1;
12864         fi
12865
12866         echo "Dirty pages not leaked on ENOENT"
12867
12868         # Due to the above error the OSC will issue all RPCs syncronously
12869         # until a subsequent RPC completes successfully without error.
12870         $MULTIOP $DIR/$tfile Ow4096yc
12871         rm -f $DIR/$tfile
12872
12873         return 0
12874 }
12875 run_test 118b "Reclaim dirty pages on fatal error =========="
12876
12877 test_118c()
12878 {
12879         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12880
12881         # for 118c, restore the original resend count, LU-1940
12882         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
12883                                 set_resend_count $OLD_RESENDCOUNT
12884         remote_ost_nodsh && skip "remote OST with nodsh"
12885
12886         reset_async
12887
12888         #define OBD_FAIL_OST_EROFS               0x216
12889         set_nodes_failloc "$(osts_nodes)" 0x216
12890
12891         # multiop should block due to fsync until pages are written
12892         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12893         MULTIPID=$!
12894         sleep 1
12895
12896         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12897                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12898         fi
12899
12900         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12901                     grep -c writeback)
12902         if [[ $WRITEBACK -eq 0 ]]; then
12903                 error "No page in writeback, writeback=$WRITEBACK"
12904         fi
12905
12906         set_nodes_failloc "$(osts_nodes)" 0
12907         wait $MULTIPID
12908         RC=$?
12909         if [[ $RC -ne 0 ]]; then
12910                 error "Multiop fsync failed, rc=$RC"
12911         fi
12912
12913         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12914         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12915                     grep -c writeback)
12916         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12917                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12918         fi
12919
12920         rm -f $DIR/$tfile
12921         echo "Dirty pages flushed via fsync on EROFS"
12922         return 0
12923 }
12924 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
12925
12926 # continue to use small resend count to reduce test_118* time (b=14842)
12927 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
12928
12929 test_118d()
12930 {
12931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12932         remote_ost_nodsh && skip "remote OST with nodsh"
12933
12934         reset_async
12935
12936         #define OBD_FAIL_OST_BRW_PAUSE_BULK
12937         set_nodes_failloc "$(osts_nodes)" 0x214
12938         # multiop should block due to fsync until pages are written
12939         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
12940         MULTIPID=$!
12941         sleep 1
12942
12943         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
12944                 error "Multiop failed to block on fsync, pid=$MULTIPID"
12945         fi
12946
12947         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12948                     grep -c writeback)
12949         if [[ $WRITEBACK -eq 0 ]]; then
12950                 error "No page in writeback, writeback=$WRITEBACK"
12951         fi
12952
12953         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
12954         set_nodes_failloc "$(osts_nodes)" 0
12955
12956         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12957         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12958                     grep -c writeback)
12959         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12960                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12961         fi
12962
12963         rm -f $DIR/$tfile
12964         echo "Dirty pages gaurenteed flushed via fsync"
12965         return 0
12966 }
12967 run_test 118d "Fsync validation inject a delay of the bulk =========="
12968
12969 test_118f() {
12970         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12971
12972         reset_async
12973
12974         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
12975         lctl set_param fail_loc=0x8000040a
12976
12977         # Should simulate EINVAL error which is fatal
12978         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
12979         RC=$?
12980         if [[ $RC -eq 0 ]]; then
12981                 error "Must return error due to dropped pages, rc=$RC"
12982         fi
12983
12984         lctl set_param fail_loc=0x0
12985
12986         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
12987         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
12988         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
12989                     grep -c writeback)
12990         if [[ $LOCKED -ne 0 ]]; then
12991                 error "Locked pages remain in cache, locked=$LOCKED"
12992         fi
12993
12994         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
12995                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
12996         fi
12997
12998         rm -f $DIR/$tfile
12999         echo "No pages locked after fsync"
13000
13001         reset_async
13002         return 0
13003 }
13004 run_test 118f "Simulate unrecoverable OSC side error =========="
13005
13006 test_118g() {
13007         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13008
13009         reset_async
13010
13011         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
13012         lctl set_param fail_loc=0x406
13013
13014         # simulate local -ENOMEM
13015         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13016         RC=$?
13017
13018         lctl set_param fail_loc=0
13019         if [[ $RC -eq 0 ]]; then
13020                 error "Must return error due to dropped pages, rc=$RC"
13021         fi
13022
13023         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13024         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13025         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13026                         grep -c writeback)
13027         if [[ $LOCKED -ne 0 ]]; then
13028                 error "Locked pages remain in cache, locked=$LOCKED"
13029         fi
13030
13031         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13032                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13033         fi
13034
13035         rm -f $DIR/$tfile
13036         echo "No pages locked after fsync"
13037
13038         reset_async
13039         return 0
13040 }
13041 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
13042
13043 test_118h() {
13044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13045         remote_ost_nodsh && skip "remote OST with nodsh"
13046
13047         reset_async
13048
13049         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13050         set_nodes_failloc "$(osts_nodes)" 0x20e
13051         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13052         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13053         RC=$?
13054
13055         set_nodes_failloc "$(osts_nodes)" 0
13056         if [[ $RC -eq 0 ]]; then
13057                 error "Must return error due to dropped pages, rc=$RC"
13058         fi
13059
13060         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13061         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13062         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
13063                     grep -c writeback)
13064         if [[ $LOCKED -ne 0 ]]; then
13065                 error "Locked pages remain in cache, locked=$LOCKED"
13066         fi
13067
13068         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13069                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13070         fi
13071
13072         rm -f $DIR/$tfile
13073         echo "No pages locked after fsync"
13074
13075         return 0
13076 }
13077 run_test 118h "Verify timeout in handling recoverables errors  =========="
13078
13079 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13080
13081 test_118i() {
13082         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13083         remote_ost_nodsh && skip "remote OST with nodsh"
13084
13085         reset_async
13086
13087         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13088         set_nodes_failloc "$(osts_nodes)" 0x20e
13089
13090         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
13091         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
13092         PID=$!
13093         sleep 5
13094         set_nodes_failloc "$(osts_nodes)" 0
13095
13096         wait $PID
13097         RC=$?
13098         if [[ $RC -ne 0 ]]; then
13099                 error "got error, but should be not, rc=$RC"
13100         fi
13101
13102         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13103         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13104         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13105         if [[ $LOCKED -ne 0 ]]; then
13106                 error "Locked pages remain in cache, locked=$LOCKED"
13107         fi
13108
13109         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13110                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13111         fi
13112
13113         rm -f $DIR/$tfile
13114         echo "No pages locked after fsync"
13115
13116         return 0
13117 }
13118 run_test 118i "Fix error before timeout in recoverable error  =========="
13119
13120 [ "$SLOW" = "no" ] && set_resend_count 4
13121
13122 test_118j() {
13123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13124         remote_ost_nodsh && skip "remote OST with nodsh"
13125
13126         reset_async
13127
13128         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
13129         set_nodes_failloc "$(osts_nodes)" 0x220
13130
13131         # return -EIO from OST
13132         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
13133         RC=$?
13134         set_nodes_failloc "$(osts_nodes)" 0x0
13135         if [[ $RC -eq 0 ]]; then
13136                 error "Must return error due to dropped pages, rc=$RC"
13137         fi
13138
13139         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
13140         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
13141         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
13142         if [[ $LOCKED -ne 0 ]]; then
13143                 error "Locked pages remain in cache, locked=$LOCKED"
13144         fi
13145
13146         # in recoverable error on OST we want resend and stay until it finished
13147         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
13148                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
13149         fi
13150
13151         rm -f $DIR/$tfile
13152         echo "No pages locked after fsync"
13153
13154         return 0
13155 }
13156 run_test 118j "Simulate unrecoverable OST side error =========="
13157
13158 test_118k()
13159 {
13160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13161         remote_ost_nodsh && skip "remote OSTs with nodsh"
13162
13163         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
13164         set_nodes_failloc "$(osts_nodes)" 0x20e
13165         test_mkdir $DIR/$tdir
13166
13167         for ((i=0;i<10;i++)); do
13168                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
13169                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
13170                 SLEEPPID=$!
13171                 sleep 0.500s
13172                 kill $SLEEPPID
13173                 wait $SLEEPPID
13174         done
13175
13176         set_nodes_failloc "$(osts_nodes)" 0
13177         rm -rf $DIR/$tdir
13178 }
13179 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
13180
13181 test_118l() # LU-646
13182 {
13183         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13184
13185         test_mkdir $DIR/$tdir
13186         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
13187         rm -rf $DIR/$tdir
13188 }
13189 run_test 118l "fsync dir"
13190
13191 test_118m() # LU-3066
13192 {
13193         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13194
13195         test_mkdir $DIR/$tdir
13196         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
13197         rm -rf $DIR/$tdir
13198 }
13199 run_test 118m "fdatasync dir ========="
13200
13201 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
13202
13203 test_118n()
13204 {
13205         local begin
13206         local end
13207
13208         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13209         remote_ost_nodsh && skip "remote OSTs with nodsh"
13210
13211         # Sleep to avoid a cached response.
13212         #define OBD_STATFS_CACHE_SECONDS 1
13213         sleep 2
13214
13215         # Inject a 10 second delay in the OST_STATFS handler.
13216         #define OBD_FAIL_OST_STATFS_DELAY 0x242
13217         set_nodes_failloc "$(osts_nodes)" 0x242
13218
13219         begin=$SECONDS
13220         stat --file-system $MOUNT > /dev/null
13221         end=$SECONDS
13222
13223         set_nodes_failloc "$(osts_nodes)" 0
13224
13225         if ((end - begin > 20)); then
13226             error "statfs took $((end - begin)) seconds, expected 10"
13227         fi
13228 }
13229 run_test 118n "statfs() sends OST_STATFS requests in parallel"
13230
13231 test_119a() # bug 11737
13232 {
13233         BSIZE=$((512 * 1024))
13234         directio write $DIR/$tfile 0 1 $BSIZE
13235         # We ask to read two blocks, which is more than a file size.
13236         # directio will indicate an error when requested and actual
13237         # sizes aren't equeal (a normal situation in this case) and
13238         # print actual read amount.
13239         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
13240         if [ "$NOB" != "$BSIZE" ]; then
13241                 error "read $NOB bytes instead of $BSIZE"
13242         fi
13243         rm -f $DIR/$tfile
13244 }
13245 run_test 119a "Short directIO read must return actual read amount"
13246
13247 test_119b() # bug 11737
13248 {
13249         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
13250
13251         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
13252         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
13253         sync
13254         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
13255                 error "direct read failed"
13256         rm -f $DIR/$tfile
13257 }
13258 run_test 119b "Sparse directIO read must return actual read amount"
13259
13260 test_119c() # bug 13099
13261 {
13262         BSIZE=1048576
13263         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
13264         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
13265         rm -f $DIR/$tfile
13266 }
13267 run_test 119c "Testing for direct read hitting hole"
13268
13269 test_119d() # bug 15950
13270 {
13271         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13272
13273         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
13274         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
13275         BSIZE=1048576
13276         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
13277         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
13278         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
13279         lctl set_param fail_loc=0x40d
13280         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
13281         pid_dio=$!
13282         sleep 1
13283         cat $DIR/$tfile > /dev/null &
13284         lctl set_param fail_loc=0
13285         pid_reads=$!
13286         wait $pid_dio
13287         log "the DIO writes have completed, now wait for the reads (should not block very long)"
13288         sleep 2
13289         [ -n "`ps h -p $pid_reads -o comm`" ] && \
13290         error "the read rpcs have not completed in 2s"
13291         rm -f $DIR/$tfile
13292         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
13293 }
13294 run_test 119d "The DIO path should try to send a new rpc once one is completed"
13295
13296 test_120a() {
13297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13298         remote_mds_nodsh && skip "remote MDS with nodsh"
13299         test_mkdir -i0 -c1 $DIR/$tdir
13300         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13301                 skip_env "no early lock cancel on server"
13302
13303         lru_resize_disable mdc
13304         lru_resize_disable osc
13305         cancel_lru_locks mdc
13306         # asynchronous object destroy at MDT could cause bl ast to client
13307         cancel_lru_locks osc
13308
13309         stat $DIR/$tdir > /dev/null
13310         can1=$(do_facet mds1 \
13311                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13312                awk '/ldlm_cancel/ {print $2}')
13313         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13314                awk '/ldlm_bl_callback/ {print $2}')
13315         test_mkdir -i0 -c1 $DIR/$tdir/d1
13316         can2=$(do_facet mds1 \
13317                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13318                awk '/ldlm_cancel/ {print $2}')
13319         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13320                awk '/ldlm_bl_callback/ {print $2}')
13321         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13322         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13323         lru_resize_enable mdc
13324         lru_resize_enable osc
13325 }
13326 run_test 120a "Early Lock Cancel: mkdir test"
13327
13328 test_120b() {
13329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13330         remote_mds_nodsh && skip "remote MDS with nodsh"
13331         test_mkdir $DIR/$tdir
13332         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13333                 skip_env "no early lock cancel on server"
13334
13335         lru_resize_disable mdc
13336         lru_resize_disable osc
13337         cancel_lru_locks mdc
13338         stat $DIR/$tdir > /dev/null
13339         can1=$(do_facet $SINGLEMDS \
13340                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13341                awk '/ldlm_cancel/ {print $2}')
13342         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13343                awk '/ldlm_bl_callback/ {print $2}')
13344         touch $DIR/$tdir/f1
13345         can2=$(do_facet $SINGLEMDS \
13346                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13347                awk '/ldlm_cancel/ {print $2}')
13348         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13349                awk '/ldlm_bl_callback/ {print $2}')
13350         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13351         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13352         lru_resize_enable mdc
13353         lru_resize_enable osc
13354 }
13355 run_test 120b "Early Lock Cancel: create test"
13356
13357 test_120c() {
13358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13359         remote_mds_nodsh && skip "remote MDS with nodsh"
13360         test_mkdir -i0 -c1 $DIR/$tdir
13361         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13362                 skip "no early lock cancel on server"
13363
13364         lru_resize_disable mdc
13365         lru_resize_disable osc
13366         test_mkdir -i0 -c1 $DIR/$tdir/d1
13367         test_mkdir -i0 -c1 $DIR/$tdir/d2
13368         touch $DIR/$tdir/d1/f1
13369         cancel_lru_locks mdc
13370         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
13371         can1=$(do_facet mds1 \
13372                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13373                awk '/ldlm_cancel/ {print $2}')
13374         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13375                awk '/ldlm_bl_callback/ {print $2}')
13376         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13377         can2=$(do_facet mds1 \
13378                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13379                awk '/ldlm_cancel/ {print $2}')
13380         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13381                awk '/ldlm_bl_callback/ {print $2}')
13382         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13383         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13384         lru_resize_enable mdc
13385         lru_resize_enable osc
13386 }
13387 run_test 120c "Early Lock Cancel: link test"
13388
13389 test_120d() {
13390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13391         remote_mds_nodsh && skip "remote MDS with nodsh"
13392         test_mkdir -i0 -c1 $DIR/$tdir
13393         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13394                 skip_env "no early lock cancel on server"
13395
13396         lru_resize_disable mdc
13397         lru_resize_disable osc
13398         touch $DIR/$tdir
13399         cancel_lru_locks mdc
13400         stat $DIR/$tdir > /dev/null
13401         can1=$(do_facet mds1 \
13402                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13403                awk '/ldlm_cancel/ {print $2}')
13404         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13405                awk '/ldlm_bl_callback/ {print $2}')
13406         chmod a+x $DIR/$tdir
13407         can2=$(do_facet mds1 \
13408                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13409                awk '/ldlm_cancel/ {print $2}')
13410         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13411                awk '/ldlm_bl_callback/ {print $2}')
13412         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13413         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13414         lru_resize_enable mdc
13415         lru_resize_enable osc
13416 }
13417 run_test 120d "Early Lock Cancel: setattr test"
13418
13419 test_120e() {
13420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13421         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13422                 skip_env "no early lock cancel on server"
13423         remote_mds_nodsh && skip "remote MDS with nodsh"
13424
13425         local dlmtrace_set=false
13426
13427         test_mkdir -i0 -c1 $DIR/$tdir
13428         lru_resize_disable mdc
13429         lru_resize_disable osc
13430         ! $LCTL get_param debug | grep -q dlmtrace &&
13431                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
13432         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
13433         cancel_lru_locks mdc
13434         cancel_lru_locks osc
13435         dd if=$DIR/$tdir/f1 of=/dev/null
13436         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
13437         # XXX client can not do early lock cancel of OST lock
13438         # during unlink (LU-4206), so cancel osc lock now.
13439         sleep 2
13440         cancel_lru_locks osc
13441         can1=$(do_facet mds1 \
13442                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13443                awk '/ldlm_cancel/ {print $2}')
13444         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13445                awk '/ldlm_bl_callback/ {print $2}')
13446         unlink $DIR/$tdir/f1
13447         sleep 5
13448         can2=$(do_facet mds1 \
13449                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13450                awk '/ldlm_cancel/ {print $2}')
13451         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13452                awk '/ldlm_bl_callback/ {print $2}')
13453         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
13454                 $LCTL dk $TMP/cancel.debug.txt
13455         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
13456                 $LCTL dk $TMP/blocking.debug.txt
13457         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
13458         lru_resize_enable mdc
13459         lru_resize_enable osc
13460 }
13461 run_test 120e "Early Lock Cancel: unlink test"
13462
13463 test_120f() {
13464         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13465         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13466                 skip_env "no early lock cancel on server"
13467         remote_mds_nodsh && skip "remote MDS with nodsh"
13468
13469         test_mkdir -i0 -c1 $DIR/$tdir
13470         lru_resize_disable mdc
13471         lru_resize_disable osc
13472         test_mkdir -i0 -c1 $DIR/$tdir/d1
13473         test_mkdir -i0 -c1 $DIR/$tdir/d2
13474         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
13475         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
13476         cancel_lru_locks mdc
13477         cancel_lru_locks osc
13478         dd if=$DIR/$tdir/d1/f1 of=/dev/null
13479         dd if=$DIR/$tdir/d2/f2 of=/dev/null
13480         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
13481         # XXX client can not do early lock cancel of OST lock
13482         # during rename (LU-4206), so cancel osc lock now.
13483         sleep 2
13484         cancel_lru_locks osc
13485         can1=$(do_facet mds1 \
13486                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13487                awk '/ldlm_cancel/ {print $2}')
13488         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13489                awk '/ldlm_bl_callback/ {print $2}')
13490         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
13491         sleep 5
13492         can2=$(do_facet mds1 \
13493                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13494                awk '/ldlm_cancel/ {print $2}')
13495         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13496                awk '/ldlm_bl_callback/ {print $2}')
13497         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
13498         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
13499         lru_resize_enable mdc
13500         lru_resize_enable osc
13501 }
13502 run_test 120f "Early Lock Cancel: rename test"
13503
13504 test_120g() {
13505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13506         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
13507                 skip_env "no early lock cancel on server"
13508         remote_mds_nodsh && skip "remote MDS with nodsh"
13509
13510         lru_resize_disable mdc
13511         lru_resize_disable osc
13512         count=10000
13513         echo create $count files
13514         test_mkdir $DIR/$tdir
13515         cancel_lru_locks mdc
13516         cancel_lru_locks osc
13517         t0=$(date +%s)
13518
13519         can0=$(do_facet $SINGLEMDS \
13520                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13521                awk '/ldlm_cancel/ {print $2}')
13522         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13523                awk '/ldlm_bl_callback/ {print $2}')
13524         createmany -o $DIR/$tdir/f $count
13525         sync
13526         can1=$(do_facet $SINGLEMDS \
13527                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13528                awk '/ldlm_cancel/ {print $2}')
13529         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13530                awk '/ldlm_bl_callback/ {print $2}')
13531         t1=$(date +%s)
13532         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
13533         echo rm $count files
13534         rm -r $DIR/$tdir
13535         sync
13536         can2=$(do_facet $SINGLEMDS \
13537                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
13538                awk '/ldlm_cancel/ {print $2}')
13539         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
13540                awk '/ldlm_bl_callback/ {print $2}')
13541         t2=$(date +%s)
13542         echo total: $count removes in $((t2-t1))
13543         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
13544         sleep 2
13545         # wait for commitment of removal
13546         lru_resize_enable mdc
13547         lru_resize_enable osc
13548 }
13549 run_test 120g "Early Lock Cancel: performance test"
13550
13551 test_121() { #bug #10589
13552         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13553
13554         rm -rf $DIR/$tfile
13555         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
13556 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
13557         lctl set_param fail_loc=0x310
13558         cancel_lru_locks osc > /dev/null
13559         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
13560         lctl set_param fail_loc=0
13561         [[ $reads -eq $writes ]] ||
13562                 error "read $reads blocks, must be $writes blocks"
13563 }
13564 run_test 121 "read cancel race ========="
13565
13566 test_123a_base() { # was test 123, statahead(bug 11401)
13567         local lsx="$1"
13568
13569         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
13570
13571         SLOWOK=0
13572         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
13573                 log "testing UP system. Performance may be lower than expected."
13574                 SLOWOK=1
13575         fi
13576         running_in_vm && SLOWOK=1
13577
13578         rm -rf $DIR/$tdir
13579         test_mkdir $DIR/$tdir
13580         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13581         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13582         MULT=10
13583         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13584                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13585
13586                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13587                 lctl set_param -n llite.*.statahead_max 0
13588                 lctl get_param llite.*.statahead_max
13589                 cancel_lru_locks mdc
13590                 cancel_lru_locks osc
13591                 stime=$(date +%s)
13592                 time $lsx $DIR/$tdir | wc -l
13593                 etime=$(date +%s)
13594                 delta=$((etime - stime))
13595                 log "$lsx $i files without statahead: $delta sec"
13596                 lctl set_param llite.*.statahead_max=$max
13597
13598                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13599                          awk '/statahead.wrong:/ { print $NF }')
13600                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13601                 cancel_lru_locks mdc
13602                 cancel_lru_locks osc
13603                 stime=$(date +%s)
13604                 time $lsx $DIR/$tdir | wc -l
13605                 etime=$(date +%s)
13606                 delta_sa=$((etime - stime))
13607                 log "$lsx $i files with statahead: $delta_sa sec"
13608                 lctl get_param -n llite.*.statahead_stats
13609                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13610                          awk '/statahead.wrong:/ { print $NF }')
13611
13612                 [[ $swrong -lt $ewrong ]] &&
13613                         log "statahead was stopped, maybe too many locks held!"
13614                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13615
13616                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13617                         max=$(lctl get_param -n llite.*.statahead_max |
13618                                 head -n 1)
13619                         lctl set_param -n llite.*.statahead_max 0
13620                         lctl get_param llite.*.statahead_max
13621                         cancel_lru_locks mdc
13622                         cancel_lru_locks osc
13623                         stime=$(date +%s)
13624                         time $lsx $DIR/$tdir | wc -l
13625                         etime=$(date +%s)
13626                         delta=$((etime - stime))
13627                         log "$lsx $i files again without statahead: $delta sec"
13628                         lctl set_param llite.*.statahead_max=$max
13629                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13630                                 if [ $SLOWOK -eq 0 ]; then
13631                                         error "$lsx $i files is slower with statahead!"
13632                                 else
13633                                         log "$lsx $i files is slower with statahead!"
13634                                 fi
13635                                 break
13636                         fi
13637                 fi
13638
13639                 [ $delta -gt 20 ] && break
13640                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13641                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13642         done
13643         log "$lsx done"
13644
13645         stime=$(date +%s)
13646         rm -r $DIR/$tdir
13647         sync
13648         etime=$(date +%s)
13649         delta=$((etime - stime))
13650         log "rm -r $DIR/$tdir/: $delta seconds"
13651         log "rm done"
13652         lctl get_param -n llite.*.statahead_stats
13653 }
13654
13655 test_123aa() {
13656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13657
13658         test_123a_base "ls -l"
13659 }
13660 run_test 123aa "verify statahead work"
13661
13662 test_123ab() {
13663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13664
13665         statx_supported || skip_env "Test must be statx() syscall supported"
13666
13667         test_123a_base "$STATX -l"
13668 }
13669 run_test 123ab "verify statahead work by using statx"
13670
13671 test_123ac() {
13672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13673
13674         statx_supported || skip_env "Test must be statx() syscall supported"
13675
13676         local rpcs_before
13677         local rpcs_after
13678         local agl_before
13679         local agl_after
13680
13681         cancel_lru_locks $OSC
13682         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13683         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13684                      awk '/agl.total:/ { print $NF }')
13685         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13686         test_123a_base "$STATX --cached=always -D"
13687         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13688                     awk '/agl.total:/ { print $NF }')
13689         [ $agl_before -eq $agl_after ] ||
13690                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13691         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13692         [ $rpcs_after -eq $rpcs_before ] ||
13693                 error "$STATX should not send glimpse RPCs to $OSC"
13694 }
13695 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13696
13697 test_123b () { # statahead(bug 15027)
13698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13699
13700         test_mkdir $DIR/$tdir
13701         createmany -o $DIR/$tdir/$tfile-%d 1000
13702
13703         cancel_lru_locks mdc
13704         cancel_lru_locks osc
13705
13706 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13707         lctl set_param fail_loc=0x80000803
13708         ls -lR $DIR/$tdir > /dev/null
13709         log "ls done"
13710         lctl set_param fail_loc=0x0
13711         lctl get_param -n llite.*.statahead_stats
13712         rm -r $DIR/$tdir
13713         sync
13714
13715 }
13716 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13717
13718 test_123c() {
13719         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13720
13721         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13722         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13723         touch $DIR/$tdir.1/{1..3}
13724         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13725
13726         remount_client $MOUNT
13727
13728         $MULTIOP $DIR/$tdir.0 Q
13729
13730         # let statahead to complete
13731         ls -l $DIR/$tdir.0 > /dev/null
13732
13733         testid=$(echo $TESTNAME | tr '_' ' ')
13734         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13735                 error "statahead warning" || true
13736 }
13737 run_test 123c "Can not initialize inode warning on DNE statahead"
13738
13739 test_123d() {
13740         local num=100
13741         local swrong
13742         local ewrong
13743
13744         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13745         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13746                 error "setdirstripe $DIR/$tdir failed"
13747         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13748         remount_client $MOUNT
13749         $LCTL get_param llite.*.statahead_max
13750         $LCTL set_param llite.*.statahead_stats=0 ||
13751                 error "clear statahead_stats failed"
13752         swrong=$(lctl get_param -n llite.*.statahead_stats |
13753                  awk '/statahead.wrong:/ { print $NF }')
13754         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13755         # wait for statahead thread finished to update hit/miss stats.
13756         sleep 1
13757         $LCTL get_param -n llite.*.statahead_stats
13758         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13759                  awk '/statahead.wrong:/ { print $NF }')
13760         (( $swrong == $ewrong )) ||
13761                 log "statahead was stopped, maybe too many locks held!"
13762 }
13763 run_test 123d "Statahead on striped directories works correctly"
13764
13765 test_124a() {
13766         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13767         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13768                 skip_env "no lru resize on server"
13769
13770         local NR=2000
13771
13772         test_mkdir $DIR/$tdir
13773
13774         log "create $NR files at $DIR/$tdir"
13775         createmany -o $DIR/$tdir/f $NR ||
13776                 error "failed to create $NR files in $DIR/$tdir"
13777
13778         cancel_lru_locks mdc
13779         ls -l $DIR/$tdir > /dev/null
13780
13781         local NSDIR=""
13782         local LRU_SIZE=0
13783         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13784                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13785                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13786                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13787                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13788                         log "NSDIR=$NSDIR"
13789                         log "NS=$(basename $NSDIR)"
13790                         break
13791                 fi
13792         done
13793
13794         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13795                 skip "Not enough cached locks created!"
13796         fi
13797         log "LRU=$LRU_SIZE"
13798
13799         local SLEEP=30
13800
13801         # We know that lru resize allows one client to hold $LIMIT locks
13802         # for 10h. After that locks begin to be killed by client.
13803         local MAX_HRS=10
13804         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13805         log "LIMIT=$LIMIT"
13806         if [ $LIMIT -lt $LRU_SIZE ]; then
13807                 skip "Limit is too small $LIMIT"
13808         fi
13809
13810         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13811         # killing locks. Some time was spent for creating locks. This means
13812         # that up to the moment of sleep finish we must have killed some of
13813         # them (10-100 locks). This depends on how fast ther were created.
13814         # Many of them were touched in almost the same moment and thus will
13815         # be killed in groups.
13816         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13817
13818         # Use $LRU_SIZE_B here to take into account real number of locks
13819         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13820         local LRU_SIZE_B=$LRU_SIZE
13821         log "LVF=$LVF"
13822         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13823         log "OLD_LVF=$OLD_LVF"
13824         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13825
13826         # Let's make sure that we really have some margin. Client checks
13827         # cached locks every 10 sec.
13828         SLEEP=$((SLEEP+20))
13829         log "Sleep ${SLEEP} sec"
13830         local SEC=0
13831         while ((SEC<$SLEEP)); do
13832                 echo -n "..."
13833                 sleep 5
13834                 SEC=$((SEC+5))
13835                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13836                 echo -n "$LRU_SIZE"
13837         done
13838         echo ""
13839         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13840         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13841
13842         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13843                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13844                 unlinkmany $DIR/$tdir/f $NR
13845                 return
13846         }
13847
13848         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13849         log "unlink $NR files at $DIR/$tdir"
13850         unlinkmany $DIR/$tdir/f $NR
13851 }
13852 run_test 124a "lru resize ======================================="
13853
13854 get_max_pool_limit()
13855 {
13856         local limit=$($LCTL get_param \
13857                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13858         local max=0
13859         for l in $limit; do
13860                 if [[ $l -gt $max ]]; then
13861                         max=$l
13862                 fi
13863         done
13864         echo $max
13865 }
13866
13867 test_124b() {
13868         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13869         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13870                 skip_env "no lru resize on server"
13871
13872         LIMIT=$(get_max_pool_limit)
13873
13874         NR=$(($(default_lru_size)*20))
13875         if [[ $NR -gt $LIMIT ]]; then
13876                 log "Limit lock number by $LIMIT locks"
13877                 NR=$LIMIT
13878         fi
13879
13880         IFree=$(mdsrate_inodes_available)
13881         if [ $IFree -lt $NR ]; then
13882                 log "Limit lock number by $IFree inodes"
13883                 NR=$IFree
13884         fi
13885
13886         lru_resize_disable mdc
13887         test_mkdir -p $DIR/$tdir/disable_lru_resize
13888
13889         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13890         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13891         cancel_lru_locks mdc
13892         stime=`date +%s`
13893         PID=""
13894         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13895         PID="$PID $!"
13896         sleep 2
13897         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13898         PID="$PID $!"
13899         sleep 2
13900         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13901         PID="$PID $!"
13902         wait $PID
13903         etime=`date +%s`
13904         nolruresize_delta=$((etime-stime))
13905         log "ls -la time: $nolruresize_delta seconds"
13906         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13907         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13908
13909         lru_resize_enable mdc
13910         test_mkdir -p $DIR/$tdir/enable_lru_resize
13911
13912         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13913         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13914         cancel_lru_locks mdc
13915         stime=`date +%s`
13916         PID=""
13917         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13918         PID="$PID $!"
13919         sleep 2
13920         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13921         PID="$PID $!"
13922         sleep 2
13923         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13924         PID="$PID $!"
13925         wait $PID
13926         etime=`date +%s`
13927         lruresize_delta=$((etime-stime))
13928         log "ls -la time: $lruresize_delta seconds"
13929         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13930
13931         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13932                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13933         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13934                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13935         else
13936                 log "lru resize performs the same with no lru resize"
13937         fi
13938         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13939 }
13940 run_test 124b "lru resize (performance test) ======================="
13941
13942 test_124c() {
13943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13944         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13945                 skip_env "no lru resize on server"
13946
13947         # cache ununsed locks on client
13948         local nr=100
13949         cancel_lru_locks mdc
13950         test_mkdir $DIR/$tdir
13951         createmany -o $DIR/$tdir/f $nr ||
13952                 error "failed to create $nr files in $DIR/$tdir"
13953         ls -l $DIR/$tdir > /dev/null
13954
13955         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13956         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13957         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13958         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13959         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13960
13961         # set lru_max_age to 1 sec
13962         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13963         echo "sleep $((recalc_p * 2)) seconds..."
13964         sleep $((recalc_p * 2))
13965
13966         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13967         # restore lru_max_age
13968         $LCTL set_param -n $nsdir.lru_max_age $max_age
13969         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13970         unlinkmany $DIR/$tdir/f $nr
13971 }
13972 run_test 124c "LRUR cancel very aged locks"
13973
13974 test_124d() {
13975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13976         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13977                 skip_env "no lru resize on server"
13978
13979         # cache ununsed locks on client
13980         local nr=100
13981
13982         lru_resize_disable mdc
13983         stack_trap "lru_resize_enable mdc" EXIT
13984
13985         cancel_lru_locks mdc
13986
13987         # asynchronous object destroy at MDT could cause bl ast to client
13988         test_mkdir $DIR/$tdir
13989         createmany -o $DIR/$tdir/f $nr ||
13990                 error "failed to create $nr files in $DIR/$tdir"
13991         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13992
13993         ls -l $DIR/$tdir > /dev/null
13994
13995         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13996         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13997         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13998         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13999
14000         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14001
14002         # set lru_max_age to 1 sec
14003         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14004         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14005
14006         echo "sleep $((recalc_p * 2)) seconds..."
14007         sleep $((recalc_p * 2))
14008
14009         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14010
14011         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14012 }
14013 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14014
14015 test_125() { # 13358
14016         $LCTL get_param -n llite.*.client_type | grep -q local ||
14017                 skip "must run as local client"
14018         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14019                 skip_env "must have acl enabled"
14020         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14021
14022         test_mkdir $DIR/$tdir
14023         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14024         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14025                 error "setfacl $DIR/$tdir failed"
14026         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14027 }
14028 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14029
14030 test_126() { # bug 12829/13455
14031         $GSS && skip_env "must run as gss disabled"
14032         $LCTL get_param -n llite.*.client_type | grep -q local ||
14033                 skip "must run as local client"
14034         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14035
14036         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14037         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14038         rm -f $DIR/$tfile
14039         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14040 }
14041 run_test 126 "check that the fsgid provided by the client is taken into account"
14042
14043 test_127a() { # bug 15521
14044         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14045         local name count samp unit min max sum sumsq
14046         local tmpfile=$TMP/$tfile.tmp
14047
14048         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14049         echo "stats before reset"
14050         stack_trap "rm -f $tmpfile"
14051         local now=$(date +%s)
14052
14053         $LCTL get_param osc.*.stats | tee $tmpfile
14054
14055         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14056         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14057         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14058         local uptime=$(awk '{ print $1 }' /proc/uptime)
14059
14060         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14061         (( ${snapshot_time%\.*} >= $now - 5 &&
14062            ${snapshot_time%\.*} <= $now + 5 )) ||
14063                 error "snapshot_time=$snapshot_time != now=$now"
14064         # elapsed _should_ be from mount, but at least less than uptime
14065         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14066                 error "elapsed=$elapsed > uptime=$uptime"
14067         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14068            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14069                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14070
14071         $LCTL set_param osc.*.stats=0
14072         local reset=$(date +%s)
14073         local fsize=$((2048 * 1024))
14074
14075         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14076         cancel_lru_locks osc
14077         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14078
14079         now=$(date +%s)
14080         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14081         while read name count samp unit min max sum sumsq; do
14082                 [[ "$samp" == "samples" ]] || continue
14083
14084                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14085                 [ ! $min ] && error "Missing min value for $name proc entry"
14086                 eval $name=$count || error "Wrong proc format"
14087
14088                 case $name in
14089                 read_bytes|write_bytes)
14090                         [[ "$unit" =~ "bytes" ]] ||
14091                                 error "unit is not 'bytes': $unit"
14092                         (( $min >= 4096 )) || error "min is too small: $min"
14093                         (( $min <= $fsize )) || error "min is too big: $min"
14094                         (( $max >= 4096 )) || error "max is too small: $max"
14095                         (( $max <= $fsize )) || error "max is too big: $max"
14096                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14097                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14098                                 error "sumsquare is too small: $sumsq"
14099                         (( $sumsq <= $fsize * $fsize )) ||
14100                                 error "sumsquare is too big: $sumsq"
14101                         ;;
14102                 ost_read|ost_write)
14103                         [[ "$unit" =~ "usec" ]] ||
14104                                 error "unit is not 'usec': $unit"
14105                         ;;
14106                 *)      ;;
14107                 esac
14108         done < $tmpfile
14109
14110         #check that we actually got some stats
14111         [ "$read_bytes" ] || error "Missing read_bytes stats"
14112         [ "$write_bytes" ] || error "Missing write_bytes stats"
14113         [ "$read_bytes" != 0 ] || error "no read done"
14114         [ "$write_bytes" != 0 ] || error "no write done"
14115
14116         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14117         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14118         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14119
14120         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14121         (( ${snapshot_time%\.*} >= $now - 5 &&
14122            ${snapshot_time%\.*} <= $now + 5 )) ||
14123                 error "reset snapshot_time=$snapshot_time != now=$now"
14124         # elapsed should be from time of stats reset
14125         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14126            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14127                 error "reset elapsed=$elapsed > $now - $reset"
14128         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14129            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14130                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14131 }
14132 run_test 127a "verify the client stats are sane"
14133
14134 test_127b() { # bug LU-333
14135         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14136         local name count samp unit min max sum sumsq
14137
14138         echo "stats before reset"
14139         $LCTL get_param llite.*.stats
14140         $LCTL set_param llite.*.stats=0
14141
14142         # perform 2 reads and writes so MAX is different from SUM.
14143         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14144         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14145         cancel_lru_locks osc
14146         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14147         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14148
14149         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14150         stack_trap "rm -f $TMP/$tfile.tmp"
14151         while read name count samp unit min max sum sumsq; do
14152                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14153                 eval $name=$count || error "Wrong proc format"
14154
14155                 case $name in
14156                 read_bytes|write_bytes)
14157                         [[ "$unit" =~ "bytes" ]] ||
14158                                 error "unit is not 'bytes': $unit"
14159                         (( $count == 2 )) || error "count is not 2: $count"
14160                         (( $min == $PAGE_SIZE )) ||
14161                                 error "min is not $PAGE_SIZE: $min"
14162                         (( $max == $PAGE_SIZE )) ||
14163                                 error "max is not $PAGE_SIZE: $max"
14164                         (( $sum == $PAGE_SIZE * 2 )) ||
14165                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14166                         ;;
14167                 read|write)
14168                         [[ "$unit" =~ "usec" ]] ||
14169                                 error "unit is not 'usec': $unit"
14170                         ;;
14171                 *)      ;;
14172                 esac
14173         done < $TMP/$tfile.tmp
14174
14175         #check that we actually got some stats
14176         [ "$read_bytes" ] || error "Missing read_bytes stats"
14177         [ "$write_bytes" ] || error "Missing write_bytes stats"
14178         [ "$read_bytes" != 0 ] || error "no read done"
14179         [ "$write_bytes" != 0 ] || error "no write done"
14180 }
14181 run_test 127b "verify the llite client stats are sane"
14182
14183 test_127c() { # LU-12394
14184         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14185         local size
14186         local bsize
14187         local reads
14188         local writes
14189         local count
14190
14191         $LCTL set_param llite.*.extents_stats=1
14192         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14193
14194         # Use two stripes so there is enough space in default config
14195         $LFS setstripe -c 2 $DIR/$tfile
14196
14197         # Extent stats start at 0-4K and go in power of two buckets
14198         # LL_HIST_START = 12 --> 2^12 = 4K
14199         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14200         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14201         # small configs
14202         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14203                 do
14204                 # Write and read, 2x each, second time at a non-zero offset
14205                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14206                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14207                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14208                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14209                 rm -f $DIR/$tfile
14210         done
14211
14212         $LCTL get_param llite.*.extents_stats
14213
14214         count=2
14215         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14216                 do
14217                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14218                                 grep -m 1 $bsize)
14219                 reads=$(echo $bucket | awk '{print $5}')
14220                 writes=$(echo $bucket | awk '{print $9}')
14221                 [ "$reads" -eq $count ] ||
14222                         error "$reads reads in < $bsize bucket, expect $count"
14223                 [ "$writes" -eq $count ] ||
14224                         error "$writes writes in < $bsize bucket, expect $count"
14225         done
14226
14227         # Test mmap write and read
14228         $LCTL set_param llite.*.extents_stats=c
14229         size=512
14230         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14231         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14232         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14233
14234         $LCTL get_param llite.*.extents_stats
14235
14236         count=$(((size*1024) / PAGE_SIZE))
14237
14238         bsize=$((2 * PAGE_SIZE / 1024))K
14239
14240         bucket=$($LCTL get_param -n llite.*.extents_stats |
14241                         grep -m 1 $bsize)
14242         reads=$(echo $bucket | awk '{print $5}')
14243         writes=$(echo $bucket | awk '{print $9}')
14244         # mmap writes fault in the page first, creating an additonal read
14245         [ "$reads" -eq $((2 * count)) ] ||
14246                 error "$reads reads in < $bsize bucket, expect $count"
14247         [ "$writes" -eq $count ] ||
14248                 error "$writes writes in < $bsize bucket, expect $count"
14249 }
14250 run_test 127c "test llite extent stats with regular & mmap i/o"
14251
14252 test_128() { # bug 15212
14253         touch $DIR/$tfile
14254         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14255                 find $DIR/$tfile
14256                 find $DIR/$tfile
14257         EOF
14258
14259         result=$(grep error $TMP/$tfile.log)
14260         rm -f $DIR/$tfile $TMP/$tfile.log
14261         [ -z "$result" ] ||
14262                 error "consecutive find's under interactive lfs failed"
14263 }
14264 run_test 128 "interactive lfs for 2 consecutive find's"
14265
14266 set_dir_limits () {
14267         local mntdev
14268         local canondev
14269         local node
14270
14271         local ldproc=/proc/fs/ldiskfs
14272         local facets=$(get_facets MDS)
14273
14274         for facet in ${facets//,/ }; do
14275                 canondev=$(ldiskfs_canon \
14276                            *.$(convert_facet2label $facet).mntdev $facet)
14277                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14278                         ldproc=/sys/fs/ldiskfs
14279                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14280                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14281         done
14282 }
14283
14284 check_mds_dmesg() {
14285         local facets=$(get_facets MDS)
14286         for facet in ${facets//,/ }; do
14287                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14288         done
14289         return 1
14290 }
14291
14292 test_129() {
14293         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14294         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14295                 skip "Need MDS version with at least 2.5.56"
14296         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14297                 skip_env "ldiskfs only test"
14298         fi
14299         remote_mds_nodsh && skip "remote MDS with nodsh"
14300
14301         local ENOSPC=28
14302         local has_warning=false
14303
14304         rm -rf $DIR/$tdir
14305         mkdir -p $DIR/$tdir
14306
14307         # block size of mds1
14308         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14309         set_dir_limits $maxsize $((maxsize * 6 / 8))
14310         stack_trap "set_dir_limits 0 0"
14311         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14312         local dirsize=$(stat -c%s "$DIR/$tdir")
14313         local nfiles=0
14314         while (( $dirsize <= $maxsize )); do
14315                 $MCREATE $DIR/$tdir/file_base_$nfiles
14316                 rc=$?
14317                 # check two errors:
14318                 # ENOSPC for ext4 max_dir_size, which has been used since
14319                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14320                 if (( rc == ENOSPC )); then
14321                         set_dir_limits 0 0
14322                         echo "rc=$rc returned as expected after $nfiles files"
14323
14324                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14325                                 error "create failed w/o dir size limit"
14326
14327                         # messages may be rate limited if test is run repeatedly
14328                         check_mds_dmesg '"is approaching max"' ||
14329                                 echo "warning message should be output"
14330                         check_mds_dmesg '"has reached max"' ||
14331                                 echo "reached message should be output"
14332
14333                         dirsize=$(stat -c%s "$DIR/$tdir")
14334
14335                         [[ $dirsize -ge $maxsize ]] && return 0
14336                         error "dirsize $dirsize < $maxsize after $nfiles files"
14337                 elif (( rc != 0 )); then
14338                         break
14339                 fi
14340                 nfiles=$((nfiles + 1))
14341                 dirsize=$(stat -c%s "$DIR/$tdir")
14342         done
14343
14344         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14345 }
14346 run_test 129 "test directory size limit ========================"
14347
14348 OLDIFS="$IFS"
14349 cleanup_130() {
14350         trap 0
14351         IFS="$OLDIFS"
14352 }
14353
14354 test_130a() {
14355         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14356         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14357
14358         trap cleanup_130 EXIT RETURN
14359
14360         local fm_file=$DIR/$tfile
14361         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14362         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14363                 error "dd failed for $fm_file"
14364
14365         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14366         filefrag -ves $fm_file
14367         local rc=$?
14368         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14369                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14370         (( $rc == 0 )) || error "filefrag $fm_file failed"
14371
14372         filefrag_op=$(filefrag -ve -k $fm_file |
14373                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14374         local lun=$($LFS getstripe -i $fm_file)
14375
14376         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14377         IFS=$'\n'
14378         local tot_len=0
14379         for line in $filefrag_op; do
14380                 local frag_lun=$(echo $line | cut -d: -f5)
14381                 local ext_len=$(echo $line | cut -d: -f4)
14382
14383                 if (( $frag_lun != $lun )); then
14384                         error "FIEMAP on 1-stripe file($fm_file) failed"
14385                         return
14386                 fi
14387                 (( tot_len += ext_len ))
14388         done
14389
14390         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14391                 error "FIEMAP on 1-stripe file($fm_file) failed"
14392                 return
14393         fi
14394
14395         echo "FIEMAP on single striped file succeeded"
14396 }
14397 run_test 130a "FIEMAP (1-stripe file)"
14398
14399 test_130b() {
14400         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14401
14402         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14403         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14404         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14405                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14406
14407         trap cleanup_130 EXIT RETURN
14408
14409         local fm_file=$DIR/$tfile
14410         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14411                 error "setstripe on $fm_file"
14412
14413         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14414                 error "dd failed on $fm_file"
14415
14416         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14417         filefrag_op=$(filefrag -ve -k $fm_file |
14418                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14419
14420         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14421                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14422
14423         IFS=$'\n'
14424         local tot_len=0
14425         local num_luns=1
14426
14427         for line in $filefrag_op; do
14428                 local frag_lun=$(echo $line | cut -d: -f5 |
14429                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14430                 local ext_len=$(echo $line | cut -d: -f4)
14431                 if (( $frag_lun != $last_lun )); then
14432                         if (( tot_len != 1024 )); then
14433                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14434                                 return
14435                         else
14436                                 (( num_luns += 1 ))
14437                                 tot_len=0
14438                         fi
14439                 fi
14440                 (( tot_len += ext_len ))
14441                 last_lun=$frag_lun
14442         done
14443         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14444                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14445                 return
14446         fi
14447
14448         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14449 }
14450 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14451
14452 test_130c() {
14453         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14454
14455         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14456         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14457         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14458                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14459
14460         trap cleanup_130 EXIT RETURN
14461
14462         local fm_file=$DIR/$tfile
14463         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14464
14465         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14466                 error "dd failed on $fm_file"
14467
14468         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14469         filefrag_op=$(filefrag -ve -k $fm_file |
14470                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14471
14472         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14473                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14474
14475         IFS=$'\n'
14476         local tot_len=0
14477         local num_luns=1
14478         for line in $filefrag_op; do
14479                 local frag_lun=$(echo $line | cut -d: -f5 |
14480                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14481                 local ext_len=$(echo $line | cut -d: -f4)
14482                 if (( $frag_lun != $last_lun )); then
14483                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14484                         if (( logical != 512 )); then
14485                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14486                                 return
14487                         fi
14488                         if (( tot_len != 512 )); then
14489                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14490                                 return
14491                         else
14492                                 (( num_luns += 1 ))
14493                                 tot_len=0
14494                         fi
14495                 fi
14496                 (( tot_len += ext_len ))
14497                 last_lun=$frag_lun
14498         done
14499         if (( num_luns != 2 || tot_len != 512 )); then
14500                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14501                 return
14502         fi
14503
14504         echo "FIEMAP on 2-stripe file with hole succeeded"
14505 }
14506 run_test 130c "FIEMAP (2-stripe file with hole)"
14507
14508 test_130d() {
14509         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14510
14511         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14512         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14513         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14514                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14515
14516         trap cleanup_130 EXIT RETURN
14517
14518         local fm_file=$DIR/$tfile
14519         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14520                         error "setstripe on $fm_file"
14521
14522         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14523         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14524                 error "dd failed on $fm_file"
14525
14526         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14527         filefrag_op=$(filefrag -ve -k $fm_file |
14528                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14529
14530         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14531                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14532
14533         IFS=$'\n'
14534         local tot_len=0
14535         local num_luns=1
14536         for line in $filefrag_op; do
14537                 local frag_lun=$(echo $line | cut -d: -f5 |
14538                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14539                 local ext_len=$(echo $line | cut -d: -f4)
14540                 if (( $frag_lun != $last_lun )); then
14541                         if (( tot_len != 1024 )); then
14542                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14543                                 return
14544                         else
14545                                 (( num_luns += 1 ))
14546                                 local tot_len=0
14547                         fi
14548                 fi
14549                 (( tot_len += ext_len ))
14550                 last_lun=$frag_lun
14551         done
14552         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14553                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14554                 return
14555         fi
14556
14557         echo "FIEMAP on N-stripe file succeeded"
14558 }
14559 run_test 130d "FIEMAP (N-stripe file)"
14560
14561 test_130e() {
14562         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14563
14564         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14565         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14566         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14567                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14568
14569         trap cleanup_130 EXIT RETURN
14570
14571         local fm_file=$DIR/$tfile
14572         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14573
14574         local num_blks=512
14575         local expected_len=$(( (num_blks / 2) * 64 ))
14576         for ((i = 0; i < $num_blks; i++)); do
14577                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14578                         conv=notrunc > /dev/null 2>&1
14579         done
14580
14581         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14582         filefrag_op=$(filefrag -ve -k $fm_file |
14583                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14584
14585         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14586
14587         IFS=$'\n'
14588         local tot_len=0
14589         local num_luns=1
14590         for line in $filefrag_op; do
14591                 local frag_lun=$(echo $line | cut -d: -f5)
14592                 local ext_len=$(echo $line | cut -d: -f4)
14593                 if (( $frag_lun != $last_lun )); then
14594                         if (( tot_len != $expected_len )); then
14595                                 error "OST$last_lun $tot_len != $expected_len"
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 != $expected_len )); then
14605                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14606         fi
14607
14608         echo "FIEMAP with continuation calls succeeded"
14609 }
14610 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14611
14612 test_130f() {
14613         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14614         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14615         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14616                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14617
14618         local fm_file=$DIR/$tfile
14619         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14620                 error "multiop create with lov_delay_create on $fm_file"
14621
14622         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14623         filefrag_extents=$(filefrag -vek $fm_file |
14624                            awk '/extents? found/ { print $2 }')
14625         if (( $filefrag_extents != 0 )); then
14626                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14627         fi
14628
14629         rm -f $fm_file
14630 }
14631 run_test 130f "FIEMAP (unstriped file)"
14632
14633 test_130g() {
14634         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14635                 skip "Need MDS version with at least 2.12.53 for overstriping"
14636         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14637         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14638         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14639                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14640
14641         local file=$DIR/$tfile
14642         local nr=$((OSTCOUNT * 100))
14643
14644         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14645
14646         stack_trap "rm -f $file"
14647         dd if=/dev/zero of=$file count=$nr bs=1M
14648         sync
14649         nr=$($LFS getstripe -c $file)
14650
14651         local extents=$(filefrag -v $file |
14652                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14653
14654         echo "filefrag list $extents extents in file with stripecount $nr"
14655         if (( extents < nr )); then
14656                 $LFS getstripe $file
14657                 filefrag -v $file
14658                 error "filefrag printed $extents < $nr extents"
14659         fi
14660 }
14661 run_test 130g "FIEMAP (overstripe file)"
14662
14663 # Test for writev/readv
14664 test_131a() {
14665         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14666                 error "writev test failed"
14667         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14668                 error "readv failed"
14669         rm -f $DIR/$tfile
14670 }
14671 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14672
14673 test_131b() {
14674         local fsize=$((524288 + 1048576 + 1572864))
14675         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14676                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14677                         error "append writev test failed"
14678
14679         ((fsize += 1572864 + 1048576))
14680         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14681                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14682                         error "append writev test failed"
14683         rm -f $DIR/$tfile
14684 }
14685 run_test 131b "test append writev"
14686
14687 test_131c() {
14688         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14689         error "NOT PASS"
14690 }
14691 run_test 131c "test read/write on file w/o objects"
14692
14693 test_131d() {
14694         rwv -f $DIR/$tfile -w -n 1 1572864
14695         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14696         if [ "$NOB" != 1572864 ]; then
14697                 error "Short read filed: read $NOB bytes instead of 1572864"
14698         fi
14699         rm -f $DIR/$tfile
14700 }
14701 run_test 131d "test short read"
14702
14703 test_131e() {
14704         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14705         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14706         error "read hitting hole failed"
14707         rm -f $DIR/$tfile
14708 }
14709 run_test 131e "test read hitting hole"
14710
14711 check_stats() {
14712         local facet=$1
14713         local op=$2
14714         local want=${3:-0}
14715         local res
14716
14717         # open             11 samples [usecs] 468 4793 13658 35791898
14718         case $facet in
14719         mds*) res=($(do_facet $facet \
14720                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14721                  ;;
14722         ost*) res=($(do_facet $facet \
14723                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14724                  ;;
14725         *) error "Wrong facet '$facet'" ;;
14726         esac
14727         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14728         # if $want is zero, it means any stat increment is ok.
14729         if (( $want > 0 )); then
14730                 local count=${res[1]}
14731
14732                 if (( $count != $want )); then
14733                         if [[ $facet =~ "mds" ]]; then
14734                                 do_nodes $(comma_list $(mdts_nodes)) \
14735                                         $LCTL get_param mdt.*.md_stats
14736                         else
14737                                 do_nodes $(comma_list $(osts-nodes)) \
14738                                         $LCTL get_param obdfilter.*.stats
14739                         fi
14740                         error "The $op counter on $facet is $count, not $want"
14741                 fi
14742         fi
14743 }
14744
14745 test_133a() {
14746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14747         remote_ost_nodsh && skip "remote OST with nodsh"
14748         remote_mds_nodsh && skip "remote MDS with nodsh"
14749         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14750                 skip_env "MDS doesn't support rename stats"
14751
14752         local testdir=$DIR/${tdir}/stats_testdir
14753
14754         mkdir -p $DIR/${tdir}
14755
14756         # clear stats.
14757         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14758         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14759
14760         # verify mdt stats first.
14761         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14762         check_stats $SINGLEMDS "mkdir" 1
14763
14764         # clear "open" from "lfs mkdir" above
14765         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14766         touch ${testdir}/${tfile} || error "touch failed"
14767         check_stats $SINGLEMDS "open" 1
14768         check_stats $SINGLEMDS "close" 1
14769         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14770                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14771                 check_stats $SINGLEMDS "mknod" 2
14772         }
14773         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14774         check_stats $SINGLEMDS "unlink" 1
14775         rm -f ${testdir}/${tfile} || error "file remove failed"
14776         check_stats $SINGLEMDS "unlink" 2
14777
14778         # remove working dir and check mdt stats again.
14779         rmdir ${testdir} || error "rmdir failed"
14780         check_stats $SINGLEMDS "rmdir" 1
14781
14782         local testdir1=$DIR/${tdir}/stats_testdir1
14783         mkdir_on_mdt0 -p ${testdir}
14784         mkdir_on_mdt0 -p ${testdir1}
14785         touch ${testdir1}/test1
14786         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14787         check_stats $SINGLEMDS "crossdir_rename" 1
14788
14789         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14790         check_stats $SINGLEMDS "samedir_rename" 1
14791
14792         rm -rf $DIR/${tdir}
14793 }
14794 run_test 133a "Verifying MDT stats ========================================"
14795
14796 test_133b() {
14797         local res
14798
14799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14800         remote_ost_nodsh && skip "remote OST with nodsh"
14801         remote_mds_nodsh && skip "remote MDS with nodsh"
14802
14803         local testdir=$DIR/${tdir}/stats_testdir
14804
14805         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14806         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14807         touch ${testdir}/${tfile} || error "touch failed"
14808         cancel_lru_locks mdc
14809
14810         # clear stats.
14811         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14812         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14813
14814         # extra mdt stats verification.
14815         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14816         check_stats $SINGLEMDS "setattr" 1
14817         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14818         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14819         then            # LU-1740
14820                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14821                 check_stats $SINGLEMDS "getattr" 1
14822         fi
14823         rm -rf $DIR/${tdir}
14824
14825         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14826         # so the check below is not reliable
14827         [ $MDSCOUNT -eq 1 ] || return 0
14828
14829         # Sleep to avoid a cached response.
14830         #define OBD_STATFS_CACHE_SECONDS 1
14831         sleep 2
14832         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14833         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14834         $LFS df || error "lfs failed"
14835         check_stats $SINGLEMDS "statfs" 1
14836
14837         # check aggregated statfs (LU-10018)
14838         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14839                 return 0
14840         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14841                 return 0
14842         sleep 2
14843         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14844         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14845         df $DIR
14846         check_stats $SINGLEMDS "statfs" 1
14847
14848         # We want to check that the client didn't send OST_STATFS to
14849         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14850         # extra care is needed here.
14851         if remote_mds; then
14852                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14853                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14854
14855                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14856                 [ "$res" ] && error "OST got STATFS"
14857         fi
14858
14859         return 0
14860 }
14861 run_test 133b "Verifying extra MDT stats =================================="
14862
14863 test_133c() {
14864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14865         remote_ost_nodsh && skip "remote OST with nodsh"
14866         remote_mds_nodsh && skip "remote MDS with nodsh"
14867
14868         local testdir=$DIR/$tdir/stats_testdir
14869
14870         test_mkdir -p $testdir
14871
14872         # verify obdfilter stats.
14873         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14874         sync
14875         cancel_lru_locks osc
14876         wait_delete_completed
14877
14878         # clear stats.
14879         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14880         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14881
14882         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14883                 error "dd failed"
14884         sync
14885         cancel_lru_locks osc
14886         check_stats ost1 "write" 1
14887
14888         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14889         check_stats ost1 "read" 1
14890
14891         > $testdir/$tfile || error "truncate failed"
14892         check_stats ost1 "punch" 1
14893
14894         rm -f $testdir/$tfile || error "file remove failed"
14895         wait_delete_completed
14896         check_stats ost1 "destroy" 1
14897
14898         rm -rf $DIR/$tdir
14899 }
14900 run_test 133c "Verifying OST stats ========================================"
14901
14902 order_2() {
14903         local value=$1
14904         local orig=$value
14905         local order=1
14906
14907         while [ $value -ge 2 ]; do
14908                 order=$((order*2))
14909                 value=$((value/2))
14910         done
14911
14912         if [ $orig -gt $order ]; then
14913                 order=$((order*2))
14914         fi
14915         echo $order
14916 }
14917
14918 size_in_KMGT() {
14919     local value=$1
14920     local size=('K' 'M' 'G' 'T');
14921     local i=0
14922     local size_string=$value
14923
14924     while [ $value -ge 1024 ]; do
14925         if [ $i -gt 3 ]; then
14926             #T is the biggest unit we get here, if that is bigger,
14927             #just return XXXT
14928             size_string=${value}T
14929             break
14930         fi
14931         value=$((value >> 10))
14932         if [ $value -lt 1024 ]; then
14933             size_string=${value}${size[$i]}
14934             break
14935         fi
14936         i=$((i + 1))
14937     done
14938
14939     echo $size_string
14940 }
14941
14942 get_rename_size() {
14943         local size=$1
14944         local context=${2:-.}
14945         local sample=$(do_facet $SINGLEMDS $LCTL \
14946                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14947                 grep -A1 $context |
14948                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14949         echo $sample
14950 }
14951
14952 test_133d() {
14953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14954         remote_ost_nodsh && skip "remote OST with nodsh"
14955         remote_mds_nodsh && skip "remote MDS with nodsh"
14956         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14957                 skip_env "MDS doesn't support rename stats"
14958
14959         local testdir1=$DIR/${tdir}/stats_testdir1
14960         local testdir2=$DIR/${tdir}/stats_testdir2
14961         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14962
14963         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14964
14965         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14966         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14967
14968         createmany -o $testdir1/test 512 || error "createmany failed"
14969
14970         # check samedir rename size
14971         mv ${testdir1}/test0 ${testdir1}/test_0
14972
14973         local testdir1_size=$(ls -l $DIR/${tdir} |
14974                 awk '/stats_testdir1/ {print $5}')
14975         local testdir2_size=$(ls -l $DIR/${tdir} |
14976                 awk '/stats_testdir2/ {print $5}')
14977
14978         testdir1_size=$(order_2 $testdir1_size)
14979         testdir2_size=$(order_2 $testdir2_size)
14980
14981         testdir1_size=$(size_in_KMGT $testdir1_size)
14982         testdir2_size=$(size_in_KMGT $testdir2_size)
14983
14984         echo "source rename dir size: ${testdir1_size}"
14985         echo "target rename dir size: ${testdir2_size}"
14986
14987         local cmd="do_facet $SINGLEMDS $LCTL "
14988         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14989
14990         eval $cmd || error "$cmd failed"
14991         local samedir=$($cmd | grep 'same_dir')
14992         local same_sample=$(get_rename_size $testdir1_size)
14993         [ -z "$samedir" ] && error "samedir_rename_size count error"
14994         [[ $same_sample -eq 1 ]] ||
14995                 error "samedir_rename_size error $same_sample"
14996         echo "Check same dir rename stats success"
14997
14998         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14999
15000         # check crossdir rename size
15001         mv ${testdir1}/test_0 ${testdir2}/test_0
15002
15003         testdir1_size=$(ls -l $DIR/${tdir} |
15004                 awk '/stats_testdir1/ {print $5}')
15005         testdir2_size=$(ls -l $DIR/${tdir} |
15006                 awk '/stats_testdir2/ {print $5}')
15007
15008         testdir1_size=$(order_2 $testdir1_size)
15009         testdir2_size=$(order_2 $testdir2_size)
15010
15011         testdir1_size=$(size_in_KMGT $testdir1_size)
15012         testdir2_size=$(size_in_KMGT $testdir2_size)
15013
15014         echo "source rename dir size: ${testdir1_size}"
15015         echo "target rename dir size: ${testdir2_size}"
15016
15017         eval $cmd || error "$cmd failed"
15018         local crossdir=$($cmd | grep 'crossdir')
15019         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15020         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15021         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15022         [[ $src_sample -eq 1 ]] ||
15023                 error "crossdir_rename_size error $src_sample"
15024         [[ $tgt_sample -eq 1 ]] ||
15025                 error "crossdir_rename_size error $tgt_sample"
15026         echo "Check cross dir rename stats success"
15027         rm -rf $DIR/${tdir}
15028 }
15029 run_test 133d "Verifying rename_stats ========================================"
15030
15031 test_133e() {
15032         remote_mds_nodsh && skip "remote MDS with nodsh"
15033         remote_ost_nodsh && skip "remote OST with nodsh"
15034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15035
15036         local testdir=$DIR/${tdir}/stats_testdir
15037         local ctr f0 f1 bs=32768 count=42 sum
15038
15039         mkdir -p ${testdir} || error "mkdir failed"
15040
15041         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15042
15043         for ctr in {write,read}_bytes; do
15044                 sync
15045                 cancel_lru_locks osc
15046
15047                 do_facet ost1 $LCTL set_param -n \
15048                         "obdfilter.*.exports.clear=clear"
15049
15050                 if [ $ctr = write_bytes ]; then
15051                         f0=/dev/zero
15052                         f1=${testdir}/${tfile}
15053                 else
15054                         f0=${testdir}/${tfile}
15055                         f1=/dev/null
15056                 fi
15057
15058                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15059                         error "dd failed"
15060                 sync
15061                 cancel_lru_locks osc
15062
15063                 sum=$(do_facet ost1 $LCTL get_param \
15064                         "obdfilter.*.exports.*.stats" |
15065                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15066                                 $1 == ctr { sum += $7 }
15067                                 END { printf("%0.0f", sum) }')
15068
15069                 if ((sum != bs * count)); then
15070                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15071                 fi
15072         done
15073
15074         rm -rf $DIR/${tdir}
15075 }
15076 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15077
15078 test_133f() {
15079         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15080                 skip "too old lustre for get_param -R ($facet_ver)"
15081
15082         # verifying readability.
15083         $LCTL get_param -R '*' &> /dev/null
15084
15085         # Verifing writability with badarea_io.
15086         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15087         local skipped_params='force_lbug|changelog_mask|daemon_file'
15088         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15089                 egrep -v "$skipped_params" |
15090                 xargs -n 1 find $proc_dirs -name |
15091                 xargs -n 1 badarea_io ||
15092                 error "client badarea_io failed"
15093
15094         # remount the FS in case writes/reads /proc break the FS
15095         cleanup || error "failed to unmount"
15096         setup || error "failed to setup"
15097 }
15098 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15099
15100 test_133g() {
15101         remote_mds_nodsh && skip "remote MDS with nodsh"
15102         remote_ost_nodsh && skip "remote OST with nodsh"
15103
15104         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15105         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15106         local facet
15107         for facet in mds1 ost1; do
15108                 local facet_ver=$(lustre_version_code $facet)
15109                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15110                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15111                 else
15112                         log "$facet: too old lustre for get_param -R"
15113                 fi
15114                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15115                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15116                                 tr -d = | egrep -v $skipped_params |
15117                                 xargs -n 1 find $proc_dirs -name |
15118                                 xargs -n 1 badarea_io" ||
15119                                         error "$facet badarea_io failed"
15120                 else
15121                         skip_noexit "$facet: too old lustre for get_param -R"
15122                 fi
15123         done
15124
15125         # remount the FS in case writes/reads /proc break the FS
15126         cleanup || error "failed to unmount"
15127         setup || error "failed to setup"
15128 }
15129 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15130
15131 test_133h() {
15132         remote_mds_nodsh && skip "remote MDS with nodsh"
15133         remote_ost_nodsh && skip "remote OST with nodsh"
15134         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15135                 skip "Need MDS version at least 2.9.54"
15136
15137         local facet
15138         for facet in client mds1 ost1; do
15139                 # Get the list of files that are missing the terminating newline
15140                 local plist=$(do_facet $facet
15141                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15142                 local ent
15143                 for ent in $plist; do
15144                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15145                                 awk -v FS='\v' -v RS='\v\v' \
15146                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15147                                         print FILENAME}'" 2>/dev/null)
15148                         [ -z $missing ] || {
15149                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15150                                 error "file does not end with newline: $facet-$ent"
15151                         }
15152                 done
15153         done
15154 }
15155 run_test 133h "Proc files should end with newlines"
15156
15157 test_134a() {
15158         remote_mds_nodsh && skip "remote MDS with nodsh"
15159         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15160                 skip "Need MDS version at least 2.7.54"
15161
15162         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15163         cancel_lru_locks mdc
15164
15165         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15166         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15167         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15168
15169         local nr=1000
15170         createmany -o $DIR/$tdir/f $nr ||
15171                 error "failed to create $nr files in $DIR/$tdir"
15172         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15173
15174         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15175         do_facet mds1 $LCTL set_param fail_loc=0x327
15176         do_facet mds1 $LCTL set_param fail_val=500
15177         touch $DIR/$tdir/m
15178
15179         echo "sleep 10 seconds ..."
15180         sleep 10
15181         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15182
15183         do_facet mds1 $LCTL set_param fail_loc=0
15184         do_facet mds1 $LCTL set_param fail_val=0
15185         [ $lck_cnt -lt $unused ] ||
15186                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15187
15188         rm $DIR/$tdir/m
15189         unlinkmany $DIR/$tdir/f $nr
15190 }
15191 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15192
15193 test_134b() {
15194         remote_mds_nodsh && skip "remote MDS with nodsh"
15195         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15196                 skip "Need MDS version at least 2.7.54"
15197
15198         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15199         cancel_lru_locks mdc
15200
15201         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15202                         ldlm.lock_reclaim_threshold_mb)
15203         # disable reclaim temporarily
15204         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15205
15206         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15207         do_facet mds1 $LCTL set_param fail_loc=0x328
15208         do_facet mds1 $LCTL set_param fail_val=500
15209
15210         $LCTL set_param debug=+trace
15211
15212         local nr=600
15213         createmany -o $DIR/$tdir/f $nr &
15214         local create_pid=$!
15215
15216         echo "Sleep $TIMEOUT seconds ..."
15217         sleep $TIMEOUT
15218         if ! ps -p $create_pid  > /dev/null 2>&1; then
15219                 do_facet mds1 $LCTL set_param fail_loc=0
15220                 do_facet mds1 $LCTL set_param fail_val=0
15221                 do_facet mds1 $LCTL set_param \
15222                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15223                 error "createmany finished incorrectly!"
15224         fi
15225         do_facet mds1 $LCTL set_param fail_loc=0
15226         do_facet mds1 $LCTL set_param fail_val=0
15227         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15228         wait $create_pid || return 1
15229
15230         unlinkmany $DIR/$tdir/f $nr
15231 }
15232 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15233
15234 test_135() {
15235         remote_mds_nodsh && skip "remote MDS with nodsh"
15236         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15237                 skip "Need MDS version at least 2.13.50"
15238         local fname
15239
15240         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15241
15242 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15243         #set only one record at plain llog
15244         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15245
15246         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15247
15248         #fill already existed plain llog each 64767
15249         #wrapping whole catalog
15250         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15251
15252         createmany -o $DIR/$tdir/$tfile_ 64700
15253         for (( i = 0; i < 64700; i = i + 2 ))
15254         do
15255                 rm $DIR/$tdir/$tfile_$i &
15256                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15257                 local pid=$!
15258                 wait $pid
15259         done
15260
15261         #waiting osp synchronization
15262         wait_delete_completed
15263 }
15264 run_test 135 "Race catalog processing"
15265
15266 test_136() {
15267         remote_mds_nodsh && skip "remote MDS with nodsh"
15268         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15269                 skip "Need MDS version at least 2.13.50"
15270         local fname
15271
15272         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15273         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15274         #set only one record at plain llog
15275 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15276         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15277
15278         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15279
15280         #fill already existed 2 plain llogs each 64767
15281         #wrapping whole catalog
15282         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15283         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15284         wait_delete_completed
15285
15286         createmany -o $DIR/$tdir/$tfile_ 10
15287         sleep 25
15288
15289         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15290         for (( i = 0; i < 10; i = i + 3 ))
15291         do
15292                 rm $DIR/$tdir/$tfile_$i &
15293                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15294                 local pid=$!
15295                 wait $pid
15296                 sleep 7
15297                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15298         done
15299
15300         #waiting osp synchronization
15301         wait_delete_completed
15302 }
15303 run_test 136 "Race catalog processing 2"
15304
15305 test_140() { #bug-17379
15306         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15307
15308         test_mkdir $DIR/$tdir
15309         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15310         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15311
15312         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15313         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15314         local i=0
15315         while i=$((i + 1)); do
15316                 test_mkdir $i
15317                 cd $i || error "Changing to $i"
15318                 ln -s ../stat stat || error "Creating stat symlink"
15319                 # Read the symlink until ELOOP present,
15320                 # not LBUGing the system is considered success,
15321                 # we didn't overrun the stack.
15322                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15323                 if [ $ret -ne 0 ]; then
15324                         if [ $ret -eq 40 ]; then
15325                                 break  # -ELOOP
15326                         else
15327                                 error "Open stat symlink"
15328                                         return
15329                         fi
15330                 fi
15331         done
15332         i=$((i - 1))
15333         echo "The symlink depth = $i"
15334         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15335                 error "Invalid symlink depth"
15336
15337         # Test recursive symlink
15338         ln -s symlink_self symlink_self
15339         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15340         echo "open symlink_self returns $ret"
15341         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15342 }
15343 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15344
15345 test_150a() {
15346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15347
15348         local TF="$TMP/$tfile"
15349
15350         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15351         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15352         cp $TF $DIR/$tfile
15353         cancel_lru_locks $OSC
15354         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15355         remount_client $MOUNT
15356         df -P $MOUNT
15357         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15358
15359         $TRUNCATE $TF 6000
15360         $TRUNCATE $DIR/$tfile 6000
15361         cancel_lru_locks $OSC
15362         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15363
15364         echo "12345" >>$TF
15365         echo "12345" >>$DIR/$tfile
15366         cancel_lru_locks $OSC
15367         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15368
15369         echo "12345" >>$TF
15370         echo "12345" >>$DIR/$tfile
15371         cancel_lru_locks $OSC
15372         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15373 }
15374 run_test 150a "truncate/append tests"
15375
15376 test_150b() {
15377         check_set_fallocate_or_skip
15378         local out
15379
15380         touch $DIR/$tfile
15381         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15382         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15383                 skip_eopnotsupp "$out|check_fallocate failed"
15384 }
15385 run_test 150b "Verify fallocate (prealloc) functionality"
15386
15387 test_150bb() {
15388         check_set_fallocate_or_skip
15389
15390         touch $DIR/$tfile
15391         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15392         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15393         > $DIR/$tfile
15394         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15395         # precomputed md5sum for 20MB of zeroes
15396         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15397         local sum=($(md5sum $DIR/$tfile))
15398
15399         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15400
15401         check_set_fallocate 1
15402
15403         > $DIR/$tfile
15404         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15405         sum=($(md5sum $DIR/$tfile))
15406
15407         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15408 }
15409 run_test 150bb "Verify fallocate modes both zero space"
15410
15411 test_150c() {
15412         check_set_fallocate_or_skip
15413         local striping="-c2"
15414
15415         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15416         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15417         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15418         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15419         local want=$((OSTCOUNT * 1048576))
15420
15421         # Must allocate all requested space, not more than 5% extra
15422         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15423                 error "bytes $bytes is not $want"
15424
15425         rm -f $DIR/$tfile
15426
15427         echo "verify fallocate on PFL file"
15428
15429         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15430
15431         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15432                 error "Create $DIR/$tfile failed"
15433         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15434         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15435         want=$((512 * 1048576))
15436
15437         # Must allocate all requested space, not more than 5% extra
15438         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15439                 error "bytes $bytes is not $want"
15440 }
15441 run_test 150c "Verify fallocate Size and Blocks"
15442
15443 test_150d() {
15444         check_set_fallocate_or_skip
15445         local striping="-c2"
15446
15447         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15448
15449         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15450         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15451                 error "setstripe failed"
15452         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15453         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15454         local want=$((OSTCOUNT * 1048576))
15455
15456         # Must allocate all requested space, not more than 5% extra
15457         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15458                 error "bytes $bytes is not $want"
15459 }
15460 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15461
15462 test_150e() {
15463         check_set_fallocate_or_skip
15464
15465         echo "df before:"
15466         $LFS df
15467         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15468         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15469                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15470
15471         # Find OST with Minimum Size
15472         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15473                        sort -un | head -1)
15474
15475         # Get 100MB per OST of the available space to reduce run time
15476         # else 60% of the available space if we are running SLOW tests
15477         if [ $SLOW == "no" ]; then
15478                 local space=$((1024 * 100 * OSTCOUNT))
15479         else
15480                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15481         fi
15482
15483         fallocate -l${space}k $DIR/$tfile ||
15484                 error "fallocate ${space}k $DIR/$tfile failed"
15485         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15486
15487         # get size immediately after fallocate. This should be correctly
15488         # updated
15489         local size=$(stat -c '%s' $DIR/$tfile)
15490         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15491
15492         # Sleep for a while for statfs to get updated. And not pull from cache.
15493         sleep 2
15494
15495         echo "df after fallocate:"
15496         $LFS df
15497
15498         (( size / 1024 == space )) || error "size $size != requested $space"
15499         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15500                 error "used $used < space $space"
15501
15502         rm $DIR/$tfile || error "rm failed"
15503         sync
15504         wait_delete_completed
15505
15506         echo "df after unlink:"
15507         $LFS df
15508 }
15509 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15510
15511 test_150f() {
15512         local size
15513         local blocks
15514         local want_size_before=20480 # in bytes
15515         local want_blocks_before=40 # 512 sized blocks
15516         local want_blocks_after=24  # 512 sized blocks
15517         local length=$(((want_blocks_before - want_blocks_after) * 512))
15518
15519         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15520                 skip "need at least 2.14.0 for fallocate punch"
15521
15522         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15523                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15524         fi
15525
15526         check_set_fallocate_or_skip
15527         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15528
15529         [[ "x$DOM" == "xyes" ]] &&
15530                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15531
15532         echo "Verify fallocate punch: Range within the file range"
15533         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15534                 error "dd failed for bs 4096 and count 5"
15535
15536         # Call fallocate with punch range which is within the file range
15537         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15538                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15539         # client must see changes immediately after fallocate
15540         size=$(stat -c '%s' $DIR/$tfile)
15541         blocks=$(stat -c '%b' $DIR/$tfile)
15542
15543         # Verify punch worked.
15544         (( blocks == want_blocks_after )) ||
15545                 error "punch failed: blocks $blocks != $want_blocks_after"
15546
15547         (( size == want_size_before )) ||
15548                 error "punch failed: size $size != $want_size_before"
15549
15550         # Verify there is hole in file
15551         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15552         # precomputed md5sum
15553         local expect="4a9a834a2db02452929c0a348273b4aa"
15554
15555         cksum=($(md5sum $DIR/$tfile))
15556         [[ "${cksum[0]}" == "$expect" ]] ||
15557                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15558
15559         # Start second sub-case for fallocate punch.
15560         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15561         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15562                 error "dd failed for bs 4096 and count 5"
15563
15564         # Punch range less than block size will have no change in block count
15565         want_blocks_after=40  # 512 sized blocks
15566
15567         # Punch overlaps two blocks and less than blocksize
15568         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15569                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15570         size=$(stat -c '%s' $DIR/$tfile)
15571         blocks=$(stat -c '%b' $DIR/$tfile)
15572
15573         # Verify punch worked.
15574         (( blocks == want_blocks_after )) ||
15575                 error "punch failed: blocks $blocks != $want_blocks_after"
15576
15577         (( size == want_size_before )) ||
15578                 error "punch failed: size $size != $want_size_before"
15579
15580         # Verify if range is really zero'ed out. We expect Zeros.
15581         # precomputed md5sum
15582         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15583         cksum=($(md5sum $DIR/$tfile))
15584         [[ "${cksum[0]}" == "$expect" ]] ||
15585                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15586 }
15587 run_test 150f "Verify fallocate punch functionality"
15588
15589 test_150g() {
15590         local space
15591         local size
15592         local blocks
15593         local blocks_after
15594         local size_after
15595         local BS=4096 # Block size in bytes
15596
15597         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15598                 skip "need at least 2.14.0 for fallocate punch"
15599
15600         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15601                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15602         fi
15603
15604         check_set_fallocate_or_skip
15605         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15606
15607         if [[ "x$DOM" == "xyes" ]]; then
15608                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15609                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15610         else
15611                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15612                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15613         fi
15614
15615         # Get 100MB per OST of the available space to reduce run time
15616         # else 60% of the available space if we are running SLOW tests
15617         if [ $SLOW == "no" ]; then
15618                 space=$((1024 * 100 * OSTCOUNT))
15619         else
15620                 # Find OST with Minimum Size
15621                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15622                         sort -un | head -1)
15623                 echo "min size OST: $space"
15624                 space=$(((space * 60)/100 * OSTCOUNT))
15625         fi
15626         # space in 1k units, round to 4k blocks
15627         local blkcount=$((space * 1024 / $BS))
15628
15629         echo "Verify fallocate punch: Very large Range"
15630         fallocate -l${space}k $DIR/$tfile ||
15631                 error "fallocate ${space}k $DIR/$tfile failed"
15632         # write 1M at the end, start and in the middle
15633         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15634                 error "dd failed: bs $BS count 256"
15635         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15636                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15637         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15638                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15639
15640         # Gather stats.
15641         size=$(stat -c '%s' $DIR/$tfile)
15642
15643         # gather punch length.
15644         local punch_size=$((size - (BS * 2)))
15645
15646         echo "punch_size = $punch_size"
15647         echo "size - punch_size: $((size - punch_size))"
15648         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15649
15650         # Call fallocate to punch all except 2 blocks. We leave the
15651         # first and the last block
15652         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15653         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15654                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15655
15656         size_after=$(stat -c '%s' $DIR/$tfile)
15657         blocks_after=$(stat -c '%b' $DIR/$tfile)
15658
15659         # Verify punch worked.
15660         # Size should be kept
15661         (( size == size_after )) ||
15662                 error "punch failed: size $size != $size_after"
15663
15664         # two 4k data blocks to remain plus possible 1 extra extent block
15665         (( blocks_after <= ((BS / 512) * 3) )) ||
15666                 error "too many blocks remains: $blocks_after"
15667
15668         # Verify that file has hole between the first and the last blocks
15669         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15670         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15671
15672         echo "Hole at [$hole_start, $hole_end)"
15673         (( hole_start == BS )) ||
15674                 error "no hole at offset $BS after punch"
15675
15676         (( hole_end == BS + punch_size )) ||
15677                 error "data at offset $hole_end < $((BS + punch_size))"
15678 }
15679 run_test 150g "Verify fallocate punch on large range"
15680
15681 test_150h() {
15682         local file=$DIR/$tfile
15683         local size
15684
15685         check_set_fallocate_or_skip
15686         statx_supported || skip_env "Test must be statx() syscall supported"
15687
15688         # fallocate() does not update the size information on the MDT
15689         fallocate -l 16K $file || error "failed to fallocate $file"
15690         cancel_lru_locks $OSC
15691         # STATX with cached-always mode will not send glimpse RPCs to OST,
15692         # it uses the caching attrs on the client side as much as possible.
15693         size=$($STATX --cached=always -c %s $file)
15694         [ $size == 16384 ] ||
15695                 error "size after fallocate() is $size, expected 16384"
15696 }
15697 run_test 150h "Verify extend fallocate updates the file size"
15698
15699 #LU-2902 roc_hit was not able to read all values from lproc
15700 function roc_hit_init() {
15701         local list=$(comma_list $(osts_nodes))
15702         local dir=$DIR/$tdir-check
15703         local file=$dir/$tfile
15704         local BEFORE
15705         local AFTER
15706         local idx
15707
15708         test_mkdir $dir
15709         #use setstripe to do a write to every ost
15710         for i in $(seq 0 $((OSTCOUNT-1))); do
15711                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15712                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15713                 idx=$(printf %04x $i)
15714                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15715                         awk '$1 == "cache_access" {sum += $7}
15716                                 END { printf("%0.0f", sum) }')
15717
15718                 cancel_lru_locks osc
15719                 cat $file >/dev/null
15720
15721                 AFTER=$(get_osd_param $list *OST*$idx stats |
15722                         awk '$1 == "cache_access" {sum += $7}
15723                                 END { printf("%0.0f", sum) }')
15724
15725                 echo BEFORE:$BEFORE AFTER:$AFTER
15726                 if ! let "AFTER - BEFORE == 4"; then
15727                         rm -rf $dir
15728                         error "roc_hit is not safe to use"
15729                 fi
15730                 rm $file
15731         done
15732
15733         rm -rf $dir
15734 }
15735
15736 function roc_hit() {
15737         local list=$(comma_list $(osts_nodes))
15738         echo $(get_osd_param $list '' stats |
15739                 awk '$1 == "cache_hit" {sum += $7}
15740                         END { printf("%0.0f", sum) }')
15741 }
15742
15743 function set_cache() {
15744         local on=1
15745
15746         if [ "$2" == "off" ]; then
15747                 on=0;
15748         fi
15749         local list=$(comma_list $(osts_nodes))
15750         set_osd_param $list '' $1_cache_enable $on
15751
15752         cancel_lru_locks osc
15753 }
15754
15755 test_151() {
15756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15757         remote_ost_nodsh && skip "remote OST with nodsh"
15758
15759         local CPAGES=3
15760         local list=$(comma_list $(osts_nodes))
15761
15762         # check whether obdfilter is cache capable at all
15763         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15764                 skip "not cache-capable obdfilter"
15765         fi
15766
15767         # check cache is enabled on all obdfilters
15768         if get_osd_param $list '' read_cache_enable | grep 0; then
15769                 skip "oss cache is disabled"
15770         fi
15771
15772         set_osd_param $list '' writethrough_cache_enable 1
15773
15774         # check write cache is enabled on all obdfilters
15775         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15776                 skip "oss write cache is NOT enabled"
15777         fi
15778
15779         roc_hit_init
15780
15781         #define OBD_FAIL_OBD_NO_LRU  0x609
15782         do_nodes $list $LCTL set_param fail_loc=0x609
15783
15784         # pages should be in the case right after write
15785         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15786                 error "dd failed"
15787
15788         local BEFORE=$(roc_hit)
15789         cancel_lru_locks osc
15790         cat $DIR/$tfile >/dev/null
15791         local AFTER=$(roc_hit)
15792
15793         do_nodes $list $LCTL set_param fail_loc=0
15794
15795         if ! let "AFTER - BEFORE == CPAGES"; then
15796                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15797         fi
15798
15799         cancel_lru_locks osc
15800         # invalidates OST cache
15801         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15802         set_osd_param $list '' read_cache_enable 0
15803         cat $DIR/$tfile >/dev/null
15804
15805         # now data shouldn't be found in the cache
15806         BEFORE=$(roc_hit)
15807         cancel_lru_locks osc
15808         cat $DIR/$tfile >/dev/null
15809         AFTER=$(roc_hit)
15810         if let "AFTER - BEFORE != 0"; then
15811                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15812         fi
15813
15814         set_osd_param $list '' read_cache_enable 1
15815         rm -f $DIR/$tfile
15816 }
15817 run_test 151 "test cache on oss and controls ==============================="
15818
15819 test_152() {
15820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15821
15822         local TF="$TMP/$tfile"
15823
15824         # simulate ENOMEM during write
15825 #define OBD_FAIL_OST_NOMEM      0x226
15826         lctl set_param fail_loc=0x80000226
15827         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15828         cp $TF $DIR/$tfile
15829         sync || error "sync failed"
15830         lctl set_param fail_loc=0
15831
15832         # discard client's cache
15833         cancel_lru_locks osc
15834
15835         # simulate ENOMEM during read
15836         lctl set_param fail_loc=0x80000226
15837         cmp $TF $DIR/$tfile || error "cmp failed"
15838         lctl set_param fail_loc=0
15839
15840         rm -f $TF
15841 }
15842 run_test 152 "test read/write with enomem ============================"
15843
15844 test_153() {
15845         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15846 }
15847 run_test 153 "test if fdatasync does not crash ======================="
15848
15849 dot_lustre_fid_permission_check() {
15850         local fid=$1
15851         local ffid=$MOUNT/.lustre/fid/$fid
15852         local test_dir=$2
15853
15854         echo "stat fid $fid"
15855         stat $ffid || error "stat $ffid failed."
15856         echo "touch fid $fid"
15857         touch $ffid || error "touch $ffid failed."
15858         echo "write to fid $fid"
15859         cat /etc/hosts > $ffid || error "write $ffid failed."
15860         echo "read fid $fid"
15861         diff /etc/hosts $ffid || error "read $ffid failed."
15862         echo "append write to fid $fid"
15863         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15864         echo "rename fid $fid"
15865         mv $ffid $test_dir/$tfile.1 &&
15866                 error "rename $ffid to $tfile.1 should fail."
15867         touch $test_dir/$tfile.1
15868         mv $test_dir/$tfile.1 $ffid &&
15869                 error "rename $tfile.1 to $ffid should fail."
15870         rm -f $test_dir/$tfile.1
15871         echo "truncate fid $fid"
15872         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15873         echo "link fid $fid"
15874         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15875         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15876                 echo "setfacl fid $fid"
15877                 setfacl -R -m u:$USER0:rwx $ffid ||
15878                         error "setfacl $ffid failed"
15879                 echo "getfacl fid $fid"
15880                 getfacl $ffid || error "getfacl $ffid failed."
15881         fi
15882         echo "unlink fid $fid"
15883         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15884         echo "mknod fid $fid"
15885         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15886
15887         fid=[0xf00000400:0x1:0x0]
15888         ffid=$MOUNT/.lustre/fid/$fid
15889
15890         echo "stat non-exist fid $fid"
15891         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15892         echo "write to non-exist fid $fid"
15893         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15894         echo "link new fid $fid"
15895         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15896
15897         mkdir -p $test_dir/$tdir
15898         touch $test_dir/$tdir/$tfile
15899         fid=$($LFS path2fid $test_dir/$tdir)
15900         rc=$?
15901         [ $rc -ne 0 ] &&
15902                 error "error: could not get fid for $test_dir/$dir/$tfile."
15903
15904         ffid=$MOUNT/.lustre/fid/$fid
15905
15906         echo "ls $fid"
15907         ls $ffid || error "ls $ffid failed."
15908         echo "touch $fid/$tfile.1"
15909         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15910
15911         echo "touch $MOUNT/.lustre/fid/$tfile"
15912         touch $MOUNT/.lustre/fid/$tfile && \
15913                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15914
15915         echo "setxattr to $MOUNT/.lustre/fid"
15916         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15917
15918         echo "listxattr for $MOUNT/.lustre/fid"
15919         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15920
15921         echo "delxattr from $MOUNT/.lustre/fid"
15922         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15923
15924         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15925         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15926                 error "touch invalid fid should fail."
15927
15928         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15929         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15930                 error "touch non-normal fid should fail."
15931
15932         echo "rename $tdir to $MOUNT/.lustre/fid"
15933         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15934                 error "rename to $MOUNT/.lustre/fid should fail."
15935
15936         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15937         then            # LU-3547
15938                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15939                 local new_obf_mode=777
15940
15941                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15942                 chmod $new_obf_mode $DIR/.lustre/fid ||
15943                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15944
15945                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15946                 [ $obf_mode -eq $new_obf_mode ] ||
15947                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15948
15949                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15950                 chmod $old_obf_mode $DIR/.lustre/fid ||
15951                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15952         fi
15953
15954         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15955         fid=$($LFS path2fid $test_dir/$tfile-2)
15956
15957         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15958         then # LU-5424
15959                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15960                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15961                         error "create lov data thru .lustre failed"
15962         fi
15963         echo "cp /etc/passwd $test_dir/$tfile-2"
15964         cp /etc/passwd $test_dir/$tfile-2 ||
15965                 error "copy to $test_dir/$tfile-2 failed."
15966         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15967         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15968                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15969
15970         rm -rf $test_dir/tfile.lnk
15971         rm -rf $test_dir/$tfile-2
15972 }
15973
15974 test_154A() {
15975         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15976                 skip "Need MDS version at least 2.4.1"
15977
15978         local tf=$DIR/$tfile
15979         touch $tf
15980
15981         local fid=$($LFS path2fid $tf)
15982         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15983
15984         # check that we get the same pathname back
15985         local rootpath
15986         local found
15987         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15988                 echo "$rootpath $fid"
15989                 found=$($LFS fid2path $rootpath "$fid")
15990                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15991                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15992         done
15993
15994         # check wrong root path format
15995         rootpath=$MOUNT"_wrong"
15996         found=$($LFS fid2path $rootpath "$fid")
15997         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
15998 }
15999 run_test 154A "lfs path2fid and fid2path basic checks"
16000
16001 test_154B() {
16002         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16003                 skip "Need MDS version at least 2.4.1"
16004
16005         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16006         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16007         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16008         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16009
16010         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16011         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16012
16013         # check that we get the same pathname
16014         echo "PFID: $PFID, name: $name"
16015         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16016         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16017         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16018                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16019
16020         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16021 }
16022 run_test 154B "verify the ll_decode_linkea tool"
16023
16024 test_154a() {
16025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16026         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16027         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16028                 skip "Need MDS version at least 2.2.51"
16029         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16030
16031         cp /etc/hosts $DIR/$tfile
16032
16033         fid=$($LFS path2fid $DIR/$tfile)
16034         rc=$?
16035         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16036
16037         dot_lustre_fid_permission_check "$fid" $DIR ||
16038                 error "dot lustre permission check $fid failed"
16039
16040         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16041
16042         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16043
16044         touch $MOUNT/.lustre/file &&
16045                 error "creation is not allowed under .lustre"
16046
16047         mkdir $MOUNT/.lustre/dir &&
16048                 error "mkdir is not allowed under .lustre"
16049
16050         rm -rf $DIR/$tfile
16051 }
16052 run_test 154a "Open-by-FID"
16053
16054 test_154b() {
16055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16056         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16057         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16058         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16059                 skip "Need MDS version at least 2.2.51"
16060
16061         local remote_dir=$DIR/$tdir/remote_dir
16062         local MDTIDX=1
16063         local rc=0
16064
16065         mkdir -p $DIR/$tdir
16066         $LFS mkdir -i $MDTIDX $remote_dir ||
16067                 error "create remote directory failed"
16068
16069         cp /etc/hosts $remote_dir/$tfile
16070
16071         fid=$($LFS path2fid $remote_dir/$tfile)
16072         rc=$?
16073         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16074
16075         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16076                 error "dot lustre permission check $fid failed"
16077         rm -rf $DIR/$tdir
16078 }
16079 run_test 154b "Open-by-FID for remote directory"
16080
16081 test_154c() {
16082         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16083                 skip "Need MDS version at least 2.4.1"
16084
16085         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16086         local FID1=$($LFS path2fid $DIR/$tfile.1)
16087         local FID2=$($LFS path2fid $DIR/$tfile.2)
16088         local FID3=$($LFS path2fid $DIR/$tfile.3)
16089
16090         local N=1
16091         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16092                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16093                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16094                 local want=FID$N
16095                 [ "$FID" = "${!want}" ] ||
16096                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16097                 N=$((N + 1))
16098         done
16099
16100         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16101         do
16102                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16103                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16104                 N=$((N + 1))
16105         done
16106 }
16107 run_test 154c "lfs path2fid and fid2path multiple arguments"
16108
16109 test_154d() {
16110         remote_mds_nodsh && skip "remote MDS with nodsh"
16111         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16112                 skip "Need MDS version at least 2.5.53"
16113
16114         if remote_mds; then
16115                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16116         else
16117                 nid="0@lo"
16118         fi
16119         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16120         local fd
16121         local cmd
16122
16123         rm -f $DIR/$tfile
16124         touch $DIR/$tfile
16125
16126         local fid=$($LFS path2fid $DIR/$tfile)
16127         # Open the file
16128         fd=$(free_fd)
16129         cmd="exec $fd<$DIR/$tfile"
16130         eval $cmd
16131         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16132         echo "$fid_list" | grep "$fid"
16133         rc=$?
16134
16135         cmd="exec $fd>/dev/null"
16136         eval $cmd
16137         if [ $rc -ne 0 ]; then
16138                 error "FID $fid not found in open files list $fid_list"
16139         fi
16140 }
16141 run_test 154d "Verify open file fid"
16142
16143 test_154e()
16144 {
16145         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16146                 skip "Need MDS version at least 2.6.50"
16147
16148         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16149                 error ".lustre returned by readdir"
16150         fi
16151 }
16152 run_test 154e ".lustre is not returned by readdir"
16153
16154 test_154f() {
16155         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16156
16157         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16158         mkdir_on_mdt0 $DIR/$tdir
16159         # test dirs inherit from its stripe
16160         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16161         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16162         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16163         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16164         touch $DIR/f
16165
16166         # get fid of parents
16167         local FID0=$($LFS path2fid $DIR/$tdir)
16168         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16169         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16170         local FID3=$($LFS path2fid $DIR)
16171
16172         # check that path2fid --parents returns expected <parent_fid>/name
16173         # 1) test for a directory (single parent)
16174         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16175         [ "$parent" == "$FID0/foo1" ] ||
16176                 error "expected parent: $FID0/foo1, got: $parent"
16177
16178         # 2) test for a file with nlink > 1 (multiple parents)
16179         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16180         echo "$parent" | grep -F "$FID1/$tfile" ||
16181                 error "$FID1/$tfile not returned in parent list"
16182         echo "$parent" | grep -F "$FID2/link" ||
16183                 error "$FID2/link not returned in parent list"
16184
16185         # 3) get parent by fid
16186         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16187         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16188         echo "$parent" | grep -F "$FID1/$tfile" ||
16189                 error "$FID1/$tfile not returned in parent list (by fid)"
16190         echo "$parent" | grep -F "$FID2/link" ||
16191                 error "$FID2/link not returned in parent list (by fid)"
16192
16193         # 4) test for entry in root directory
16194         parent=$($LFS path2fid --parents $DIR/f)
16195         echo "$parent" | grep -F "$FID3/f" ||
16196                 error "$FID3/f not returned in parent list"
16197
16198         # 5) test it on root directory
16199         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16200                 error "$MOUNT should not have parents"
16201
16202         # enable xattr caching and check that linkea is correctly updated
16203         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16204         save_lustre_params client "llite.*.xattr_cache" > $save
16205         lctl set_param llite.*.xattr_cache 1
16206
16207         # 6.1) linkea update on rename
16208         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16209
16210         # get parents by fid
16211         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16212         # foo1 should no longer be returned in parent list
16213         echo "$parent" | grep -F "$FID1" &&
16214                 error "$FID1 should no longer be in parent list"
16215         # the new path should appear
16216         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16217                 error "$FID2/$tfile.moved is not in parent list"
16218
16219         # 6.2) linkea update on unlink
16220         rm -f $DIR/$tdir/foo2/link
16221         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16222         # foo2/link should no longer be returned in parent list
16223         echo "$parent" | grep -F "$FID2/link" &&
16224                 error "$FID2/link should no longer be in parent list"
16225         true
16226
16227         rm -f $DIR/f
16228         restore_lustre_params < $save
16229         rm -f $save
16230 }
16231 run_test 154f "get parent fids by reading link ea"
16232
16233 test_154g()
16234 {
16235         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16236            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16237                 skip "Need MDS version at least 2.6.92"
16238
16239         mkdir_on_mdt0 $DIR/$tdir
16240         llapi_fid_test -d $DIR/$tdir
16241 }
16242 run_test 154g "various llapi FID tests"
16243
16244 test_155_small_load() {
16245     local temp=$TMP/$tfile
16246     local file=$DIR/$tfile
16247
16248     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16249         error "dd of=$temp bs=6096 count=1 failed"
16250     cp $temp $file
16251     cancel_lru_locks $OSC
16252     cmp $temp $file || error "$temp $file differ"
16253
16254     $TRUNCATE $temp 6000
16255     $TRUNCATE $file 6000
16256     cmp $temp $file || error "$temp $file differ (truncate1)"
16257
16258     echo "12345" >>$temp
16259     echo "12345" >>$file
16260     cmp $temp $file || error "$temp $file differ (append1)"
16261
16262     echo "12345" >>$temp
16263     echo "12345" >>$file
16264     cmp $temp $file || error "$temp $file differ (append2)"
16265
16266     rm -f $temp $file
16267     true
16268 }
16269
16270 test_155_big_load() {
16271         remote_ost_nodsh && skip "remote OST with nodsh"
16272
16273         local temp=$TMP/$tfile
16274         local file=$DIR/$tfile
16275
16276         free_min_max
16277         local cache_size=$(do_facet ost$((MAXI+1)) \
16278                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16279
16280         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16281         # pre-set value
16282         if [ -z "$cache_size" ]; then
16283                 cache_size=256
16284         fi
16285         local large_file_size=$((cache_size * 2))
16286
16287         echo "OSS cache size: $cache_size KB"
16288         echo "Large file size: $large_file_size KB"
16289
16290         [ $MAXV -le $large_file_size ] &&
16291                 skip_env "max available OST size needs > $large_file_size KB"
16292
16293         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16294
16295         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16296                 error "dd of=$temp bs=$large_file_size count=1k failed"
16297         cp $temp $file
16298         ls -lh $temp $file
16299         cancel_lru_locks osc
16300         cmp $temp $file || error "$temp $file differ"
16301
16302         rm -f $temp $file
16303         true
16304 }
16305
16306 save_writethrough() {
16307         local facets=$(get_facets OST)
16308
16309         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16310 }
16311
16312 test_155a() {
16313         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16314
16315         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16316
16317         save_writethrough $p
16318
16319         set_cache read on
16320         set_cache writethrough on
16321         test_155_small_load
16322         restore_lustre_params < $p
16323         rm -f $p
16324 }
16325 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16326
16327 test_155b() {
16328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16329
16330         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16331
16332         save_writethrough $p
16333
16334         set_cache read on
16335         set_cache writethrough off
16336         test_155_small_load
16337         restore_lustre_params < $p
16338         rm -f $p
16339 }
16340 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16341
16342 test_155c() {
16343         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16344
16345         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16346
16347         save_writethrough $p
16348
16349         set_cache read off
16350         set_cache writethrough on
16351         test_155_small_load
16352         restore_lustre_params < $p
16353         rm -f $p
16354 }
16355 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16356
16357 test_155d() {
16358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16359
16360         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16361
16362         save_writethrough $p
16363
16364         set_cache read off
16365         set_cache writethrough off
16366         test_155_small_load
16367         restore_lustre_params < $p
16368         rm -f $p
16369 }
16370 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16371
16372 test_155e() {
16373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16374
16375         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16376
16377         save_writethrough $p
16378
16379         set_cache read on
16380         set_cache writethrough on
16381         test_155_big_load
16382         restore_lustre_params < $p
16383         rm -f $p
16384 }
16385 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16386
16387 test_155f() {
16388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16389
16390         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16391
16392         save_writethrough $p
16393
16394         set_cache read on
16395         set_cache writethrough off
16396         test_155_big_load
16397         restore_lustre_params < $p
16398         rm -f $p
16399 }
16400 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16401
16402 test_155g() {
16403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16404
16405         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16406
16407         save_writethrough $p
16408
16409         set_cache read off
16410         set_cache writethrough on
16411         test_155_big_load
16412         restore_lustre_params < $p
16413         rm -f $p
16414 }
16415 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16416
16417 test_155h() {
16418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16419
16420         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16421
16422         save_writethrough $p
16423
16424         set_cache read off
16425         set_cache writethrough off
16426         test_155_big_load
16427         restore_lustre_params < $p
16428         rm -f $p
16429 }
16430 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16431
16432 test_156() {
16433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16434         remote_ost_nodsh && skip "remote OST with nodsh"
16435         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16436                 skip "stats not implemented on old servers"
16437         [ "$ost1_FSTYPE" = "zfs" ] &&
16438                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16439
16440         local CPAGES=3
16441         local BEFORE
16442         local AFTER
16443         local file="$DIR/$tfile"
16444         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16445
16446         save_writethrough $p
16447         roc_hit_init
16448
16449         log "Turn on read and write cache"
16450         set_cache read on
16451         set_cache writethrough on
16452
16453         log "Write data and read it back."
16454         log "Read should be satisfied from the cache."
16455         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16456         BEFORE=$(roc_hit)
16457         cancel_lru_locks osc
16458         cat $file >/dev/null
16459         AFTER=$(roc_hit)
16460         if ! let "AFTER - BEFORE == CPAGES"; then
16461                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16462         else
16463                 log "cache hits: before: $BEFORE, after: $AFTER"
16464         fi
16465
16466         log "Read again; it should be satisfied from the cache."
16467         BEFORE=$AFTER
16468         cancel_lru_locks osc
16469         cat $file >/dev/null
16470         AFTER=$(roc_hit)
16471         if ! let "AFTER - BEFORE == CPAGES"; then
16472                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16473         else
16474                 log "cache hits:: before: $BEFORE, after: $AFTER"
16475         fi
16476
16477         log "Turn off the read cache and turn on the write cache"
16478         set_cache read off
16479         set_cache writethrough on
16480
16481         log "Read again; it should be satisfied from the cache."
16482         BEFORE=$(roc_hit)
16483         cancel_lru_locks osc
16484         cat $file >/dev/null
16485         AFTER=$(roc_hit)
16486         if ! let "AFTER - BEFORE == CPAGES"; then
16487                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16488         else
16489                 log "cache hits:: before: $BEFORE, after: $AFTER"
16490         fi
16491
16492         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16493                 # > 2.12.56 uses pagecache if cached
16494                 log "Read again; it should not be satisfied from the cache."
16495                 BEFORE=$AFTER
16496                 cancel_lru_locks osc
16497                 cat $file >/dev/null
16498                 AFTER=$(roc_hit)
16499                 if ! let "AFTER - BEFORE == 0"; then
16500                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16501                 else
16502                         log "cache hits:: before: $BEFORE, after: $AFTER"
16503                 fi
16504         fi
16505
16506         log "Write data and read it back."
16507         log "Read should be satisfied from the cache."
16508         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16509         BEFORE=$(roc_hit)
16510         cancel_lru_locks osc
16511         cat $file >/dev/null
16512         AFTER=$(roc_hit)
16513         if ! let "AFTER - BEFORE == CPAGES"; then
16514                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16515         else
16516                 log "cache hits:: before: $BEFORE, after: $AFTER"
16517         fi
16518
16519         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16520                 # > 2.12.56 uses pagecache if cached
16521                 log "Read again; it should not be satisfied from the cache."
16522                 BEFORE=$AFTER
16523                 cancel_lru_locks osc
16524                 cat $file >/dev/null
16525                 AFTER=$(roc_hit)
16526                 if ! let "AFTER - BEFORE == 0"; then
16527                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16528                 else
16529                         log "cache hits:: before: $BEFORE, after: $AFTER"
16530                 fi
16531         fi
16532
16533         log "Turn off read and write cache"
16534         set_cache read off
16535         set_cache writethrough off
16536
16537         log "Write data and read it back"
16538         log "It should not be satisfied from the cache."
16539         rm -f $file
16540         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16541         cancel_lru_locks osc
16542         BEFORE=$(roc_hit)
16543         cat $file >/dev/null
16544         AFTER=$(roc_hit)
16545         if ! let "AFTER - BEFORE == 0"; then
16546                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16547         else
16548                 log "cache hits:: before: $BEFORE, after: $AFTER"
16549         fi
16550
16551         log "Turn on the read cache and turn off the write cache"
16552         set_cache read on
16553         set_cache writethrough off
16554
16555         log "Write data and read it back"
16556         log "It should not be satisfied from the cache."
16557         rm -f $file
16558         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16559         BEFORE=$(roc_hit)
16560         cancel_lru_locks osc
16561         cat $file >/dev/null
16562         AFTER=$(roc_hit)
16563         if ! let "AFTER - BEFORE == 0"; then
16564                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16565         else
16566                 log "cache hits:: before: $BEFORE, after: $AFTER"
16567         fi
16568
16569         log "Read again; it should be satisfied from the cache."
16570         BEFORE=$(roc_hit)
16571         cancel_lru_locks osc
16572         cat $file >/dev/null
16573         AFTER=$(roc_hit)
16574         if ! let "AFTER - BEFORE == CPAGES"; then
16575                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16576         else
16577                 log "cache hits:: before: $BEFORE, after: $AFTER"
16578         fi
16579
16580         restore_lustre_params < $p
16581         rm -f $p $file
16582 }
16583 run_test 156 "Verification of tunables"
16584
16585 test_160a() {
16586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16587         remote_mds_nodsh && skip "remote MDS with nodsh"
16588         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16589                 skip "Need MDS version at least 2.2.0"
16590
16591         changelog_register || error "changelog_register failed"
16592         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16593         changelog_users $SINGLEMDS | grep -q $cl_user ||
16594                 error "User $cl_user not found in changelog_users"
16595
16596         mkdir_on_mdt0 $DIR/$tdir
16597
16598         # change something
16599         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16600         changelog_clear 0 || error "changelog_clear failed"
16601         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16602         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16603         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16604         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16605         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16606         rm $DIR/$tdir/pics/desktop.jpg
16607
16608         echo "verifying changelog mask"
16609         changelog_chmask "-MKDIR"
16610         changelog_chmask "-CLOSE"
16611
16612         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16613         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16614
16615         changelog_chmask "+MKDIR"
16616         changelog_chmask "+CLOSE"
16617
16618         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16619         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16620
16621         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16622         CLOSES=$(changelog_dump | grep -c "CLOSE")
16623         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16624         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16625
16626         # verify contents
16627         echo "verifying target fid"
16628         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16629         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16630         [ "$fidc" == "$fidf" ] ||
16631                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16632         echo "verifying parent fid"
16633         # The FID returned from the Changelog may be the directory shard on
16634         # a different MDT, and not the FID returned by path2fid on the parent.
16635         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16636         # since this is what will matter when recreating this file in the tree.
16637         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16638         local pathp=$($LFS fid2path $MOUNT "$fidp")
16639         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16640                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16641
16642         echo "getting records for $cl_user"
16643         changelog_users $SINGLEMDS
16644         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16645         local nclr=3
16646         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16647                 error "changelog_clear failed"
16648         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16649         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16650         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16651                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16652
16653         local min0_rec=$(changelog_users $SINGLEMDS |
16654                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16655         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16656                           awk '{ print $1; exit; }')
16657
16658         changelog_dump | tail -n 5
16659         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16660         [ $first_rec == $((min0_rec + 1)) ] ||
16661                 error "first index should be $min0_rec + 1 not $first_rec"
16662
16663         # LU-3446 changelog index reset on MDT restart
16664         local cur_rec1=$(changelog_users $SINGLEMDS |
16665                          awk '/^current.index:/ { print $NF }')
16666         changelog_clear 0 ||
16667                 error "clear all changelog records for $cl_user failed"
16668         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16669         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16670                 error "Fail to start $SINGLEMDS"
16671         local cur_rec2=$(changelog_users $SINGLEMDS |
16672                          awk '/^current.index:/ { print $NF }')
16673         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16674         [ $cur_rec1 == $cur_rec2 ] ||
16675                 error "current index should be $cur_rec1 not $cur_rec2"
16676
16677         echo "verifying users from this test are deregistered"
16678         changelog_deregister || error "changelog_deregister failed"
16679         changelog_users $SINGLEMDS | grep -q $cl_user &&
16680                 error "User '$cl_user' still in changelog_users"
16681
16682         # lctl get_param -n mdd.*.changelog_users
16683         # current_index: 144
16684         # ID    index (idle seconds)
16685         # cl3   144   (2) mask=<list>
16686         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16687                 # this is the normal case where all users were deregistered
16688                 # make sure no new records are added when no users are present
16689                 local last_rec1=$(changelog_users $SINGLEMDS |
16690                                   awk '/^current.index:/ { print $NF }')
16691                 touch $DIR/$tdir/chloe
16692                 local last_rec2=$(changelog_users $SINGLEMDS |
16693                                   awk '/^current.index:/ { print $NF }')
16694                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16695                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16696         else
16697                 # any changelog users must be leftovers from a previous test
16698                 changelog_users $SINGLEMDS
16699                 echo "other changelog users; can't verify off"
16700         fi
16701 }
16702 run_test 160a "changelog sanity"
16703
16704 test_160b() { # LU-3587
16705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16706         remote_mds_nodsh && skip "remote MDS with nodsh"
16707         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16708                 skip "Need MDS version at least 2.2.0"
16709
16710         changelog_register || error "changelog_register failed"
16711         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16712         changelog_users $SINGLEMDS | grep -q $cl_user ||
16713                 error "User '$cl_user' not found in changelog_users"
16714
16715         local longname1=$(str_repeat a 255)
16716         local longname2=$(str_repeat b 255)
16717
16718         cd $DIR
16719         echo "creating very long named file"
16720         touch $longname1 || error "create of '$longname1' failed"
16721         echo "renaming very long named file"
16722         mv $longname1 $longname2
16723
16724         changelog_dump | grep RENME | tail -n 5
16725         rm -f $longname2
16726 }
16727 run_test 160b "Verify that very long rename doesn't crash in changelog"
16728
16729 test_160c() {
16730         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16731         remote_mds_nodsh && skip "remote MDS with nodsh"
16732
16733         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16734                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16735                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16736                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16737
16738         local rc=0
16739
16740         # Registration step
16741         changelog_register || error "changelog_register failed"
16742
16743         rm -rf $DIR/$tdir
16744         mkdir -p $DIR/$tdir
16745         $MCREATE $DIR/$tdir/foo_160c
16746         changelog_chmask "-TRUNC"
16747         $TRUNCATE $DIR/$tdir/foo_160c 200
16748         changelog_chmask "+TRUNC"
16749         $TRUNCATE $DIR/$tdir/foo_160c 199
16750         changelog_dump | tail -n 5
16751         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16752         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16753 }
16754 run_test 160c "verify that changelog log catch the truncate event"
16755
16756 test_160d() {
16757         remote_mds_nodsh && skip "remote MDS with nodsh"
16758         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16760         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16761                 skip "Need MDS version at least 2.7.60"
16762
16763         # Registration step
16764         changelog_register || error "changelog_register failed"
16765
16766         mkdir -p $DIR/$tdir/migrate_dir
16767         changelog_clear 0 || error "changelog_clear failed"
16768
16769         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16770         changelog_dump | tail -n 5
16771         local migrates=$(changelog_dump | grep -c "MIGRT")
16772         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16773 }
16774 run_test 160d "verify that changelog log catch the migrate event"
16775
16776 test_160e() {
16777         remote_mds_nodsh && skip "remote MDS with nodsh"
16778
16779         # Create a user
16780         changelog_register || error "changelog_register failed"
16781
16782         local MDT0=$(facet_svc $SINGLEMDS)
16783         local rc
16784
16785         # No user (expect fail)
16786         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16787         rc=$?
16788         if [ $rc -eq 0 ]; then
16789                 error "Should fail without user"
16790         elif [ $rc -ne 4 ]; then
16791                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16792         fi
16793
16794         # Delete a future user (expect fail)
16795         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16796         rc=$?
16797         if [ $rc -eq 0 ]; then
16798                 error "Deleted non-existant user cl77"
16799         elif [ $rc -ne 2 ]; then
16800                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16801         fi
16802
16803         # Clear to a bad index (1 billion should be safe)
16804         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16805         rc=$?
16806
16807         if [ $rc -eq 0 ]; then
16808                 error "Successfully cleared to invalid CL index"
16809         elif [ $rc -ne 22 ]; then
16810                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16811         fi
16812 }
16813 run_test 160e "changelog negative testing (should return errors)"
16814
16815 test_160f() {
16816         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16817         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16818                 skip "Need MDS version at least 2.10.56"
16819
16820         local mdts=$(comma_list $(mdts_nodes))
16821
16822         # Create a user
16823         changelog_register || error "first changelog_register failed"
16824         changelog_register || error "second changelog_register failed"
16825         local cl_users
16826         declare -A cl_user1
16827         declare -A cl_user2
16828         local user_rec1
16829         local user_rec2
16830         local i
16831
16832         # generate some changelog records to accumulate on each MDT
16833         # use all_char because created files should be evenly distributed
16834         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16835                 error "test_mkdir $tdir failed"
16836         log "$(date +%s): creating first files"
16837         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16838                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16839                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16840         done
16841
16842         # check changelogs have been generated
16843         local start=$SECONDS
16844         local idle_time=$((MDSCOUNT * 5 + 5))
16845         local nbcl=$(changelog_dump | wc -l)
16846         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16847
16848         for param in "changelog_max_idle_time=$idle_time" \
16849                      "changelog_gc=1" \
16850                      "changelog_min_gc_interval=2" \
16851                      "changelog_min_free_cat_entries=3"; do
16852                 local MDT0=$(facet_svc $SINGLEMDS)
16853                 local var="${param%=*}"
16854                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16855
16856                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16857                 do_nodes $mdts $LCTL set_param mdd.*.$param
16858         done
16859
16860         # force cl_user2 to be idle (1st part), but also cancel the
16861         # cl_user1 records so that it is not evicted later in the test.
16862         local sleep1=$((idle_time / 2))
16863         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16864         sleep $sleep1
16865
16866         # simulate changelog catalog almost full
16867         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16868         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16869
16870         for i in $(seq $MDSCOUNT); do
16871                 cl_users=(${CL_USERS[mds$i]})
16872                 cl_user1[mds$i]="${cl_users[0]}"
16873                 cl_user2[mds$i]="${cl_users[1]}"
16874
16875                 [ -n "${cl_user1[mds$i]}" ] ||
16876                         error "mds$i: no user registered"
16877                 [ -n "${cl_user2[mds$i]}" ] ||
16878                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16879
16880                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16881                 [ -n "$user_rec1" ] ||
16882                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16883                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16884                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16885                 [ -n "$user_rec2" ] ||
16886                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16887                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16888                      "$user_rec1 + 2 == $user_rec2"
16889                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16890                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16891                               "$user_rec1 + 2, but is $user_rec2"
16892                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16893                 [ -n "$user_rec2" ] ||
16894                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16895                 [ $user_rec1 == $user_rec2 ] ||
16896                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16897                               "$user_rec1, but is $user_rec2"
16898         done
16899
16900         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16901         local sleep2=$((idle_time - (SECONDS - start) + 1))
16902         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16903         sleep $sleep2
16904
16905         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16906         # cl_user1 should be OK because it recently processed records.
16907         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16908         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16909                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16910                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16911         done
16912
16913         # ensure gc thread is done
16914         for i in $(mdts_nodes); do
16915                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16916                         error "$i: GC-thread not done"
16917         done
16918
16919         local first_rec
16920         for (( i = 1; i <= MDSCOUNT; i++ )); do
16921                 # check cl_user1 still registered
16922                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16923                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16924                 # check cl_user2 unregistered
16925                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16926                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16927
16928                 # check changelogs are present and starting at $user_rec1 + 1
16929                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16930                 [ -n "$user_rec1" ] ||
16931                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16932                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16933                             awk '{ print $1; exit; }')
16934
16935                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16936                 [ $((user_rec1 + 1)) == $first_rec ] ||
16937                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16938         done
16939 }
16940 run_test 160f "changelog garbage collect (timestamped users)"
16941
16942 test_160g() {
16943         remote_mds_nodsh && skip "remote MDS with nodsh"
16944         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16945                 skip "Need MDS version at least 2.14.55"
16946
16947         local mdts=$(comma_list $(mdts_nodes))
16948
16949         # Create a user
16950         changelog_register || error "first changelog_register failed"
16951         changelog_register || error "second changelog_register failed"
16952         local cl_users
16953         declare -A cl_user1
16954         declare -A cl_user2
16955         local user_rec1
16956         local user_rec2
16957         local i
16958
16959         # generate some changelog records to accumulate on each MDT
16960         # use all_char because created files should be evenly distributed
16961         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16962                 error "test_mkdir $tdir failed"
16963         for ((i = 0; i < MDSCOUNT; i++)); do
16964                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16965                         error "create $DIR/$tdir/d$i.1 failed"
16966         done
16967
16968         # check changelogs have been generated
16969         local nbcl=$(changelog_dump | wc -l)
16970         (( $nbcl > 0 )) || error "no changelogs found"
16971
16972         # reduce the max_idle_indexes value to make sure we exceed it
16973         for param in "changelog_max_idle_indexes=2" \
16974                      "changelog_gc=1" \
16975                      "changelog_min_gc_interval=2"; do
16976                 local MDT0=$(facet_svc $SINGLEMDS)
16977                 local var="${param%=*}"
16978                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16979
16980                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16981                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16982                         error "unable to set mdd.*.$param"
16983         done
16984
16985         local start=$SECONDS
16986         for i in $(seq $MDSCOUNT); do
16987                 cl_users=(${CL_USERS[mds$i]})
16988                 cl_user1[mds$i]="${cl_users[0]}"
16989                 cl_user2[mds$i]="${cl_users[1]}"
16990
16991                 [ -n "${cl_user1[mds$i]}" ] ||
16992                         error "mds$i: user1 is not registered"
16993                 [ -n "${cl_user2[mds$i]}" ] ||
16994                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16995
16996                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16997                 [ -n "$user_rec1" ] ||
16998                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
16999                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17000                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17001                 [ -n "$user_rec2" ] ||
17002                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17003                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17004                      "$user_rec1 + 2 == $user_rec2"
17005                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17006                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17007                               "expected $user_rec1 + 2, but is $user_rec2"
17008                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17009                 [ -n "$user_rec2" ] ||
17010                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17011                 [ $user_rec1 == $user_rec2 ] ||
17012                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17013                               "expected $user_rec1, but is $user_rec2"
17014         done
17015
17016         # ensure we are past the previous changelog_min_gc_interval set above
17017         local sleep2=$((start + 2 - SECONDS))
17018         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17019         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17020         # cl_user1 should be OK because it recently processed records.
17021         for ((i = 0; i < MDSCOUNT; i++)); do
17022                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17023                         error "create $DIR/$tdir/d$i.3 failed"
17024         done
17025
17026         # ensure gc thread is done
17027         for i in $(mdts_nodes); do
17028                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17029                         error "$i: GC-thread not done"
17030         done
17031
17032         local first_rec
17033         for (( i = 1; i <= MDSCOUNT; i++ )); do
17034                 # check cl_user1 still registered
17035                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17036                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17037                 # check cl_user2 unregistered
17038                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17039                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17040
17041                 # check changelogs are present and starting at $user_rec1 + 1
17042                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17043                 [ -n "$user_rec1" ] ||
17044                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17045                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17046                             awk '{ print $1; exit; }')
17047
17048                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17049                 [ $((user_rec1 + 1)) == $first_rec ] ||
17050                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17051         done
17052 }
17053 run_test 160g "changelog garbage collect on idle records"
17054
17055 test_160h() {
17056         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17057         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17058                 skip "Need MDS version at least 2.10.56"
17059
17060         local mdts=$(comma_list $(mdts_nodes))
17061
17062         # Create a user
17063         changelog_register || error "first changelog_register failed"
17064         changelog_register || error "second changelog_register failed"
17065         local cl_users
17066         declare -A cl_user1
17067         declare -A cl_user2
17068         local user_rec1
17069         local user_rec2
17070         local i
17071
17072         # generate some changelog records to accumulate on each MDT
17073         # use all_char because created files should be evenly distributed
17074         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17075                 error "test_mkdir $tdir failed"
17076         for ((i = 0; i < MDSCOUNT; i++)); do
17077                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17078                         error "create $DIR/$tdir/d$i.1 failed"
17079         done
17080
17081         # check changelogs have been generated
17082         local nbcl=$(changelog_dump | wc -l)
17083         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17084
17085         for param in "changelog_max_idle_time=10" \
17086                      "changelog_gc=1" \
17087                      "changelog_min_gc_interval=2"; do
17088                 local MDT0=$(facet_svc $SINGLEMDS)
17089                 local var="${param%=*}"
17090                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17091
17092                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17093                 do_nodes $mdts $LCTL set_param mdd.*.$param
17094         done
17095
17096         # force cl_user2 to be idle (1st part)
17097         sleep 9
17098
17099         for i in $(seq $MDSCOUNT); do
17100                 cl_users=(${CL_USERS[mds$i]})
17101                 cl_user1[mds$i]="${cl_users[0]}"
17102                 cl_user2[mds$i]="${cl_users[1]}"
17103
17104                 [ -n "${cl_user1[mds$i]}" ] ||
17105                         error "mds$i: no user registered"
17106                 [ -n "${cl_user2[mds$i]}" ] ||
17107                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17108
17109                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17110                 [ -n "$user_rec1" ] ||
17111                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17112                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17113                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17114                 [ -n "$user_rec2" ] ||
17115                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17116                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17117                      "$user_rec1 + 2 == $user_rec2"
17118                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17119                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17120                               "$user_rec1 + 2, but is $user_rec2"
17121                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17122                 [ -n "$user_rec2" ] ||
17123                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17124                 [ $user_rec1 == $user_rec2 ] ||
17125                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17126                               "$user_rec1, but is $user_rec2"
17127         done
17128
17129         # force cl_user2 to be idle (2nd part) and to reach
17130         # changelog_max_idle_time
17131         sleep 2
17132
17133         # force each GC-thread start and block then
17134         # one per MDT/MDD, set fail_val accordingly
17135         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17136         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17137
17138         # generate more changelogs to trigger fail_loc
17139         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17140                 error "create $DIR/$tdir/${tfile}bis failed"
17141
17142         # stop MDT to stop GC-thread, should be done in back-ground as it will
17143         # block waiting for the thread to be released and exit
17144         declare -A stop_pids
17145         for i in $(seq $MDSCOUNT); do
17146                 stop mds$i &
17147                 stop_pids[mds$i]=$!
17148         done
17149
17150         for i in $(mdts_nodes); do
17151                 local facet
17152                 local nb=0
17153                 local facets=$(facets_up_on_host $i)
17154
17155                 for facet in ${facets//,/ }; do
17156                         if [[ $facet == mds* ]]; then
17157                                 nb=$((nb + 1))
17158                         fi
17159                 done
17160                 # ensure each MDS's gc threads are still present and all in "R"
17161                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17162                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17163                         error "$i: expected $nb GC-thread"
17164                 wait_update $i \
17165                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17166                         "R" 20 ||
17167                         error "$i: GC-thread not found in R-state"
17168                 # check umounts of each MDT on MDS have reached kthread_stop()
17169                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17170                         error "$i: expected $nb umount"
17171                 wait_update $i \
17172                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17173                         error "$i: umount not found in D-state"
17174         done
17175
17176         # release all GC-threads
17177         do_nodes $mdts $LCTL set_param fail_loc=0
17178
17179         # wait for MDT stop to complete
17180         for i in $(seq $MDSCOUNT); do
17181                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17182         done
17183
17184         # XXX
17185         # may try to check if any orphan changelog records are present
17186         # via ldiskfs/zfs and llog_reader...
17187
17188         # re-start/mount MDTs
17189         for i in $(seq $MDSCOUNT); do
17190                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17191                         error "Fail to start mds$i"
17192         done
17193
17194         local first_rec
17195         for i in $(seq $MDSCOUNT); do
17196                 # check cl_user1 still registered
17197                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17198                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17199                 # check cl_user2 unregistered
17200                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17201                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17202
17203                 # check changelogs are present and starting at $user_rec1 + 1
17204                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17205                 [ -n "$user_rec1" ] ||
17206                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17207                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17208                             awk '{ print $1; exit; }')
17209
17210                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17211                 [ $((user_rec1 + 1)) == $first_rec ] ||
17212                         error "mds$i: first index should be $user_rec1 + 1, " \
17213                               "but is $first_rec"
17214         done
17215 }
17216 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17217               "during mount"
17218
17219 test_160i() {
17220
17221         local mdts=$(comma_list $(mdts_nodes))
17222
17223         changelog_register || error "first changelog_register failed"
17224
17225         # generate some changelog records to accumulate on each MDT
17226         # use all_char because created files should be evenly distributed
17227         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17228                 error "test_mkdir $tdir failed"
17229         for ((i = 0; i < MDSCOUNT; i++)); do
17230                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17231                         error "create $DIR/$tdir/d$i.1 failed"
17232         done
17233
17234         # check changelogs have been generated
17235         local nbcl=$(changelog_dump | wc -l)
17236         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17237
17238         # simulate race between register and unregister
17239         # XXX as fail_loc is set per-MDS, with DNE configs the race
17240         # simulation will only occur for one MDT per MDS and for the
17241         # others the normal race scenario will take place
17242         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17243         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17244         do_nodes $mdts $LCTL set_param fail_val=1
17245
17246         # unregister 1st user
17247         changelog_deregister &
17248         local pid1=$!
17249         # wait some time for deregister work to reach race rdv
17250         sleep 2
17251         # register 2nd user
17252         changelog_register || error "2nd user register failed"
17253
17254         wait $pid1 || error "1st user deregister failed"
17255
17256         local i
17257         local last_rec
17258         declare -A LAST_REC
17259         for i in $(seq $MDSCOUNT); do
17260                 if changelog_users mds$i | grep "^cl"; then
17261                         # make sure new records are added with one user present
17262                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17263                                           awk '/^current.index:/ { print $NF }')
17264                 else
17265                         error "mds$i has no user registered"
17266                 fi
17267         done
17268
17269         # generate more changelog records to accumulate on each MDT
17270         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17271                 error "create $DIR/$tdir/${tfile}bis failed"
17272
17273         for i in $(seq $MDSCOUNT); do
17274                 last_rec=$(changelog_users $SINGLEMDS |
17275                            awk '/^current.index:/ { print $NF }')
17276                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17277                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17278                         error "changelogs are off on mds$i"
17279         done
17280 }
17281 run_test 160i "changelog user register/unregister race"
17282
17283 test_160j() {
17284         remote_mds_nodsh && skip "remote MDS with nodsh"
17285         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17286                 skip "Need MDS version at least 2.12.56"
17287
17288         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17289         stack_trap "umount $MOUNT2" EXIT
17290
17291         changelog_register || error "first changelog_register failed"
17292         stack_trap "changelog_deregister" EXIT
17293
17294         # generate some changelog
17295         # use all_char because created files should be evenly distributed
17296         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17297                 error "mkdir $tdir failed"
17298         for ((i = 0; i < MDSCOUNT; i++)); do
17299                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17300                         error "create $DIR/$tdir/d$i.1 failed"
17301         done
17302
17303         # open the changelog device
17304         exec 3>/dev/changelog-$FSNAME-MDT0000
17305         stack_trap "exec 3>&-" EXIT
17306         exec 4</dev/changelog-$FSNAME-MDT0000
17307         stack_trap "exec 4<&-" EXIT
17308
17309         # umount the first lustre mount
17310         umount $MOUNT
17311         stack_trap "mount_client $MOUNT" EXIT
17312
17313         # read changelog, which may or may not fail, but should not crash
17314         cat <&4 >/dev/null
17315
17316         # clear changelog
17317         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17318         changelog_users $SINGLEMDS | grep -q $cl_user ||
17319                 error "User $cl_user not found in changelog_users"
17320
17321         printf 'clear:'$cl_user':0' >&3
17322 }
17323 run_test 160j "client can be umounted while its chanangelog is being used"
17324
17325 test_160k() {
17326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17327         remote_mds_nodsh && skip "remote MDS with nodsh"
17328
17329         mkdir -p $DIR/$tdir/1/1
17330
17331         changelog_register || error "changelog_register failed"
17332         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17333
17334         changelog_users $SINGLEMDS | grep -q $cl_user ||
17335                 error "User '$cl_user' not found in changelog_users"
17336 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17337         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17338         rmdir $DIR/$tdir/1/1 & sleep 1
17339         mkdir $DIR/$tdir/2
17340         touch $DIR/$tdir/2/2
17341         rm -rf $DIR/$tdir/2
17342
17343         wait
17344         sleep 4
17345
17346         changelog_dump | grep rmdir || error "rmdir not recorded"
17347 }
17348 run_test 160k "Verify that changelog records are not lost"
17349
17350 # Verifies that a file passed as a parameter has recently had an operation
17351 # performed on it that has generated an MTIME changelog which contains the
17352 # correct parent FID. As files might reside on a different MDT from the
17353 # parent directory in DNE configurations, the FIDs are translated to paths
17354 # before being compared, which should be identical
17355 compare_mtime_changelog() {
17356         local file="${1}"
17357         local mdtidx
17358         local mtime
17359         local cl_fid
17360         local pdir
17361         local dir
17362
17363         mdtidx=$($LFS getstripe --mdt-index $file)
17364         mdtidx=$(printf "%04x" $mdtidx)
17365
17366         # Obtain the parent FID from the MTIME changelog
17367         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17368         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17369
17370         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17371         [ -z "$cl_fid" ] && error "parent FID not present"
17372
17373         # Verify that the path for the parent FID is the same as the path for
17374         # the test directory
17375         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17376
17377         dir=$(dirname $1)
17378
17379         [[ "${pdir%/}" == "$dir" ]] ||
17380                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17381 }
17382
17383 test_160l() {
17384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17385
17386         remote_mds_nodsh && skip "remote MDS with nodsh"
17387         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17388                 skip "Need MDS version at least 2.13.55"
17389
17390         local cl_user
17391
17392         changelog_register || error "changelog_register failed"
17393         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17394
17395         changelog_users $SINGLEMDS | grep -q $cl_user ||
17396                 error "User '$cl_user' not found in changelog_users"
17397
17398         # Clear some types so that MTIME changelogs are generated
17399         changelog_chmask "-CREAT"
17400         changelog_chmask "-CLOSE"
17401
17402         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17403
17404         # Test CL_MTIME during setattr
17405         touch $DIR/$tdir/$tfile
17406         compare_mtime_changelog $DIR/$tdir/$tfile
17407
17408         # Test CL_MTIME during close
17409         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17410         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17411 }
17412 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17413
17414 test_160m() {
17415         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17416         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17417                 skip "Need MDS version at least 2.14.51"
17418         local cl_users
17419         local cl_user1
17420         local cl_user2
17421         local pid1
17422
17423         # Create a user
17424         changelog_register || error "first changelog_register failed"
17425         changelog_register || error "second changelog_register failed"
17426
17427         cl_users=(${CL_USERS[mds1]})
17428         cl_user1="${cl_users[0]}"
17429         cl_user2="${cl_users[1]}"
17430         # generate some changelog records to accumulate on MDT0
17431         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17432         createmany -m $DIR/$tdir/$tfile 50 ||
17433                 error "create $DIR/$tdir/$tfile failed"
17434         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17435         rm -f $DIR/$tdir
17436
17437         # check changelogs have been generated
17438         local nbcl=$(changelog_dump | wc -l)
17439         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17440
17441 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17442         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17443
17444         __changelog_clear mds1 $cl_user1 +10
17445         __changelog_clear mds1 $cl_user2 0 &
17446         pid1=$!
17447         sleep 2
17448         __changelog_clear mds1 $cl_user1 0 ||
17449                 error "fail to cancel record for $cl_user1"
17450         wait $pid1
17451         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17452 }
17453 run_test 160m "Changelog clear race"
17454
17455 test_160n() {
17456         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17457         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17458                 skip "Need MDS version at least 2.14.51"
17459         local cl_users
17460         local cl_user1
17461         local cl_user2
17462         local pid1
17463         local first_rec
17464         local last_rec=0
17465
17466         # Create a user
17467         changelog_register || error "first changelog_register failed"
17468
17469         cl_users=(${CL_USERS[mds1]})
17470         cl_user1="${cl_users[0]}"
17471
17472         # generate some changelog records to accumulate on MDT0
17473         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17474         first_rec=$(changelog_users $SINGLEMDS |
17475                         awk '/^current.index:/ { print $NF }')
17476         while (( last_rec < (( first_rec + 65000)) )); do
17477                 createmany -m $DIR/$tdir/$tfile 10000 ||
17478                         error "create $DIR/$tdir/$tfile failed"
17479
17480                 for i in $(seq 0 10000); do
17481                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17482                                 > /dev/null
17483                 done
17484
17485                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17486                         error "unlinkmany failed unlink"
17487                 last_rec=$(changelog_users $SINGLEMDS |
17488                         awk '/^current.index:/ { print $NF }')
17489                 echo last record $last_rec
17490                 (( last_rec == 0 )) && error "no changelog found"
17491         done
17492
17493 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17494         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17495
17496         __changelog_clear mds1 $cl_user1 0 &
17497         pid1=$!
17498         sleep 2
17499         __changelog_clear mds1 $cl_user1 0 ||
17500                 error "fail to cancel record for $cl_user1"
17501         wait $pid1
17502         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17503 }
17504 run_test 160n "Changelog destroy race"
17505
17506 test_160o() {
17507         local mdt="$(facet_svc $SINGLEMDS)"
17508
17509         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17510         remote_mds_nodsh && skip "remote MDS with nodsh"
17511         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17512                 skip "Need MDS version at least 2.14.52"
17513
17514         changelog_register --user test_160o -m unlnk+close+open ||
17515                 error "changelog_register failed"
17516
17517         do_facet $SINGLEMDS $LCTL --device $mdt \
17518                                 changelog_register -u "Tt3_-#" &&
17519                 error "bad symbols in name should fail"
17520
17521         do_facet $SINGLEMDS $LCTL --device $mdt \
17522                                 changelog_register -u test_160o &&
17523                 error "the same name registration should fail"
17524
17525         do_facet $SINGLEMDS $LCTL --device $mdt \
17526                         changelog_register -u test_160toolongname &&
17527                 error "too long name registration should fail"
17528
17529         changelog_chmask "MARK+HSM"
17530         lctl get_param mdd.*.changelog*mask
17531         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17532         changelog_users $SINGLEMDS | grep -q $cl_user ||
17533                 error "User $cl_user not found in changelog_users"
17534         #verify username
17535         echo $cl_user | grep -q test_160o ||
17536                 error "User $cl_user has no specific name 'test160o'"
17537
17538         # change something
17539         changelog_clear 0 || error "changelog_clear failed"
17540         # generate some changelog records to accumulate on MDT0
17541         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17542         touch $DIR/$tdir/$tfile                 # open 1
17543
17544         OPENS=$(changelog_dump | grep -c "OPEN")
17545         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17546
17547         # must be no MKDIR it wasn't set as user mask
17548         MKDIR=$(changelog_dump | grep -c "MKDIR")
17549         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17550
17551         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17552                                 mdd.$mdt.changelog_current_mask -n)
17553         # register maskless user
17554         changelog_register || error "changelog_register failed"
17555         # effective mask should be not changed because it is not minimal
17556         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17557                                 mdd.$mdt.changelog_current_mask -n)
17558         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17559         # set server mask to minimal value
17560         changelog_chmask "MARK"
17561         # check effective mask again, should be treated as DEFMASK now
17562         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17563                                 mdd.$mdt.changelog_current_mask -n)
17564         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17565
17566         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17567                 # set server mask back to some value
17568                 changelog_chmask "CLOSE,UNLNK"
17569                 # check effective mask again, should not remain as DEFMASK
17570                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17571                                 mdd.$mdt.changelog_current_mask -n)
17572                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17573         fi
17574
17575         do_facet $SINGLEMDS $LCTL --device $mdt \
17576                                 changelog_deregister -u test_160o ||
17577                 error "cannot deregister by name"
17578 }
17579 run_test 160o "changelog user name and mask"
17580
17581 test_160p() {
17582         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17583         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17584                 skip "Need MDS version at least 2.14.51"
17585         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17586         local cl_users
17587         local cl_user1
17588         local entry_count
17589
17590         # Create a user
17591         changelog_register || error "first changelog_register failed"
17592
17593         cl_users=(${CL_USERS[mds1]})
17594         cl_user1="${cl_users[0]}"
17595
17596         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17597         createmany -m $DIR/$tdir/$tfile 50 ||
17598                 error "create $DIR/$tdir/$tfile failed"
17599         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17600         rm -rf $DIR/$tdir
17601
17602         # check changelogs have been generated
17603         entry_count=$(changelog_dump | wc -l)
17604         ((entry_count != 0)) || error "no changelog entries found"
17605
17606         # remove changelog_users and check that orphan entries are removed
17607         stop mds1
17608         local dev=$(mdsdevname 1)
17609         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17610         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17611         entry_count=$(changelog_dump | wc -l)
17612         ((entry_count == 0)) ||
17613                 error "found $entry_count changelog entries, expected none"
17614 }
17615 run_test 160p "Changelog orphan cleanup with no users"
17616
17617 test_160q() {
17618         local mdt="$(facet_svc $SINGLEMDS)"
17619         local clu
17620
17621         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17622         remote_mds_nodsh && skip "remote MDS with nodsh"
17623         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17624                 skip "Need MDS version at least 2.14.54"
17625
17626         # set server mask to minimal value like server init does
17627         changelog_chmask "MARK"
17628         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17629                 error "changelog_register failed"
17630         # check effective mask again, should be treated as DEFMASK now
17631         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17632                                 mdd.$mdt.changelog_current_mask -n)
17633         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17634                 error "changelog_deregister failed"
17635         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17636 }
17637 run_test 160q "changelog effective mask is DEFMASK if not set"
17638
17639 test_160s() {
17640         remote_mds_nodsh && skip "remote MDS with nodsh"
17641         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17642                 skip "Need MDS version at least 2.14.55"
17643
17644         local mdts=$(comma_list $(mdts_nodes))
17645
17646         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17647         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17648                                        fail_val=$((24 * 3600 * 10))
17649
17650         # Create a user which is 10 days old
17651         changelog_register || error "first changelog_register failed"
17652         local cl_users
17653         declare -A cl_user1
17654         local i
17655
17656         # generate some changelog records to accumulate on each MDT
17657         # use all_char because created files should be evenly distributed
17658         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17659                 error "test_mkdir $tdir failed"
17660         for ((i = 0; i < MDSCOUNT; i++)); do
17661                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17662                         error "create $DIR/$tdir/d$i.1 failed"
17663         done
17664
17665         # check changelogs have been generated
17666         local nbcl=$(changelog_dump | wc -l)
17667         (( nbcl > 0 )) || error "no changelogs found"
17668
17669         # reduce the max_idle_indexes value to make sure we exceed it
17670         for param in "changelog_max_idle_indexes=2097446912" \
17671                      "changelog_max_idle_time=2592000" \
17672                      "changelog_gc=1" \
17673                      "changelog_min_gc_interval=2"; do
17674                 local MDT0=$(facet_svc $SINGLEMDS)
17675                 local var="${param%=*}"
17676                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17677
17678                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17679                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17680                         error "unable to set mdd.*.$param"
17681         done
17682
17683         local start=$SECONDS
17684         for i in $(seq $MDSCOUNT); do
17685                 cl_users=(${CL_USERS[mds$i]})
17686                 cl_user1[mds$i]="${cl_users[0]}"
17687
17688                 [[ -n "${cl_user1[mds$i]}" ]] ||
17689                         error "mds$i: no user registered"
17690         done
17691
17692         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17693         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17694
17695         # ensure we are past the previous changelog_min_gc_interval set above
17696         local sleep2=$((start + 2 - SECONDS))
17697         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17698
17699         # Generate one more changelog to trigger GC
17700         for ((i = 0; i < MDSCOUNT; i++)); do
17701                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17702                         error "create $DIR/$tdir/d$i.3 failed"
17703         done
17704
17705         # ensure gc thread is done
17706         for node in $(mdts_nodes); do
17707                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17708                         error "$node: GC-thread not done"
17709         done
17710
17711         do_nodes $mdts $LCTL set_param fail_loc=0
17712
17713         for (( i = 1; i <= MDSCOUNT; i++ )); do
17714                 # check cl_user1 is purged
17715                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17716                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17717         done
17718         return 0
17719 }
17720 run_test 160s "changelog garbage collect on idle records * time"
17721
17722 test_160t() {
17723         remote_mds_nodsh && skip "remote MDS with nodsh"
17724         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17725                 skip "Need MDS version at least 2.15.50"
17726
17727         local MDT0=$(facet_svc $SINGLEMDS)
17728         local cl_users
17729         local cl_user1
17730         local cl_user2
17731         local start
17732
17733         changelog_register --user user1 -m all ||
17734                 error "user1 failed to register"
17735
17736         mkdir_on_mdt0 $DIR/$tdir
17737         # create default overstripe to maximize changelog size
17738         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17739         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17740         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17741
17742         # user2 consumes less records so less space
17743         changelog_register --user user2 || error "user2 failed to register"
17744         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17745         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17746
17747         # check changelogs have been generated
17748         local nbcl=$(changelog_dump | wc -l)
17749         (( nbcl > 0 )) || error "no changelogs found"
17750
17751         # reduce the changelog_min_gc_interval to force check
17752         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17753                 local var="${param%=*}"
17754                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17755
17756                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17757                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17758                         error "unable to set mdd.*.$param"
17759         done
17760
17761         start=$SECONDS
17762         cl_users=(${CL_USERS[mds1]})
17763         cl_user1="${cl_users[0]}"
17764         cl_user2="${cl_users[1]}"
17765
17766         [[ -n $cl_user1 ]] ||
17767                 error "mds1: user #1 isn't registered"
17768         [[ -n $cl_user2 ]] ||
17769                 error "mds1: user #2 isn't registered"
17770
17771         # ensure we are past the previous changelog_min_gc_interval set above
17772         local sleep2=$((start + 2 - SECONDS))
17773         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17774
17775         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17776         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17777                         fail_val=$(((llog_size1 + llog_size2) / 2))
17778
17779         # Generate more changelog to trigger GC
17780         createmany -o $DIR/$tdir/u3_ 4 ||
17781                 error "create failed for more files"
17782
17783         # ensure gc thread is done
17784         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17785                 error "mds1: GC-thread not done"
17786
17787         do_facet mds1 $LCTL set_param fail_loc=0
17788
17789         # check cl_user1 is purged
17790         changelog_users mds1 | grep -q "$cl_user1" &&
17791                 error "User $cl_user1 is registered"
17792         # check cl_user2 is not purged
17793         changelog_users mds1 | grep -q "$cl_user2" ||
17794                 error "User $cl_user2 is not registered"
17795 }
17796 run_test 160t "changelog garbage collect on lack of space"
17797
17798 test_161a() {
17799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17800
17801         test_mkdir -c1 $DIR/$tdir
17802         cp /etc/hosts $DIR/$tdir/$tfile
17803         test_mkdir -c1 $DIR/$tdir/foo1
17804         test_mkdir -c1 $DIR/$tdir/foo2
17805         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17806         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17807         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17808         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17809         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17810         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17811                 $LFS fid2path $DIR $FID
17812                 error "bad link ea"
17813         fi
17814         # middle
17815         rm $DIR/$tdir/foo2/zachary
17816         # last
17817         rm $DIR/$tdir/foo2/thor
17818         # first
17819         rm $DIR/$tdir/$tfile
17820         # rename
17821         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17822         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17823                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17824         rm $DIR/$tdir/foo2/maggie
17825
17826         # overflow the EA
17827         local longname=$tfile.avg_len_is_thirty_two_
17828         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17829                 error_noexit 'failed to unlink many hardlinks'" EXIT
17830         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17831                 error "failed to hardlink many files"
17832         links=$($LFS fid2path $DIR $FID | wc -l)
17833         echo -n "${links}/1000 links in link EA"
17834         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17835 }
17836 run_test 161a "link ea sanity"
17837
17838 test_161b() {
17839         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17840         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17841
17842         local MDTIDX=1
17843         local remote_dir=$DIR/$tdir/remote_dir
17844
17845         mkdir -p $DIR/$tdir
17846         $LFS mkdir -i $MDTIDX $remote_dir ||
17847                 error "create remote directory failed"
17848
17849         cp /etc/hosts $remote_dir/$tfile
17850         mkdir -p $remote_dir/foo1
17851         mkdir -p $remote_dir/foo2
17852         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17853         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17854         ln $remote_dir/$tfile $remote_dir/foo1/luna
17855         ln $remote_dir/$tfile $remote_dir/foo2/thor
17856
17857         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17858                      tr -d ']')
17859         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17860                 $LFS fid2path $DIR $FID
17861                 error "bad link ea"
17862         fi
17863         # middle
17864         rm $remote_dir/foo2/zachary
17865         # last
17866         rm $remote_dir/foo2/thor
17867         # first
17868         rm $remote_dir/$tfile
17869         # rename
17870         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17871         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17872         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17873                 $LFS fid2path $DIR $FID
17874                 error "bad link rename"
17875         fi
17876         rm $remote_dir/foo2/maggie
17877
17878         # overflow the EA
17879         local longname=filename_avg_len_is_thirty_two_
17880         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17881                 error "failed to hardlink many files"
17882         links=$($LFS fid2path $DIR $FID | wc -l)
17883         echo -n "${links}/1000 links in link EA"
17884         [[ ${links} -gt 60 ]] ||
17885                 error "expected at least 60 links in link EA"
17886         unlinkmany $remote_dir/foo2/$longname 1000 ||
17887         error "failed to unlink many hardlinks"
17888 }
17889 run_test 161b "link ea sanity under remote directory"
17890
17891 test_161c() {
17892         remote_mds_nodsh && skip "remote MDS with nodsh"
17893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17894         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17895                 skip "Need MDS version at least 2.1.5"
17896
17897         # define CLF_RENAME_LAST 0x0001
17898         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17899         changelog_register || error "changelog_register failed"
17900
17901         rm -rf $DIR/$tdir
17902         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17903         touch $DIR/$tdir/foo_161c
17904         touch $DIR/$tdir/bar_161c
17905         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17906         changelog_dump | grep RENME | tail -n 5
17907         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17908         changelog_clear 0 || error "changelog_clear failed"
17909         if [ x$flags != "x0x1" ]; then
17910                 error "flag $flags is not 0x1"
17911         fi
17912
17913         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17914         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17915         touch $DIR/$tdir/foo_161c
17916         touch $DIR/$tdir/bar_161c
17917         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17918         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17919         changelog_dump | grep RENME | tail -n 5
17920         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17921         changelog_clear 0 || error "changelog_clear failed"
17922         if [ x$flags != "x0x0" ]; then
17923                 error "flag $flags is not 0x0"
17924         fi
17925         echo "rename overwrite a target having nlink > 1," \
17926                 "changelog record has flags of $flags"
17927
17928         # rename doesn't overwrite a target (changelog flag 0x0)
17929         touch $DIR/$tdir/foo_161c
17930         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17931         changelog_dump | grep RENME | tail -n 5
17932         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17933         changelog_clear 0 || error "changelog_clear failed"
17934         if [ x$flags != "x0x0" ]; then
17935                 error "flag $flags is not 0x0"
17936         fi
17937         echo "rename doesn't overwrite a target," \
17938                 "changelog record has flags of $flags"
17939
17940         # define CLF_UNLINK_LAST 0x0001
17941         # unlink a file having nlink = 1 (changelog flag 0x1)
17942         rm -f $DIR/$tdir/foo2_161c
17943         changelog_dump | grep UNLNK | tail -n 5
17944         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17945         changelog_clear 0 || error "changelog_clear failed"
17946         if [ x$flags != "x0x1" ]; then
17947                 error "flag $flags is not 0x1"
17948         fi
17949         echo "unlink a file having nlink = 1," \
17950                 "changelog record has flags of $flags"
17951
17952         # unlink a file having nlink > 1 (changelog flag 0x0)
17953         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17954         rm -f $DIR/$tdir/foobar_161c
17955         changelog_dump | grep UNLNK | tail -n 5
17956         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17957         changelog_clear 0 || error "changelog_clear failed"
17958         if [ x$flags != "x0x0" ]; then
17959                 error "flag $flags is not 0x0"
17960         fi
17961         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17962 }
17963 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17964
17965 test_161d() {
17966         remote_mds_nodsh && skip "remote MDS with nodsh"
17967         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17968
17969         local pid
17970         local fid
17971
17972         changelog_register || error "changelog_register failed"
17973
17974         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17975         # interfer with $MOUNT/.lustre/fid/ access
17976         mkdir $DIR/$tdir
17977         [[ $? -eq 0 ]] || error "mkdir failed"
17978
17979         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17980         $LCTL set_param fail_loc=0x8000140c
17981         # 5s pause
17982         $LCTL set_param fail_val=5
17983
17984         # create file
17985         echo foofoo > $DIR/$tdir/$tfile &
17986         pid=$!
17987
17988         # wait for create to be delayed
17989         sleep 2
17990
17991         ps -p $pid
17992         [[ $? -eq 0 ]] || error "create should be blocked"
17993
17994         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17995         stack_trap "rm -f $tempfile"
17996         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
17997         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
17998         # some delay may occur during ChangeLog publishing and file read just
17999         # above, that could allow file write to happen finally
18000         [[ -s $tempfile ]] && echo "file should be empty"
18001
18002         $LCTL set_param fail_loc=0
18003
18004         wait $pid
18005         [[ $? -eq 0 ]] || error "create failed"
18006 }
18007 run_test 161d "create with concurrent .lustre/fid access"
18008
18009 check_path() {
18010         local expected="$1"
18011         shift
18012         local fid="$2"
18013
18014         local path
18015         path=$($LFS fid2path "$@")
18016         local rc=$?
18017
18018         if [ $rc -ne 0 ]; then
18019                 error "path looked up of '$expected' failed: rc=$rc"
18020         elif [ "$path" != "$expected" ]; then
18021                 error "path looked up '$path' instead of '$expected'"
18022         else
18023                 echo "FID '$fid' resolves to path '$path' as expected"
18024         fi
18025 }
18026
18027 test_162a() { # was test_162
18028         test_mkdir -p -c1 $DIR/$tdir/d2
18029         touch $DIR/$tdir/d2/$tfile
18030         touch $DIR/$tdir/d2/x1
18031         touch $DIR/$tdir/d2/x2
18032         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18033         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18034         # regular file
18035         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18036         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18037
18038         # softlink
18039         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18040         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18041         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18042
18043         # softlink to wrong file
18044         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18045         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18046         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18047
18048         # hardlink
18049         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18050         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18051         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18052         # fid2path dir/fsname should both work
18053         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18054         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18055
18056         # hardlink count: check that there are 2 links
18057         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18058         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18059
18060         # hardlink indexing: remove the first link
18061         rm $DIR/$tdir/d2/p/q/r/hlink
18062         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18063 }
18064 run_test 162a "path lookup sanity"
18065
18066 test_162b() {
18067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18069
18070         mkdir $DIR/$tdir
18071         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18072                                 error "create striped dir failed"
18073
18074         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18075                                         tail -n 1 | awk '{print $2}')
18076         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18077
18078         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18079         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18080
18081         # regular file
18082         for ((i=0;i<5;i++)); do
18083                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18084                         error "get fid for f$i failed"
18085                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18086
18087                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18088                         error "get fid for d$i failed"
18089                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18090         done
18091
18092         return 0
18093 }
18094 run_test 162b "striped directory path lookup sanity"
18095
18096 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18097 test_162c() {
18098         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18099                 skip "Need MDS version at least 2.7.51"
18100
18101         local lpath=$tdir.local
18102         local rpath=$tdir.remote
18103
18104         test_mkdir $DIR/$lpath
18105         test_mkdir $DIR/$rpath
18106
18107         for ((i = 0; i <= 101; i++)); do
18108                 lpath="$lpath/$i"
18109                 mkdir $DIR/$lpath
18110                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18111                         error "get fid for local directory $DIR/$lpath failed"
18112                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18113
18114                 rpath="$rpath/$i"
18115                 test_mkdir $DIR/$rpath
18116                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18117                         error "get fid for remote directory $DIR/$rpath failed"
18118                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18119         done
18120
18121         return 0
18122 }
18123 run_test 162c "fid2path works with paths 100 or more directories deep"
18124
18125 oalr_event_count() {
18126         local event="${1}"
18127         local trace="${2}"
18128
18129         awk -v name="${FSNAME}-OST0000" \
18130             -v event="${event}" \
18131             '$1 == "TRACE" && $2 == event && $3 == name' \
18132             "${trace}" |
18133         wc -l
18134 }
18135
18136 oalr_expect_event_count() {
18137         local event="${1}"
18138         local trace="${2}"
18139         local expect="${3}"
18140         local count
18141
18142         count=$(oalr_event_count "${event}" "${trace}")
18143         if ((count == expect)); then
18144                 return 0
18145         fi
18146
18147         error_noexit "${event} event count was '${count}', expected ${expect}"
18148         cat "${trace}" >&2
18149         exit 1
18150 }
18151
18152 cleanup_165() {
18153         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18154         stop ost1
18155         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18156 }
18157
18158 setup_165() {
18159         sync # Flush previous IOs so we can count log entries.
18160         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18161         stack_trap cleanup_165 EXIT
18162 }
18163
18164 test_165a() {
18165         local trace="/tmp/${tfile}.trace"
18166         local rc
18167         local count
18168
18169         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18170                 skip "OFD access log unsupported"
18171
18172         setup_165
18173         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18174         sleep 5
18175
18176         do_facet ost1 ofd_access_log_reader --list
18177         stop ost1
18178
18179         do_facet ost1 killall -TERM ofd_access_log_reader
18180         wait
18181         rc=$?
18182
18183         if ((rc != 0)); then
18184                 error "ofd_access_log_reader exited with rc = '${rc}'"
18185         fi
18186
18187         # Parse trace file for discovery events:
18188         oalr_expect_event_count alr_log_add "${trace}" 1
18189         oalr_expect_event_count alr_log_eof "${trace}" 1
18190         oalr_expect_event_count alr_log_free "${trace}" 1
18191 }
18192 run_test 165a "ofd access log discovery"
18193
18194 test_165b() {
18195         local trace="/tmp/${tfile}.trace"
18196         local file="${DIR}/${tfile}"
18197         local pfid1
18198         local pfid2
18199         local -a entry
18200         local rc
18201         local count
18202         local size
18203         local flags
18204
18205         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18206                 skip "OFD access log unsupported"
18207
18208         setup_165
18209         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18210         sleep 5
18211
18212         do_facet ost1 ofd_access_log_reader --list
18213
18214         lfs setstripe -c 1 -i 0 "${file}"
18215         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18216                 error "cannot create '${file}'"
18217
18218         sleep 5
18219         do_facet ost1 killall -TERM ofd_access_log_reader
18220         wait
18221         rc=$?
18222
18223         if ((rc != 0)); then
18224                 error "ofd_access_log_reader exited with rc = '${rc}'"
18225         fi
18226
18227         oalr_expect_event_count alr_log_entry "${trace}" 1
18228
18229         pfid1=$($LFS path2fid "${file}")
18230
18231         # 1     2             3   4    5     6   7    8    9     10
18232         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18233         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18234
18235         echo "entry = '${entry[*]}'" >&2
18236
18237         pfid2=${entry[4]}
18238         if [[ "${pfid1}" != "${pfid2}" ]]; then
18239                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18240         fi
18241
18242         size=${entry[8]}
18243         if ((size != 1048576)); then
18244                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18245         fi
18246
18247         flags=${entry[10]}
18248         if [[ "${flags}" != "w" ]]; then
18249                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18250         fi
18251
18252         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18253         sleep 5
18254
18255         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18256                 error "cannot read '${file}'"
18257         sleep 5
18258
18259         do_facet ost1 killall -TERM ofd_access_log_reader
18260         wait
18261         rc=$?
18262
18263         if ((rc != 0)); then
18264                 error "ofd_access_log_reader exited with rc = '${rc}'"
18265         fi
18266
18267         oalr_expect_event_count alr_log_entry "${trace}" 1
18268
18269         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18270         echo "entry = '${entry[*]}'" >&2
18271
18272         pfid2=${entry[4]}
18273         if [[ "${pfid1}" != "${pfid2}" ]]; then
18274                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18275         fi
18276
18277         size=${entry[8]}
18278         if ((size != 524288)); then
18279                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18280         fi
18281
18282         flags=${entry[10]}
18283         if [[ "${flags}" != "r" ]]; then
18284                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18285         fi
18286 }
18287 run_test 165b "ofd access log entries are produced and consumed"
18288
18289 test_165c() {
18290         local trace="/tmp/${tfile}.trace"
18291         local file="${DIR}/${tdir}/${tfile}"
18292
18293         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18294                 skip "OFD access log unsupported"
18295
18296         test_mkdir "${DIR}/${tdir}"
18297
18298         setup_165
18299         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18300         sleep 5
18301
18302         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18303
18304         # 4096 / 64 = 64. Create twice as many entries.
18305         for ((i = 0; i < 128; i++)); do
18306                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18307                         error "cannot create file"
18308         done
18309
18310         sync
18311
18312         do_facet ost1 killall -TERM ofd_access_log_reader
18313         wait
18314         rc=$?
18315         if ((rc != 0)); then
18316                 error "ofd_access_log_reader exited with rc = '${rc}'"
18317         fi
18318
18319         unlinkmany  "${file}-%d" 128
18320 }
18321 run_test 165c "full ofd access logs do not block IOs"
18322
18323 oal_get_read_count() {
18324         local stats="$1"
18325
18326         # STATS lustre-OST0001 alr_read_count 1
18327
18328         do_facet ost1 cat "${stats}" |
18329         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18330              END { print count; }'
18331 }
18332
18333 oal_expect_read_count() {
18334         local stats="$1"
18335         local count
18336         local expect="$2"
18337
18338         # Ask ofd_access_log_reader to write stats.
18339         do_facet ost1 killall -USR1 ofd_access_log_reader
18340
18341         # Allow some time for things to happen.
18342         sleep 1
18343
18344         count=$(oal_get_read_count "${stats}")
18345         if ((count == expect)); then
18346                 return 0
18347         fi
18348
18349         error_noexit "bad read count, got ${count}, expected ${expect}"
18350         do_facet ost1 cat "${stats}" >&2
18351         exit 1
18352 }
18353
18354 test_165d() {
18355         local stats="/tmp/${tfile}.stats"
18356         local file="${DIR}/${tdir}/${tfile}"
18357         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18358
18359         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18360                 skip "OFD access log unsupported"
18361
18362         test_mkdir "${DIR}/${tdir}"
18363
18364         setup_165
18365         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18366         sleep 5
18367
18368         lfs setstripe -c 1 -i 0 "${file}"
18369
18370         do_facet ost1 lctl set_param "${param}=rw"
18371         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18372                 error "cannot create '${file}'"
18373         oal_expect_read_count "${stats}" 1
18374
18375         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18376                 error "cannot read '${file}'"
18377         oal_expect_read_count "${stats}" 2
18378
18379         do_facet ost1 lctl set_param "${param}=r"
18380         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18381                 error "cannot create '${file}'"
18382         oal_expect_read_count "${stats}" 2
18383
18384         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18385                 error "cannot read '${file}'"
18386         oal_expect_read_count "${stats}" 3
18387
18388         do_facet ost1 lctl set_param "${param}=w"
18389         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18390                 error "cannot create '${file}'"
18391         oal_expect_read_count "${stats}" 4
18392
18393         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18394                 error "cannot read '${file}'"
18395         oal_expect_read_count "${stats}" 4
18396
18397         do_facet ost1 lctl set_param "${param}=0"
18398         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18399                 error "cannot create '${file}'"
18400         oal_expect_read_count "${stats}" 4
18401
18402         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18403                 error "cannot read '${file}'"
18404         oal_expect_read_count "${stats}" 4
18405
18406         do_facet ost1 killall -TERM ofd_access_log_reader
18407         wait
18408         rc=$?
18409         if ((rc != 0)); then
18410                 error "ofd_access_log_reader exited with rc = '${rc}'"
18411         fi
18412 }
18413 run_test 165d "ofd_access_log mask works"
18414
18415 test_165e() {
18416         local stats="/tmp/${tfile}.stats"
18417         local file0="${DIR}/${tdir}-0/${tfile}"
18418         local file1="${DIR}/${tdir}-1/${tfile}"
18419
18420         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18421                 skip "OFD access log unsupported"
18422
18423         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18424
18425         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18426         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18427
18428         lfs setstripe -c 1 -i 0 "${file0}"
18429         lfs setstripe -c 1 -i 0 "${file1}"
18430
18431         setup_165
18432         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18433         sleep 5
18434
18435         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18436                 error "cannot create '${file0}'"
18437         sync
18438         oal_expect_read_count "${stats}" 0
18439
18440         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18441                 error "cannot create '${file1}'"
18442         sync
18443         oal_expect_read_count "${stats}" 1
18444
18445         do_facet ost1 killall -TERM ofd_access_log_reader
18446         wait
18447         rc=$?
18448         if ((rc != 0)); then
18449                 error "ofd_access_log_reader exited with rc = '${rc}'"
18450         fi
18451 }
18452 run_test 165e "ofd_access_log MDT index filter works"
18453
18454 test_165f() {
18455         local trace="/tmp/${tfile}.trace"
18456         local rc
18457         local count
18458
18459         setup_165
18460         do_facet ost1 timeout 60 ofd_access_log_reader \
18461                 --exit-on-close --debug=- --trace=- > "${trace}" &
18462         sleep 5
18463         stop ost1
18464
18465         wait
18466         rc=$?
18467
18468         if ((rc != 0)); then
18469                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18470                 cat "${trace}"
18471                 exit 1
18472         fi
18473 }
18474 run_test 165f "ofd_access_log_reader --exit-on-close works"
18475
18476 test_169() {
18477         # do directio so as not to populate the page cache
18478         log "creating a 10 Mb file"
18479         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18480                 error "multiop failed while creating a file"
18481         log "starting reads"
18482         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18483         log "truncating the file"
18484         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18485                 error "multiop failed while truncating the file"
18486         log "killing dd"
18487         kill %+ || true # reads might have finished
18488         echo "wait until dd is finished"
18489         wait
18490         log "removing the temporary file"
18491         rm -rf $DIR/$tfile || error "tmp file removal failed"
18492 }
18493 run_test 169 "parallel read and truncate should not deadlock"
18494
18495 test_170() {
18496         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18497
18498         $LCTL clear     # bug 18514
18499         $LCTL debug_daemon start $TMP/${tfile}_log_good
18500         touch $DIR/$tfile
18501         $LCTL debug_daemon stop
18502         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18503                 error "sed failed to read log_good"
18504
18505         $LCTL debug_daemon start $TMP/${tfile}_log_good
18506         rm -rf $DIR/$tfile
18507         $LCTL debug_daemon stop
18508
18509         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18510                error "lctl df log_bad failed"
18511
18512         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18513         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18514
18515         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18516         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18517
18518         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18519                 error "bad_line good_line1 good_line2 are empty"
18520
18521         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18522         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18523         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18524
18525         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18526         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18527         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18528
18529         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18530                 error "bad_line_new good_line_new are empty"
18531
18532         local expected_good=$((good_line1 + good_line2*2))
18533
18534         rm -f $TMP/${tfile}*
18535         # LU-231, short malformed line may not be counted into bad lines
18536         if [ $bad_line -ne $bad_line_new ] &&
18537                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18538                 error "expected $bad_line bad lines, but got $bad_line_new"
18539                 return 1
18540         fi
18541
18542         if [ $expected_good -ne $good_line_new ]; then
18543                 error "expected $expected_good good lines, but got $good_line_new"
18544                 return 2
18545         fi
18546         true
18547 }
18548 run_test 170 "test lctl df to handle corrupted log ====================="
18549
18550 test_171() { # bug20592
18551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18552
18553         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18554         $LCTL set_param fail_loc=0x50e
18555         $LCTL set_param fail_val=3000
18556         multiop_bg_pause $DIR/$tfile O_s || true
18557         local MULTIPID=$!
18558         kill -USR1 $MULTIPID
18559         # cause log dump
18560         sleep 3
18561         wait $MULTIPID
18562         if dmesg | grep "recursive fault"; then
18563                 error "caught a recursive fault"
18564         fi
18565         $LCTL set_param fail_loc=0
18566         true
18567 }
18568 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18569
18570 test_172() {
18571
18572         #define OBD_FAIL_OBD_CLEANUP  0x60e
18573         $LCTL set_param fail_loc=0x60e
18574         umount $MOUNT || error "umount $MOUNT failed"
18575         stack_trap "mount_client $MOUNT"
18576
18577         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18578                 error "no client OBDs are remained"
18579
18580         $LCTL dl | while read devno state type name foo; do
18581                 case $type in
18582                 lov|osc|lmv|mdc)
18583                         $LCTL --device $name cleanup
18584                         $LCTL --device $name detach
18585                         ;;
18586                 *)
18587                         # skip server devices
18588                         ;;
18589                 esac
18590         done
18591
18592         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18593                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18594                 error "some client OBDs are still remained"
18595         fi
18596
18597 }
18598 run_test 172 "manual device removal with lctl cleanup/detach ======"
18599
18600 # it would be good to share it with obdfilter-survey/iokit-libecho code
18601 setup_obdecho_osc () {
18602         local rc=0
18603         local ost_nid=$1
18604         local obdfilter_name=$2
18605         echo "Creating new osc for $obdfilter_name on $ost_nid"
18606         # make sure we can find loopback nid
18607         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18608
18609         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18610                            ${obdfilter_name}_osc_UUID || rc=2; }
18611         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18612                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18613         return $rc
18614 }
18615
18616 cleanup_obdecho_osc () {
18617         local obdfilter_name=$1
18618         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18619         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18620         return 0
18621 }
18622
18623 obdecho_test() {
18624         local OBD=$1
18625         local node=$2
18626         local pages=${3:-64}
18627         local rc=0
18628         local id
18629
18630         local count=10
18631         local obd_size=$(get_obd_size $node $OBD)
18632         local page_size=$(get_page_size $node)
18633         if [[ -n "$obd_size" ]]; then
18634                 local new_count=$((obd_size / (pages * page_size / 1024)))
18635                 [[ $new_count -ge $count ]] || count=$new_count
18636         fi
18637
18638         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18639         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18640                            rc=2; }
18641         if [ $rc -eq 0 ]; then
18642             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18643             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18644         fi
18645         echo "New object id is $id"
18646         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18647                            rc=4; }
18648         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18649                            "test_brw $count w v $pages $id" || rc=4; }
18650         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18651                            rc=4; }
18652         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18653                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18654         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18655                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18656         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18657         return $rc
18658 }
18659
18660 test_180a() {
18661         skip "obdecho on osc is no longer supported"
18662 }
18663 run_test 180a "test obdecho on osc"
18664
18665 test_180b() {
18666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18667         remote_ost_nodsh && skip "remote OST with nodsh"
18668
18669         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18670                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18671                 error "failed to load module obdecho"
18672
18673         local target=$(do_facet ost1 $LCTL dl |
18674                        awk '/obdfilter/ { print $4; exit; }')
18675
18676         if [ -n "$target" ]; then
18677                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18678         else
18679                 do_facet ost1 $LCTL dl
18680                 error "there is no obdfilter target on ost1"
18681         fi
18682 }
18683 run_test 180b "test obdecho directly on obdfilter"
18684
18685 test_180c() { # LU-2598
18686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18687         remote_ost_nodsh && skip "remote OST with nodsh"
18688         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18689                 skip "Need MDS version at least 2.4.0"
18690
18691         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18692                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18693                 error "failed to load module obdecho"
18694
18695         local target=$(do_facet ost1 $LCTL dl |
18696                        awk '/obdfilter/ { print $4; exit; }')
18697
18698         if [ -n "$target" ]; then
18699                 local pages=16384 # 64MB bulk I/O RPC size
18700
18701                 obdecho_test "$target" ost1 "$pages" ||
18702                         error "obdecho_test with pages=$pages failed with $?"
18703         else
18704                 do_facet ost1 $LCTL dl
18705                 error "there is no obdfilter target on ost1"
18706         fi
18707 }
18708 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18709
18710 test_181() { # bug 22177
18711         test_mkdir $DIR/$tdir
18712         # create enough files to index the directory
18713         createmany -o $DIR/$tdir/foobar 4000
18714         # print attributes for debug purpose
18715         lsattr -d .
18716         # open dir
18717         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18718         MULTIPID=$!
18719         # remove the files & current working dir
18720         unlinkmany $DIR/$tdir/foobar 4000
18721         rmdir $DIR/$tdir
18722         kill -USR1 $MULTIPID
18723         wait $MULTIPID
18724         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18725         return 0
18726 }
18727 run_test 181 "Test open-unlinked dir ========================"
18728
18729 test_182a() {
18730         local fcount=1000
18731         local tcount=10
18732
18733         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18734
18735         $LCTL set_param mdc.*.rpc_stats=clear
18736
18737         for (( i = 0; i < $tcount; i++ )) ; do
18738                 mkdir $DIR/$tdir/$i
18739         done
18740
18741         for (( i = 0; i < $tcount; i++ )) ; do
18742                 createmany -o $DIR/$tdir/$i/f- $fcount &
18743         done
18744         wait
18745
18746         for (( i = 0; i < $tcount; i++ )) ; do
18747                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18748         done
18749         wait
18750
18751         $LCTL get_param mdc.*.rpc_stats
18752
18753         rm -rf $DIR/$tdir
18754 }
18755 run_test 182a "Test parallel modify metadata operations from mdc"
18756
18757 test_182b() {
18758         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18759         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18760         local dcount=1000
18761         local tcount=10
18762         local stime
18763         local etime
18764         local delta
18765
18766         do_facet mds1 $LCTL list_param \
18767                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18768                 skip "MDS lacks parallel RPC handling"
18769
18770         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18771
18772         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18773                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18774
18775         stime=$(date +%s)
18776         createmany -i 0 -d $DIR/$tdir/t- $tcount
18777
18778         for (( i = 0; i < $tcount; i++ )) ; do
18779                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18780         done
18781         wait
18782         etime=$(date +%s)
18783         delta=$((etime - stime))
18784         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18785
18786         stime=$(date +%s)
18787         for (( i = 0; i < $tcount; i++ )) ; do
18788                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18789         done
18790         wait
18791         etime=$(date +%s)
18792         delta=$((etime - stime))
18793         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18794
18795         rm -rf $DIR/$tdir
18796
18797         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18798
18799         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18800
18801         stime=$(date +%s)
18802         createmany -i 0 -d $DIR/$tdir/t- $tcount
18803
18804         for (( i = 0; i < $tcount; i++ )) ; do
18805                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18806         done
18807         wait
18808         etime=$(date +%s)
18809         delta=$((etime - stime))
18810         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18811
18812         stime=$(date +%s)
18813         for (( i = 0; i < $tcount; i++ )) ; do
18814                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18815         done
18816         wait
18817         etime=$(date +%s)
18818         delta=$((etime - stime))
18819         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18820
18821         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18822 }
18823 run_test 182b "Test parallel modify metadata operations from osp"
18824
18825 test_183() { # LU-2275
18826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18827         remote_mds_nodsh && skip "remote MDS with nodsh"
18828         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18829                 skip "Need MDS version at least 2.3.56"
18830
18831         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18832         echo aaa > $DIR/$tdir/$tfile
18833
18834 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18835         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18836
18837         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18838         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18839
18840         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18841
18842         # Flush negative dentry cache
18843         touch $DIR/$tdir/$tfile
18844
18845         # We are not checking for any leaked references here, they'll
18846         # become evident next time we do cleanup with module unload.
18847         rm -rf $DIR/$tdir
18848 }
18849 run_test 183 "No crash or request leak in case of strange dispositions ========"
18850
18851 # test suite 184 is for LU-2016, LU-2017
18852 test_184a() {
18853         check_swap_layouts_support
18854
18855         dir0=$DIR/$tdir/$testnum
18856         test_mkdir -p -c1 $dir0
18857         ref1=/etc/passwd
18858         ref2=/etc/group
18859         file1=$dir0/f1
18860         file2=$dir0/f2
18861         $LFS setstripe -c1 $file1
18862         cp $ref1 $file1
18863         $LFS setstripe -c2 $file2
18864         cp $ref2 $file2
18865         gen1=$($LFS getstripe -g $file1)
18866         gen2=$($LFS getstripe -g $file2)
18867
18868         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18869         gen=$($LFS getstripe -g $file1)
18870         [[ $gen1 != $gen ]] ||
18871                 error "Layout generation on $file1 does not change"
18872         gen=$($LFS getstripe -g $file2)
18873         [[ $gen2 != $gen ]] ||
18874                 error "Layout generation on $file2 does not change"
18875
18876         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18877         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18878
18879         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18880 }
18881 run_test 184a "Basic layout swap"
18882
18883 test_184b() {
18884         check_swap_layouts_support
18885
18886         dir0=$DIR/$tdir/$testnum
18887         mkdir -p $dir0 || error "creating dir $dir0"
18888         file1=$dir0/f1
18889         file2=$dir0/f2
18890         file3=$dir0/f3
18891         dir1=$dir0/d1
18892         dir2=$dir0/d2
18893         mkdir $dir1 $dir2
18894         $LFS setstripe -c1 $file1
18895         $LFS setstripe -c2 $file2
18896         $LFS setstripe -c1 $file3
18897         chown $RUNAS_ID $file3
18898         gen1=$($LFS getstripe -g $file1)
18899         gen2=$($LFS getstripe -g $file2)
18900
18901         $LFS swap_layouts $dir1 $dir2 &&
18902                 error "swap of directories layouts should fail"
18903         $LFS swap_layouts $dir1 $file1 &&
18904                 error "swap of directory and file layouts should fail"
18905         $RUNAS $LFS swap_layouts $file1 $file2 &&
18906                 error "swap of file we cannot write should fail"
18907         $LFS swap_layouts $file1 $file3 &&
18908                 error "swap of file with different owner should fail"
18909         /bin/true # to clear error code
18910 }
18911 run_test 184b "Forbidden layout swap (will generate errors)"
18912
18913 test_184c() {
18914         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18915         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18916         check_swap_layouts_support
18917         check_swap_layout_no_dom $DIR
18918
18919         local dir0=$DIR/$tdir/$testnum
18920         mkdir -p $dir0 || error "creating dir $dir0"
18921
18922         local ref1=$dir0/ref1
18923         local ref2=$dir0/ref2
18924         local file1=$dir0/file1
18925         local file2=$dir0/file2
18926         # create a file large enough for the concurrent test
18927         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18928         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18929         echo "ref file size: ref1($(stat -c %s $ref1))," \
18930              "ref2($(stat -c %s $ref2))"
18931
18932         cp $ref2 $file2
18933         dd if=$ref1 of=$file1 bs=16k &
18934         local DD_PID=$!
18935
18936         # Make sure dd starts to copy file, but wait at most 5 seconds
18937         local loops=0
18938         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18939
18940         $LFS swap_layouts $file1 $file2
18941         local rc=$?
18942         wait $DD_PID
18943         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18944         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18945
18946         # how many bytes copied before swapping layout
18947         local copied=$(stat -c %s $file2)
18948         local remaining=$(stat -c %s $ref1)
18949         remaining=$((remaining - copied))
18950         echo "Copied $copied bytes before swapping layout..."
18951
18952         cmp -n $copied $file1 $ref2 | grep differ &&
18953                 error "Content mismatch [0, $copied) of ref2 and file1"
18954         cmp -n $copied $file2 $ref1 ||
18955                 error "Content mismatch [0, $copied) of ref1 and file2"
18956         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18957                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18958
18959         # clean up
18960         rm -f $ref1 $ref2 $file1 $file2
18961 }
18962 run_test 184c "Concurrent write and layout swap"
18963
18964 test_184d() {
18965         check_swap_layouts_support
18966         check_swap_layout_no_dom $DIR
18967         [ -z "$(which getfattr 2>/dev/null)" ] &&
18968                 skip_env "no getfattr command"
18969
18970         local file1=$DIR/$tdir/$tfile-1
18971         local file2=$DIR/$tdir/$tfile-2
18972         local file3=$DIR/$tdir/$tfile-3
18973         local lovea1
18974         local lovea2
18975
18976         mkdir -p $DIR/$tdir
18977         touch $file1 || error "create $file1 failed"
18978         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18979                 error "create $file2 failed"
18980         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18981                 error "create $file3 failed"
18982         lovea1=$(get_layout_param $file1)
18983
18984         $LFS swap_layouts $file2 $file3 ||
18985                 error "swap $file2 $file3 layouts failed"
18986         $LFS swap_layouts $file1 $file2 ||
18987                 error "swap $file1 $file2 layouts failed"
18988
18989         lovea2=$(get_layout_param $file2)
18990         echo "$lovea1"
18991         echo "$lovea2"
18992         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18993
18994         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18995         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18996 }
18997 run_test 184d "allow stripeless layouts swap"
18998
18999 test_184e() {
19000         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19001                 skip "Need MDS version at least 2.6.94"
19002         check_swap_layouts_support
19003         check_swap_layout_no_dom $DIR
19004         [ -z "$(which getfattr 2>/dev/null)" ] &&
19005                 skip_env "no getfattr command"
19006
19007         local file1=$DIR/$tdir/$tfile-1
19008         local file2=$DIR/$tdir/$tfile-2
19009         local file3=$DIR/$tdir/$tfile-3
19010         local lovea
19011
19012         mkdir -p $DIR/$tdir
19013         touch $file1 || error "create $file1 failed"
19014         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19015                 error "create $file2 failed"
19016         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19017                 error "create $file3 failed"
19018
19019         $LFS swap_layouts $file1 $file2 ||
19020                 error "swap $file1 $file2 layouts failed"
19021
19022         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19023         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19024
19025         echo 123 > $file1 || error "Should be able to write into $file1"
19026
19027         $LFS swap_layouts $file1 $file3 ||
19028                 error "swap $file1 $file3 layouts failed"
19029
19030         echo 123 > $file1 || error "Should be able to write into $file1"
19031
19032         rm -rf $file1 $file2 $file3
19033 }
19034 run_test 184e "Recreate layout after stripeless layout swaps"
19035
19036 test_184f() {
19037         # Create a file with name longer than sizeof(struct stat) ==
19038         # 144 to see if we can get chars from the file name to appear
19039         # in the returned striping. Note that 'f' == 0x66.
19040         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19041
19042         mkdir -p $DIR/$tdir
19043         mcreate $DIR/$tdir/$file
19044         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19045                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19046         fi
19047 }
19048 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19049
19050 test_185() { # LU-2441
19051         # LU-3553 - no volatile file support in old servers
19052         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19053                 skip "Need MDS version at least 2.3.60"
19054
19055         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19056         touch $DIR/$tdir/spoo
19057         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19058         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19059                 error "cannot create/write a volatile file"
19060         [ "$FILESET" == "" ] &&
19061         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19062                 error "FID is still valid after close"
19063
19064         multiop_bg_pause $DIR/$tdir vVw4096_c
19065         local multi_pid=$!
19066
19067         local OLD_IFS=$IFS
19068         IFS=":"
19069         local fidv=($fid)
19070         IFS=$OLD_IFS
19071         # assume that the next FID for this client is sequential, since stdout
19072         # is unfortunately eaten by multiop_bg_pause
19073         local n=$((${fidv[1]} + 1))
19074         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19075         if [ "$FILESET" == "" ]; then
19076                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19077                         error "FID is missing before close"
19078         fi
19079         kill -USR1 $multi_pid
19080         # 1 second delay, so if mtime change we will see it
19081         sleep 1
19082         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19083         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19084 }
19085 run_test 185 "Volatile file support"
19086
19087 function create_check_volatile() {
19088         local idx=$1
19089         local tgt
19090
19091         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19092         local PID=$!
19093         sleep 1
19094         local FID=$(cat /tmp/${tfile}.fid)
19095         [ "$FID" == "" ] && error "can't get FID for volatile"
19096         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19097         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19098         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19099         kill -USR1 $PID
19100         wait
19101         sleep 1
19102         cancel_lru_locks mdc # flush opencache
19103         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19104         return 0
19105 }
19106
19107 test_185a(){
19108         # LU-12516 - volatile creation via .lustre
19109         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19110                 skip "Need MDS version at least 2.3.55"
19111
19112         create_check_volatile 0
19113         [ $MDSCOUNT -lt 2 ] && return 0
19114
19115         # DNE case
19116         create_check_volatile 1
19117
19118         return 0
19119 }
19120 run_test 185a "Volatile file creation in .lustre/fid/"
19121
19122 test_187a() {
19123         remote_mds_nodsh && skip "remote MDS with nodsh"
19124         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19125                 skip "Need MDS version at least 2.3.0"
19126
19127         local dir0=$DIR/$tdir/$testnum
19128         mkdir -p $dir0 || error "creating dir $dir0"
19129
19130         local file=$dir0/file1
19131         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19132         local dv1=$($LFS data_version $file)
19133         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19134         local dv2=$($LFS data_version $file)
19135         [[ $dv1 != $dv2 ]] ||
19136                 error "data version did not change on write $dv1 == $dv2"
19137
19138         # clean up
19139         rm -f $file1
19140 }
19141 run_test 187a "Test data version change"
19142
19143 test_187b() {
19144         remote_mds_nodsh && skip "remote MDS with nodsh"
19145         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19146                 skip "Need MDS version at least 2.3.0"
19147
19148         local dir0=$DIR/$tdir/$testnum
19149         mkdir -p $dir0 || error "creating dir $dir0"
19150
19151         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19152         [[ ${DV[0]} != ${DV[1]} ]] ||
19153                 error "data version did not change on write"\
19154                       " ${DV[0]} == ${DV[1]}"
19155
19156         # clean up
19157         rm -f $file1
19158 }
19159 run_test 187b "Test data version change on volatile file"
19160
19161 test_200() {
19162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19163         remote_mgs_nodsh && skip "remote MGS with nodsh"
19164         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19165
19166         local POOL=${POOL:-cea1}
19167         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19168         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19169         # Pool OST targets
19170         local first_ost=0
19171         local last_ost=$(($OSTCOUNT - 1))
19172         local ost_step=2
19173         local ost_list=$(seq $first_ost $ost_step $last_ost)
19174         local ost_range="$first_ost $last_ost $ost_step"
19175         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19176         local file_dir=$POOL_ROOT/file_tst
19177         local subdir=$test_path/subdir
19178         local rc=0
19179
19180         while : ; do
19181                 # former test_200a test_200b
19182                 pool_add $POOL                          || { rc=$? ; break; }
19183                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19184                 # former test_200c test_200d
19185                 mkdir -p $test_path
19186                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19187                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19188                 mkdir -p $subdir
19189                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19190                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19191                                                         || { rc=$? ; break; }
19192                 # former test_200e test_200f
19193                 local files=$((OSTCOUNT*3))
19194                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19195                                                         || { rc=$? ; break; }
19196                 pool_create_files $POOL $file_dir $files "$ost_list" \
19197                                                         || { rc=$? ; break; }
19198                 # former test_200g test_200h
19199                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19200                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19201
19202                 # former test_201a test_201b test_201c
19203                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19204
19205                 local f=$test_path/$tfile
19206                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19207                 pool_remove $POOL $f                    || { rc=$? ; break; }
19208                 break
19209         done
19210
19211         destroy_test_pools
19212
19213         return $rc
19214 }
19215 run_test 200 "OST pools"
19216
19217 # usage: default_attr <count | size | offset>
19218 default_attr() {
19219         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19220 }
19221
19222 # usage: check_default_stripe_attr
19223 check_default_stripe_attr() {
19224         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19225         case $1 in
19226         --stripe-count|-c)
19227                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19228         --stripe-size|-S)
19229                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19230         --stripe-index|-i)
19231                 EXPECTED=-1;;
19232         *)
19233                 error "unknown getstripe attr '$1'"
19234         esac
19235
19236         [ $ACTUAL == $EXPECTED ] ||
19237                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19238 }
19239
19240 test_204a() {
19241         test_mkdir $DIR/$tdir
19242         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19243
19244         check_default_stripe_attr --stripe-count
19245         check_default_stripe_attr --stripe-size
19246         check_default_stripe_attr --stripe-index
19247 }
19248 run_test 204a "Print default stripe attributes"
19249
19250 test_204b() {
19251         test_mkdir $DIR/$tdir
19252         $LFS setstripe --stripe-count 1 $DIR/$tdir
19253
19254         check_default_stripe_attr --stripe-size
19255         check_default_stripe_attr --stripe-index
19256 }
19257 run_test 204b "Print default stripe size and offset"
19258
19259 test_204c() {
19260         test_mkdir $DIR/$tdir
19261         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19262
19263         check_default_stripe_attr --stripe-count
19264         check_default_stripe_attr --stripe-index
19265 }
19266 run_test 204c "Print default stripe count and offset"
19267
19268 test_204d() {
19269         test_mkdir $DIR/$tdir
19270         $LFS setstripe --stripe-index 0 $DIR/$tdir
19271
19272         check_default_stripe_attr --stripe-count
19273         check_default_stripe_attr --stripe-size
19274 }
19275 run_test 204d "Print default stripe count and size"
19276
19277 test_204e() {
19278         test_mkdir $DIR/$tdir
19279         $LFS setstripe -d $DIR/$tdir
19280
19281         check_default_stripe_attr --stripe-count --raw
19282         check_default_stripe_attr --stripe-size --raw
19283         check_default_stripe_attr --stripe-index --raw
19284 }
19285 run_test 204e "Print raw stripe attributes"
19286
19287 test_204f() {
19288         test_mkdir $DIR/$tdir
19289         $LFS setstripe --stripe-count 1 $DIR/$tdir
19290
19291         check_default_stripe_attr --stripe-size --raw
19292         check_default_stripe_attr --stripe-index --raw
19293 }
19294 run_test 204f "Print raw stripe size and offset"
19295
19296 test_204g() {
19297         test_mkdir $DIR/$tdir
19298         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19299
19300         check_default_stripe_attr --stripe-count --raw
19301         check_default_stripe_attr --stripe-index --raw
19302 }
19303 run_test 204g "Print raw stripe count and offset"
19304
19305 test_204h() {
19306         test_mkdir $DIR/$tdir
19307         $LFS setstripe --stripe-index 0 $DIR/$tdir
19308
19309         check_default_stripe_attr --stripe-count --raw
19310         check_default_stripe_attr --stripe-size --raw
19311 }
19312 run_test 204h "Print raw stripe count and size"
19313
19314 # Figure out which job scheduler is being used, if any,
19315 # or use a fake one
19316 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19317         JOBENV=SLURM_JOB_ID
19318 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19319         JOBENV=LSB_JOBID
19320 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19321         JOBENV=PBS_JOBID
19322 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19323         JOBENV=LOADL_STEP_ID
19324 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19325         JOBENV=JOB_ID
19326 else
19327         $LCTL list_param jobid_name > /dev/null 2>&1
19328         if [ $? -eq 0 ]; then
19329                 JOBENV=nodelocal
19330         else
19331                 JOBENV=FAKE_JOBID
19332         fi
19333 fi
19334 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19335
19336 verify_jobstats() {
19337         local cmd=($1)
19338         shift
19339         local facets="$@"
19340
19341 # we don't really need to clear the stats for this test to work, since each
19342 # command has a unique jobid, but it makes debugging easier if needed.
19343 #       for facet in $facets; do
19344 #               local dev=$(convert_facet2label $facet)
19345 #               # clear old jobstats
19346 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19347 #       done
19348
19349         # use a new JobID for each test, or we might see an old one
19350         [ "$JOBENV" = "FAKE_JOBID" ] &&
19351                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19352
19353         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19354
19355         [ "$JOBENV" = "nodelocal" ] && {
19356                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19357                 $LCTL set_param jobid_name=$FAKE_JOBID
19358                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19359         }
19360
19361         log "Test: ${cmd[*]}"
19362         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19363
19364         if [ $JOBENV = "FAKE_JOBID" ]; then
19365                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19366         else
19367                 ${cmd[*]}
19368         fi
19369
19370         # all files are created on OST0000
19371         for facet in $facets; do
19372                 local stats="*.$(convert_facet2label $facet).job_stats"
19373
19374                 # strip out libtool wrappers for in-tree executables
19375                 if (( $(do_facet $facet lctl get_param $stats |
19376                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19377                         do_facet $facet lctl get_param $stats
19378                         error "No jobstats for $JOBVAL found on $facet::$stats"
19379                 fi
19380         done
19381 }
19382
19383 jobstats_set() {
19384         local new_jobenv=$1
19385
19386         set_persistent_param_and_check client "jobid_var" \
19387                 "$FSNAME.sys.jobid_var" $new_jobenv
19388 }
19389
19390 test_205a() { # Job stats
19391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19392         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19393                 skip "Need MDS version with at least 2.7.1"
19394         remote_mgs_nodsh && skip "remote MGS with nodsh"
19395         remote_mds_nodsh && skip "remote MDS with nodsh"
19396         remote_ost_nodsh && skip "remote OST with nodsh"
19397         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19398                 skip "Server doesn't support jobstats"
19399         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19400
19401         local old_jobenv=$($LCTL get_param -n jobid_var)
19402         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19403         stack_trap "jobstats_set $old_jobenv" EXIT
19404
19405         changelog_register
19406
19407         local old_jobid_name=$($LCTL get_param jobid_name)
19408         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19409
19410         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19411                                 mdt.*.job_cleanup_interval | head -n 1)
19412         local new_interval=5
19413         do_facet $SINGLEMDS \
19414                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19415         stack_trap "do_facet $SINGLEMDS \
19416                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19417         local start=$SECONDS
19418
19419         local cmd
19420         # mkdir
19421         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19422         verify_jobstats "$cmd" "$SINGLEMDS"
19423         # rmdir
19424         cmd="rmdir $DIR/$tdir"
19425         verify_jobstats "$cmd" "$SINGLEMDS"
19426         # mkdir on secondary MDT
19427         if [ $MDSCOUNT -gt 1 ]; then
19428                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19429                 verify_jobstats "$cmd" "mds2"
19430         fi
19431         # mknod
19432         cmd="mknod $DIR/$tfile c 1 3"
19433         verify_jobstats "$cmd" "$SINGLEMDS"
19434         # unlink
19435         cmd="rm -f $DIR/$tfile"
19436         verify_jobstats "$cmd" "$SINGLEMDS"
19437         # create all files on OST0000 so verify_jobstats can find OST stats
19438         # open & close
19439         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19440         verify_jobstats "$cmd" "$SINGLEMDS"
19441         # setattr
19442         cmd="touch $DIR/$tfile"
19443         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19444         # write
19445         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19446         verify_jobstats "$cmd" "ost1"
19447         # read
19448         cancel_lru_locks osc
19449         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19450         verify_jobstats "$cmd" "ost1"
19451         # truncate
19452         cmd="$TRUNCATE $DIR/$tfile 0"
19453         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19454         # rename
19455         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19456         verify_jobstats "$cmd" "$SINGLEMDS"
19457         # jobstats expiry - sleep until old stats should be expired
19458         local left=$((new_interval + 5 - (SECONDS - start)))
19459         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19460                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19461                         "0" $left
19462         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19463         verify_jobstats "$cmd" "$SINGLEMDS"
19464         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19465             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19466
19467         # Ensure that jobid are present in changelog (if supported by MDS)
19468         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19469                 changelog_dump | tail -10
19470                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19471                 [ $jobids -eq 9 ] ||
19472                         error "Wrong changelog jobid count $jobids != 9"
19473
19474                 # LU-5862
19475                 JOBENV="disable"
19476                 jobstats_set $JOBENV
19477                 touch $DIR/$tfile
19478                 changelog_dump | grep $tfile
19479                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19480                 [ $jobids -eq 0 ] ||
19481                         error "Unexpected jobids when jobid_var=$JOBENV"
19482         fi
19483
19484         # test '%j' access to environment variable - if supported
19485         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19486                 JOBENV="JOBCOMPLEX"
19487                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19488
19489                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19490         fi
19491
19492         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19493                 JOBENV="JOBCOMPLEX"
19494                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19495
19496                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19497         fi
19498
19499         # test '%j' access to per-session jobid - if supported
19500         if lctl list_param jobid_this_session > /dev/null 2>&1
19501         then
19502                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19503                 lctl set_param jobid_this_session=$USER
19504
19505                 JOBENV="JOBCOMPLEX"
19506                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19507
19508                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19509         fi
19510 }
19511 run_test 205a "Verify job stats"
19512
19513 # LU-13117, LU-13597, LU-16599
19514 test_205b() {
19515         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19516                 skip "Need MDS version at least 2.13.54.91"
19517
19518         local job_stats="mdt.*.job_stats"
19519         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19520
19521         do_facet mds1 $LCTL set_param $job_stats=clear
19522
19523         # Setting jobid_var to USER might not be supported
19524         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19525         $LCTL set_param jobid_var=USER || true
19526         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19527         $LCTL set_param jobid_name="%j.%e.%u"
19528
19529         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19530         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19531                 { do_facet mds1 $LCTL get_param $job_stats;
19532                   error "Unexpected jobid found"; }
19533         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19534                 { do_facet mds1 $LCTL get_param $job_stats;
19535                   error "wrong job_stats format found"; }
19536
19537         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19538                 echo "MDS does not yet escape jobid" && return 0
19539
19540         mkdir_on_mdt0 $DIR/$tdir
19541         $LCTL set_param jobid_var=TEST205b
19542         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19543         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19544                       awk '/has\\x20sp/ {print $3}')
19545         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19546                   error "jobid not escaped"; }
19547
19548         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19549                 # need to run such a command on mds1:
19550                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19551                 #
19552                 # there might be multiple MDTs on single mds server, so need to
19553                 # specifiy MDT0000. Or the command will fail due to other MDTs
19554                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19555                         error "cannot clear escaped jobid in job_stats";
19556         else
19557                 echo "MDS does not support clearing escaped jobid"
19558         fi
19559 }
19560 run_test 205b "Verify job stats jobid and output format"
19561
19562 # LU-13733
19563 test_205c() {
19564         $LCTL set_param llite.*.stats=0
19565         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19566         $LCTL get_param llite.*.stats
19567         $LCTL get_param llite.*.stats | grep \
19568                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19569                         error "wrong client stats format found"
19570 }
19571 run_test 205c "Verify client stats format"
19572
19573 test_205d() {
19574         local file=$DIR/$tdir/$tfile
19575
19576         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19577                 skip "need lustre >= 2.15.53 for lljobstat"
19578         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19579                 skip "need lustre >= 2.15.53 for lljobstat"
19580         verify_yaml_available || skip_env "YAML verification not installed"
19581
19582         test_mkdir -i 0 $DIR/$tdir
19583         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19584
19585         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19586                 error "failed to write data to $file"
19587         mv $file $file.2
19588
19589         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19590         echo -n 'verify rename_stats...'
19591         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19592                 verify_yaml || error "rename_stats is not valid YAML"
19593         echo " OK"
19594
19595         echo -n 'verify mdt job_stats...'
19596         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19597                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19598         echo " OK"
19599
19600         echo -n 'verify ost job_stats...'
19601         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19602                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19603         echo " OK"
19604 }
19605 run_test 205d "verify the format of some stats files"
19606
19607 test_205e() {
19608         local ops_comma
19609         local file=$DIR/$tdir/$tfile
19610         local -a cli_params
19611
19612         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19613                 skip "need lustre >= 2.15.53 for lljobstat"
19614         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19615                 skip "need lustre >= 2.15.53 for lljobstat"
19616         verify_yaml_available || skip_env "YAML verification not installed"
19617
19618         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19619         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19620         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19621
19622         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19623
19624         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19625                 error "failed to create $file on ost1"
19626         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19627                 error "failed to write data to $file"
19628
19629         do_facet mds1 "$LCTL get_param *.*.job_stats"
19630         do_facet ost1 "$LCTL get_param *.*.job_stats"
19631
19632         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19633         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19634                 error "The output of lljobstat is not an valid YAML"
19635
19636         # verify that job dd.0 does exist and has some ops on ost1
19637         # typically this line is like:
19638         # - 205e.dd.0:            {ops: 20, ...}
19639         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19640                     awk '$2=="205e.dd.0:" {print $4}')
19641
19642         (( ${ops_comma%,} >= 10 )) ||
19643                 error "cannot find job 205e.dd.0 with ops >= 10"
19644 }
19645 run_test 205e "verify the output of lljobstat"
19646
19647 test_205f() {
19648         verify_yaml_available || skip_env "YAML verification not installed"
19649
19650         # check both qos_ost_weights and qos_mdt_weights
19651         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19652         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19653                 error "qos_ost_weights is not valid YAML"
19654 }
19655 run_test 205f "verify qos_ost_weights YAML format "
19656
19657 __test_205_jobstats_dump() {
19658         local -a pids
19659         local nbr_instance=$1
19660
19661         while true; do
19662                 if (( ${#pids[@]} >= nbr_instance )); then
19663                         wait ${pids[@]}
19664                         pids=()
19665                 fi
19666
19667                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19668                 pids+=( $! )
19669         done
19670 }
19671
19672 __test_205_cleanup() {
19673         kill $@
19674         # Clear all job entries
19675         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19676 }
19677
19678 test_205g() {
19679         local -a mds1_params
19680         local -a cli_params
19681         local pids
19682         local interval=5
19683
19684         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19685         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19686         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19687
19688         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19689         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19690         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19691
19692         # start jobs loop
19693         export TEST205G_ID=205g
19694         stack_trap "unset TEST205G_ID" EXIT
19695         while true; do
19696                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19697         done & pids="$! "
19698
19699         __test_205_jobstats_dump 4 & pids+="$! "
19700         stack_trap "__test_205_cleanup $pids" EXIT INT
19701
19702         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19703 }
19704 run_test 205g "stress test for job_stats procfile"
19705
19706 # LU-1480, LU-1773 and LU-1657
19707 test_206() {
19708         mkdir -p $DIR/$tdir
19709         $LFS setstripe -c -1 $DIR/$tdir
19710 #define OBD_FAIL_LOV_INIT 0x1403
19711         $LCTL set_param fail_loc=0xa0001403
19712         $LCTL set_param fail_val=1
19713         touch $DIR/$tdir/$tfile || true
19714 }
19715 run_test 206 "fail lov_init_raid0() doesn't lbug"
19716
19717 test_207a() {
19718         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19719         local fsz=`stat -c %s $DIR/$tfile`
19720         cancel_lru_locks mdc
19721
19722         # do not return layout in getattr intent
19723 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19724         $LCTL set_param fail_loc=0x170
19725         local sz=`stat -c %s $DIR/$tfile`
19726
19727         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19728
19729         rm -rf $DIR/$tfile
19730 }
19731 run_test 207a "can refresh layout at glimpse"
19732
19733 test_207b() {
19734         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19735         local cksum=`md5sum $DIR/$tfile`
19736         local fsz=`stat -c %s $DIR/$tfile`
19737         cancel_lru_locks mdc
19738         cancel_lru_locks osc
19739
19740         # do not return layout in getattr intent
19741 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19742         $LCTL set_param fail_loc=0x171
19743
19744         # it will refresh layout after the file is opened but before read issues
19745         echo checksum is "$cksum"
19746         echo "$cksum" |md5sum -c --quiet || error "file differs"
19747
19748         rm -rf $DIR/$tfile
19749 }
19750 run_test 207b "can refresh layout at open"
19751
19752 test_208() {
19753         # FIXME: in this test suite, only RD lease is used. This is okay
19754         # for now as only exclusive open is supported. After generic lease
19755         # is done, this test suite should be revised. - Jinshan
19756
19757         remote_mds_nodsh && skip "remote MDS with nodsh"
19758         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19759                 skip "Need MDS version at least 2.4.52"
19760
19761         echo "==== test 1: verify get lease work"
19762         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19763
19764         echo "==== test 2: verify lease can be broken by upcoming open"
19765         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19766         local PID=$!
19767         sleep 2
19768
19769         $MULTIOP $DIR/$tfile oO_RDWR:c
19770         kill -USR1 $PID && wait $PID || error "break lease error"
19771
19772         echo "==== test 3: verify lease can't be granted if an open already exists"
19773         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19774         local PID=$!
19775         sleep 2
19776
19777         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19778         kill -USR1 $PID && wait $PID || error "open file error"
19779
19780         echo "==== test 4: lease can sustain over recovery"
19781         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19782         PID=$!
19783         sleep 2
19784
19785         fail mds1
19786
19787         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19788
19789         echo "==== test 5: lease broken can't be regained by replay"
19790         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19791         PID=$!
19792         sleep 2
19793
19794         # open file to break lease and then recovery
19795         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19796         fail mds1
19797
19798         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19799
19800         rm -f $DIR/$tfile
19801 }
19802 run_test 208 "Exclusive open"
19803
19804 test_209() {
19805         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19806                 skip_env "must have disp_stripe"
19807
19808         touch $DIR/$tfile
19809         sync; sleep 5; sync;
19810
19811         echo 3 > /proc/sys/vm/drop_caches
19812         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19813                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19814         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19815
19816         # open/close 500 times
19817         for i in $(seq 500); do
19818                 cat $DIR/$tfile
19819         done
19820
19821         echo 3 > /proc/sys/vm/drop_caches
19822         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19823                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19824         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19825
19826         echo "before: $req_before, after: $req_after"
19827         [ $((req_after - req_before)) -ge 300 ] &&
19828                 error "open/close requests are not freed"
19829         return 0
19830 }
19831 run_test 209 "read-only open/close requests should be freed promptly"
19832
19833 test_210() {
19834         local pid
19835
19836         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19837         pid=$!
19838         sleep 1
19839
19840         $LFS getstripe $DIR/$tfile
19841         kill -USR1 $pid
19842         wait $pid || error "multiop failed"
19843
19844         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19845         pid=$!
19846         sleep 1
19847
19848         $LFS getstripe $DIR/$tfile
19849         kill -USR1 $pid
19850         wait $pid || error "multiop failed"
19851 }
19852 run_test 210 "lfs getstripe does not break leases"
19853
19854 test_212() {
19855         size=`date +%s`
19856         size=$((size % 8192 + 1))
19857         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19858         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19859         rm -f $DIR/f212 $DIR/f212.xyz
19860 }
19861 run_test 212 "Sendfile test ============================================"
19862
19863 test_213() {
19864         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19865         cancel_lru_locks osc
19866         lctl set_param fail_loc=0x8000040f
19867         # generate a read lock
19868         cat $DIR/$tfile > /dev/null
19869         # write to the file, it will try to cancel the above read lock.
19870         cat /etc/hosts >> $DIR/$tfile
19871 }
19872 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19873
19874 test_214() { # for bug 20133
19875         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19876         for (( i=0; i < 340; i++ )) ; do
19877                 touch $DIR/$tdir/d214c/a$i
19878         done
19879
19880         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19881         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19882         ls $DIR/d214c || error "ls $DIR/d214c failed"
19883         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19884         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19885 }
19886 run_test 214 "hash-indexed directory test - bug 20133"
19887
19888 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19889 create_lnet_proc_files() {
19890         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19891 }
19892
19893 # counterpart of create_lnet_proc_files
19894 remove_lnet_proc_files() {
19895         rm -f $TMP/lnet_$1.sys
19896 }
19897
19898 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19899 # 3rd arg as regexp for body
19900 check_lnet_proc_stats() {
19901         local l=$(cat "$TMP/lnet_$1" |wc -l)
19902         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19903
19904         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19905 }
19906
19907 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19908 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19909 # optional and can be regexp for 2nd line (lnet.routes case)
19910 check_lnet_proc_entry() {
19911         local blp=2          # blp stands for 'position of 1st line of body'
19912         [ -z "$5" ] || blp=3 # lnet.routes case
19913
19914         local l=$(cat "$TMP/lnet_$1" |wc -l)
19915         # subtracting one from $blp because the body can be empty
19916         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19917
19918         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19919                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19920
19921         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19922                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19923
19924         # bail out if any unexpected line happened
19925         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19926         [ "$?" != 0 ] || error "$2 misformatted"
19927 }
19928
19929 test_215() { # for bugs 18102, 21079, 21517
19930         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19931
19932         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19933         local P='[1-9][0-9]*'           # positive numeric
19934         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19935         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19936         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19937         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19938
19939         local L1 # regexp for 1st line
19940         local L2 # regexp for 2nd line (optional)
19941         local BR # regexp for the rest (body)
19942
19943         # lnet.stats should look as 11 space-separated non-negative numerics
19944         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19945         create_lnet_proc_files "stats"
19946         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19947         remove_lnet_proc_files "stats"
19948
19949         # lnet.routes should look like this:
19950         # Routing disabled/enabled
19951         # net hops priority state router
19952         # where net is a string like tcp0, hops > 0, priority >= 0,
19953         # state is up/down,
19954         # router is a string like 192.168.1.1@tcp2
19955         L1="^Routing (disabled|enabled)$"
19956         L2="^net +hops +priority +state +router$"
19957         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19958         create_lnet_proc_files "routes"
19959         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19960         remove_lnet_proc_files "routes"
19961
19962         # lnet.routers should look like this:
19963         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19964         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19965         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19966         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19967         L1="^ref +rtr_ref +alive +router$"
19968         BR="^$P +$P +(up|down) +$NID$"
19969         create_lnet_proc_files "routers"
19970         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19971         remove_lnet_proc_files "routers"
19972
19973         # lnet.peers should look like this:
19974         # nid refs state last max rtr min tx min queue
19975         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19976         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19977         # numeric (0 or >0 or <0), queue >= 0.
19978         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19979         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19980         create_lnet_proc_files "peers"
19981         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19982         remove_lnet_proc_files "peers"
19983
19984         # lnet.buffers  should look like this:
19985         # pages count credits min
19986         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19987         L1="^pages +count +credits +min$"
19988         BR="^ +$N +$N +$I +$I$"
19989         create_lnet_proc_files "buffers"
19990         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19991         remove_lnet_proc_files "buffers"
19992
19993         # lnet.nis should look like this:
19994         # nid status alive refs peer rtr max tx min
19995         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19996         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
19997         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
19998         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
19999         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20000         create_lnet_proc_files "nis"
20001         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20002         remove_lnet_proc_files "nis"
20003
20004         # can we successfully write to lnet.stats?
20005         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20006 }
20007 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20008
20009 test_216() { # bug 20317
20010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20011         remote_ost_nodsh && skip "remote OST with nodsh"
20012
20013         local node
20014         local facets=$(get_facets OST)
20015         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20016
20017         save_lustre_params client "osc.*.contention_seconds" > $p
20018         save_lustre_params $facets \
20019                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20020         save_lustre_params $facets \
20021                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20022         save_lustre_params $facets \
20023                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20024         clear_stats osc.*.osc_stats
20025
20026         # agressive lockless i/o settings
20027         do_nodes $(comma_list $(osts_nodes)) \
20028                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20029                         ldlm.namespaces.filter-*.contended_locks=0 \
20030                         ldlm.namespaces.filter-*.contention_seconds=60"
20031         lctl set_param -n osc.*.contention_seconds=60
20032
20033         $DIRECTIO write $DIR/$tfile 0 10 4096
20034         $CHECKSTAT -s 40960 $DIR/$tfile
20035
20036         # disable lockless i/o
20037         do_nodes $(comma_list $(osts_nodes)) \
20038                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20039                         ldlm.namespaces.filter-*.contended_locks=32 \
20040                         ldlm.namespaces.filter-*.contention_seconds=0"
20041         lctl set_param -n osc.*.contention_seconds=0
20042         clear_stats osc.*.osc_stats
20043
20044         dd if=/dev/zero of=$DIR/$tfile count=0
20045         $CHECKSTAT -s 0 $DIR/$tfile
20046
20047         restore_lustre_params <$p
20048         rm -f $p
20049         rm $DIR/$tfile
20050 }
20051 run_test 216 "check lockless direct write updates file size and kms correctly"
20052
20053 test_217() { # bug 22430
20054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20055
20056         local node
20057         local nid
20058
20059         for node in $(nodes_list); do
20060                 nid=$(host_nids_address $node $NETTYPE)
20061                 if [[ $nid = *-* ]] ; then
20062                         echo "lctl ping $(h2nettype $nid)"
20063                         lctl ping $(h2nettype $nid)
20064                 else
20065                         echo "skipping $node (no hyphen detected)"
20066                 fi
20067         done
20068 }
20069 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
20070
20071 test_218() {
20072        # do directio so as not to populate the page cache
20073        log "creating a 10 Mb file"
20074        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
20075        log "starting reads"
20076        dd if=$DIR/$tfile of=/dev/null bs=4096 &
20077        log "truncating the file"
20078        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
20079        log "killing dd"
20080        kill %+ || true # reads might have finished
20081        echo "wait until dd is finished"
20082        wait
20083        log "removing the temporary file"
20084        rm -rf $DIR/$tfile || error "tmp file removal failed"
20085 }
20086 run_test 218 "parallel read and truncate should not deadlock"
20087
20088 test_219() {
20089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20090
20091         # write one partial page
20092         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20093         # set no grant so vvp_io_commit_write will do sync write
20094         $LCTL set_param fail_loc=0x411
20095         # write a full page at the end of file
20096         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20097
20098         $LCTL set_param fail_loc=0
20099         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20100         $LCTL set_param fail_loc=0x411
20101         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20102
20103         # LU-4201
20104         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20105         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20106 }
20107 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20108
20109 test_220() { #LU-325
20110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20111         remote_ost_nodsh && skip "remote OST with nodsh"
20112         remote_mds_nodsh && skip "remote MDS with nodsh"
20113         remote_mgs_nodsh && skip "remote MGS with nodsh"
20114
20115         local OSTIDX=0
20116
20117         # create on MDT0000 so the last_id and next_id are correct
20118         mkdir_on_mdt0 $DIR/$tdir
20119         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20120         OST=${OST%_UUID}
20121
20122         # on the mdt's osc
20123         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20124         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20125                         osp.$mdtosc_proc1.prealloc_last_id)
20126         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20127                         osp.$mdtosc_proc1.prealloc_next_id)
20128
20129         $LFS df -i
20130
20131         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20132         #define OBD_FAIL_OST_ENOINO              0x229
20133         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20134         create_pool $FSNAME.$TESTNAME || return 1
20135         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20136
20137         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20138
20139         MDSOBJS=$((last_id - next_id))
20140         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20141
20142         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20143         echo "OST still has $count kbytes free"
20144
20145         echo "create $MDSOBJS files @next_id..."
20146         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20147
20148         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20149                         osp.$mdtosc_proc1.prealloc_last_id)
20150         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20151                         osp.$mdtosc_proc1.prealloc_next_id)
20152
20153         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20154         $LFS df -i
20155
20156         echo "cleanup..."
20157
20158         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20159         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20160
20161         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20162                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20163         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20164                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20165         echo "unlink $MDSOBJS files @$next_id..."
20166         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20167 }
20168 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20169
20170 test_221() {
20171         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20172
20173         dd if=`which date` of=$MOUNT/date oflag=sync
20174         chmod +x $MOUNT/date
20175
20176         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20177         $LCTL set_param fail_loc=0x80001401
20178
20179         $MOUNT/date > /dev/null
20180         rm -f $MOUNT/date
20181 }
20182 run_test 221 "make sure fault and truncate race to not cause OOM"
20183
20184 test_222a () {
20185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20186
20187         rm -rf $DIR/$tdir
20188         test_mkdir $DIR/$tdir
20189         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20190         createmany -o $DIR/$tdir/$tfile 10
20191         cancel_lru_locks mdc
20192         cancel_lru_locks osc
20193         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20194         $LCTL set_param fail_loc=0x31a
20195         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20196         $LCTL set_param fail_loc=0
20197         rm -r $DIR/$tdir
20198 }
20199 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20200
20201 test_222b () {
20202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20203
20204         rm -rf $DIR/$tdir
20205         test_mkdir $DIR/$tdir
20206         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20207         createmany -o $DIR/$tdir/$tfile 10
20208         cancel_lru_locks mdc
20209         cancel_lru_locks osc
20210         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20211         $LCTL set_param fail_loc=0x31a
20212         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20213         $LCTL set_param fail_loc=0
20214 }
20215 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20216
20217 test_223 () {
20218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20219
20220         rm -rf $DIR/$tdir
20221         test_mkdir $DIR/$tdir
20222         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20223         createmany -o $DIR/$tdir/$tfile 10
20224         cancel_lru_locks mdc
20225         cancel_lru_locks osc
20226         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20227         $LCTL set_param fail_loc=0x31b
20228         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20229         $LCTL set_param fail_loc=0
20230         rm -r $DIR/$tdir
20231 }
20232 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20233
20234 test_224a() { # LU-1039, MRP-303
20235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20236         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20237         $LCTL set_param fail_loc=0x508
20238         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20239         $LCTL set_param fail_loc=0
20240         df $DIR
20241 }
20242 run_test 224a "Don't panic on bulk IO failure"
20243
20244 test_224bd_sub() { # LU-1039, MRP-303
20245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20246         local timeout=$1
20247
20248         shift
20249         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20250
20251         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20252
20253         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20254         cancel_lru_locks osc
20255         set_checksums 0
20256         stack_trap "set_checksums $ORIG_CSUM" EXIT
20257         local at_max_saved=0
20258
20259         # adaptive timeouts may prevent seeing the issue
20260         if at_is_enabled; then
20261                 at_max_saved=$(at_max_get mds)
20262                 at_max_set 0 mds client
20263                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20264         fi
20265
20266         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20267         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20268         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20269
20270         do_facet ost1 $LCTL set_param fail_loc=0
20271         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20272         df $DIR
20273 }
20274
20275 test_224b() {
20276         test_224bd_sub 3 error "dd failed"
20277 }
20278 run_test 224b "Don't panic on bulk IO failure"
20279
20280 test_224c() { # LU-6441
20281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20282         remote_mds_nodsh && skip "remote MDS with nodsh"
20283
20284         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20285         save_writethrough $p
20286         set_cache writethrough on
20287
20288         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20289         local at_max=$($LCTL get_param -n at_max)
20290         local timeout=$($LCTL get_param -n timeout)
20291         local test_at="at_max"
20292         local param_at="$FSNAME.sys.at_max"
20293         local test_timeout="timeout"
20294         local param_timeout="$FSNAME.sys.timeout"
20295
20296         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20297
20298         set_persistent_param_and_check client "$test_at" "$param_at" 0
20299         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20300
20301         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20302         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20303         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20304         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20305         sync
20306         do_facet ost1 "$LCTL set_param fail_loc=0"
20307
20308         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20309         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20310                 $timeout
20311
20312         $LCTL set_param -n $pages_per_rpc
20313         restore_lustre_params < $p
20314         rm -f $p
20315 }
20316 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20317
20318 test_224d() { # LU-11169
20319         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20320 }
20321 run_test 224d "Don't corrupt data on bulk IO timeout"
20322
20323 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20324 test_225a () {
20325         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20326         if [ -z ${MDSSURVEY} ]; then
20327                 skip_env "mds-survey not found"
20328         fi
20329         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20330                 skip "Need MDS version at least 2.2.51"
20331
20332         local mds=$(facet_host $SINGLEMDS)
20333         local target=$(do_nodes $mds 'lctl dl' |
20334                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20335
20336         local cmd1="file_count=1000 thrhi=4"
20337         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20338         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20339         local cmd="$cmd1 $cmd2 $cmd3"
20340
20341         rm -f ${TMP}/mds_survey*
20342         echo + $cmd
20343         eval $cmd || error "mds-survey with zero-stripe failed"
20344         cat ${TMP}/mds_survey*
20345         rm -f ${TMP}/mds_survey*
20346 }
20347 run_test 225a "Metadata survey sanity with zero-stripe"
20348
20349 test_225b () {
20350         if [ -z ${MDSSURVEY} ]; then
20351                 skip_env "mds-survey not found"
20352         fi
20353         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20354                 skip "Need MDS version at least 2.2.51"
20355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20356         remote_mds_nodsh && skip "remote MDS with nodsh"
20357         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20358                 skip_env "Need to mount OST to test"
20359         fi
20360
20361         local mds=$(facet_host $SINGLEMDS)
20362         local target=$(do_nodes $mds 'lctl dl' |
20363                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20364
20365         local cmd1="file_count=1000 thrhi=4"
20366         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20367         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20368         local cmd="$cmd1 $cmd2 $cmd3"
20369
20370         rm -f ${TMP}/mds_survey*
20371         echo + $cmd
20372         eval $cmd || error "mds-survey with stripe_count failed"
20373         cat ${TMP}/mds_survey*
20374         rm -f ${TMP}/mds_survey*
20375 }
20376 run_test 225b "Metadata survey sanity with stripe_count = 1"
20377
20378 mcreate_path2fid () {
20379         local mode=$1
20380         local major=$2
20381         local minor=$3
20382         local name=$4
20383         local desc=$5
20384         local path=$DIR/$tdir/$name
20385         local fid
20386         local rc
20387         local fid_path
20388
20389         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20390                 error "cannot create $desc"
20391
20392         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20393         rc=$?
20394         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20395
20396         fid_path=$($LFS fid2path $MOUNT $fid)
20397         rc=$?
20398         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20399
20400         [ "$path" == "$fid_path" ] ||
20401                 error "fid2path returned $fid_path, expected $path"
20402
20403         echo "pass with $path and $fid"
20404 }
20405
20406 test_226a () {
20407         rm -rf $DIR/$tdir
20408         mkdir -p $DIR/$tdir
20409
20410         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20411         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20412         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20413         mcreate_path2fid 0040666 0 0 dir "directory"
20414         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20415         mcreate_path2fid 0100666 0 0 file "regular file"
20416         mcreate_path2fid 0120666 0 0 link "symbolic link"
20417         mcreate_path2fid 0140666 0 0 sock "socket"
20418 }
20419 run_test 226a "call path2fid and fid2path on files of all type"
20420
20421 test_226b () {
20422         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20423
20424         local MDTIDX=1
20425
20426         rm -rf $DIR/$tdir
20427         mkdir -p $DIR/$tdir
20428         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20429                 error "create remote directory failed"
20430         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20431         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20432                                 "character special file (null)"
20433         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20434                                 "character special file (no device)"
20435         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20436         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20437                                 "block special file (loop)"
20438         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20439         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20440         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20441 }
20442 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20443
20444 test_226c () {
20445         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20446         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20447                 skip "Need MDS version at least 2.13.55"
20448
20449         local submnt=/mnt/submnt
20450         local srcfile=/etc/passwd
20451         local dstfile=$submnt/passwd
20452         local path
20453         local fid
20454
20455         rm -rf $DIR/$tdir
20456         rm -rf $submnt
20457         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20458                 error "create remote directory failed"
20459         mkdir -p $submnt || error "create $submnt failed"
20460         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20461                 error "mount $submnt failed"
20462         stack_trap "umount $submnt" EXIT
20463
20464         cp $srcfile $dstfile
20465         fid=$($LFS path2fid $dstfile)
20466         path=$($LFS fid2path $submnt "$fid")
20467         [ "$path" = "$dstfile" ] ||
20468                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20469 }
20470 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20471
20472 # LU-1299 Executing or running ldd on a truncated executable does not
20473 # cause an out-of-memory condition.
20474 test_227() {
20475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20476         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20477
20478         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20479         chmod +x $MOUNT/date
20480
20481         $MOUNT/date > /dev/null
20482         ldd $MOUNT/date > /dev/null
20483         rm -f $MOUNT/date
20484 }
20485 run_test 227 "running truncated executable does not cause OOM"
20486
20487 # LU-1512 try to reuse idle OI blocks
20488 test_228a() {
20489         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20490         remote_mds_nodsh && skip "remote MDS with nodsh"
20491         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20492
20493         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20494         local myDIR=$DIR/$tdir
20495
20496         mkdir -p $myDIR
20497         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20498         $LCTL set_param fail_loc=0x80001002
20499         createmany -o $myDIR/t- 10000
20500         $LCTL set_param fail_loc=0
20501         # The guard is current the largest FID holder
20502         touch $myDIR/guard
20503         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20504                     tr -d '[')
20505         local IDX=$(($SEQ % 64))
20506
20507         do_facet $SINGLEMDS sync
20508         # Make sure journal flushed.
20509         sleep 6
20510         local blk1=$(do_facet $SINGLEMDS \
20511                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20512                      grep Blockcount | awk '{print $4}')
20513
20514         # Remove old files, some OI blocks will become idle.
20515         unlinkmany $myDIR/t- 10000
20516         # Create new files, idle OI blocks should be reused.
20517         createmany -o $myDIR/t- 2000
20518         do_facet $SINGLEMDS sync
20519         # Make sure journal flushed.
20520         sleep 6
20521         local blk2=$(do_facet $SINGLEMDS \
20522                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20523                      grep Blockcount | awk '{print $4}')
20524
20525         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20526 }
20527 run_test 228a "try to reuse idle OI blocks"
20528
20529 test_228b() {
20530         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20531         remote_mds_nodsh && skip "remote MDS with nodsh"
20532         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20533
20534         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20535         local myDIR=$DIR/$tdir
20536
20537         mkdir -p $myDIR
20538         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20539         $LCTL set_param fail_loc=0x80001002
20540         createmany -o $myDIR/t- 10000
20541         $LCTL set_param fail_loc=0
20542         # The guard is current the largest FID holder
20543         touch $myDIR/guard
20544         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20545                     tr -d '[')
20546         local IDX=$(($SEQ % 64))
20547
20548         do_facet $SINGLEMDS sync
20549         # Make sure journal flushed.
20550         sleep 6
20551         local blk1=$(do_facet $SINGLEMDS \
20552                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20553                      grep Blockcount | awk '{print $4}')
20554
20555         # Remove old files, some OI blocks will become idle.
20556         unlinkmany $myDIR/t- 10000
20557
20558         # stop the MDT
20559         stop $SINGLEMDS || error "Fail to stop MDT."
20560         # remount the MDT
20561         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20562                 error "Fail to start MDT."
20563
20564         client_up || error "Fail to df."
20565         # Create new files, idle OI blocks should be reused.
20566         createmany -o $myDIR/t- 2000
20567         do_facet $SINGLEMDS sync
20568         # Make sure journal flushed.
20569         sleep 6
20570         local blk2=$(do_facet $SINGLEMDS \
20571                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20572                      grep Blockcount | awk '{print $4}')
20573
20574         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20575 }
20576 run_test 228b "idle OI blocks can be reused after MDT restart"
20577
20578 #LU-1881
20579 test_228c() {
20580         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20581         remote_mds_nodsh && skip "remote MDS with nodsh"
20582         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20583
20584         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20585         local myDIR=$DIR/$tdir
20586
20587         mkdir -p $myDIR
20588         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20589         $LCTL set_param fail_loc=0x80001002
20590         # 20000 files can guarantee there are index nodes in the OI file
20591         createmany -o $myDIR/t- 20000
20592         $LCTL set_param fail_loc=0
20593         # The guard is current the largest FID holder
20594         touch $myDIR/guard
20595         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20596                     tr -d '[')
20597         local IDX=$(($SEQ % 64))
20598
20599         do_facet $SINGLEMDS sync
20600         # Make sure journal flushed.
20601         sleep 6
20602         local blk1=$(do_facet $SINGLEMDS \
20603                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20604                      grep Blockcount | awk '{print $4}')
20605
20606         # Remove old files, some OI blocks will become idle.
20607         unlinkmany $myDIR/t- 20000
20608         rm -f $myDIR/guard
20609         # The OI file should become empty now
20610
20611         # Create new files, idle OI blocks should be reused.
20612         createmany -o $myDIR/t- 2000
20613         do_facet $SINGLEMDS sync
20614         # Make sure journal flushed.
20615         sleep 6
20616         local blk2=$(do_facet $SINGLEMDS \
20617                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20618                      grep Blockcount | awk '{print $4}')
20619
20620         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20621 }
20622 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20623
20624 test_229() { # LU-2482, LU-3448
20625         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20626         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20627         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20628                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20629
20630         rm -f $DIR/$tfile
20631
20632         # Create a file with a released layout and stripe count 2.
20633         $MULTIOP $DIR/$tfile H2c ||
20634                 error "failed to create file with released layout"
20635
20636         $LFS getstripe -v $DIR/$tfile
20637
20638         local pattern=$($LFS getstripe -L $DIR/$tfile)
20639         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20640
20641         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20642                 error "getstripe"
20643         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20644         stat $DIR/$tfile || error "failed to stat released file"
20645
20646         chown $RUNAS_ID $DIR/$tfile ||
20647                 error "chown $RUNAS_ID $DIR/$tfile failed"
20648
20649         chgrp $RUNAS_ID $DIR/$tfile ||
20650                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20651
20652         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20653         rm $DIR/$tfile || error "failed to remove released file"
20654 }
20655 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20656
20657 test_230a() {
20658         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20659         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20660         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20661                 skip "Need MDS version at least 2.11.52"
20662
20663         local MDTIDX=1
20664
20665         test_mkdir $DIR/$tdir
20666         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20667         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20668         [ $mdt_idx -ne 0 ] &&
20669                 error "create local directory on wrong MDT $mdt_idx"
20670
20671         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20672                         error "create remote directory failed"
20673         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20674         [ $mdt_idx -ne $MDTIDX ] &&
20675                 error "create remote directory on wrong MDT $mdt_idx"
20676
20677         createmany -o $DIR/$tdir/test_230/t- 10 ||
20678                 error "create files on remote directory failed"
20679         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20680         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20681         rm -r $DIR/$tdir || error "unlink remote directory failed"
20682 }
20683 run_test 230a "Create remote directory and files under the remote directory"
20684
20685 test_230b() {
20686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20687         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20688         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20689                 skip "Need MDS version at least 2.11.52"
20690
20691         local MDTIDX=1
20692         local mdt_index
20693         local i
20694         local file
20695         local pid
20696         local stripe_count
20697         local migrate_dir=$DIR/$tdir/migrate_dir
20698         local other_dir=$DIR/$tdir/other_dir
20699
20700         test_mkdir $DIR/$tdir
20701         test_mkdir -i0 -c1 $migrate_dir
20702         test_mkdir -i0 -c1 $other_dir
20703         for ((i=0; i<10; i++)); do
20704                 mkdir -p $migrate_dir/dir_${i}
20705                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20706                         error "create files under remote dir failed $i"
20707         done
20708
20709         cp /etc/passwd $migrate_dir/$tfile
20710         cp /etc/passwd $other_dir/$tfile
20711         chattr +SAD $migrate_dir
20712         chattr +SAD $migrate_dir/$tfile
20713
20714         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20715         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20716         local old_dir_mode=$(stat -c%f $migrate_dir)
20717         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20718
20719         mkdir -p $migrate_dir/dir_default_stripe2
20720         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20721         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20722
20723         mkdir -p $other_dir
20724         ln $migrate_dir/$tfile $other_dir/luna
20725         ln $migrate_dir/$tfile $migrate_dir/sofia
20726         ln $other_dir/$tfile $migrate_dir/david
20727         ln -s $migrate_dir/$tfile $other_dir/zachary
20728         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20729         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20730
20731         local len
20732         local lnktgt
20733
20734         # inline symlink
20735         for len in 58 59 60; do
20736                 lnktgt=$(str_repeat 'l' $len)
20737                 touch $migrate_dir/$lnktgt
20738                 ln -s $lnktgt $migrate_dir/${len}char_ln
20739         done
20740
20741         # PATH_MAX
20742         for len in 4094 4095; do
20743                 lnktgt=$(str_repeat 'l' $len)
20744                 ln -s $lnktgt $migrate_dir/${len}char_ln
20745         done
20746
20747         # NAME_MAX
20748         for len in 254 255; do
20749                 touch $migrate_dir/$(str_repeat 'l' $len)
20750         done
20751
20752         $LFS migrate -m $MDTIDX $migrate_dir ||
20753                 error "fails on migrating remote dir to MDT1"
20754
20755         echo "migratate to MDT1, then checking.."
20756         for ((i = 0; i < 10; i++)); do
20757                 for file in $(find $migrate_dir/dir_${i}); do
20758                         mdt_index=$($LFS getstripe -m $file)
20759                         # broken symlink getstripe will fail
20760                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20761                                 error "$file is not on MDT${MDTIDX}"
20762                 done
20763         done
20764
20765         # the multiple link file should still in MDT0
20766         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20767         [ $mdt_index == 0 ] ||
20768                 error "$file is not on MDT${MDTIDX}"
20769
20770         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20771         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20772                 error " expect $old_dir_flag get $new_dir_flag"
20773
20774         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20775         [ "$old_file_flag" = "$new_file_flag" ] ||
20776                 error " expect $old_file_flag get $new_file_flag"
20777
20778         local new_dir_mode=$(stat -c%f $migrate_dir)
20779         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20780                 error "expect mode $old_dir_mode get $new_dir_mode"
20781
20782         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20783         [ "$old_file_mode" = "$new_file_mode" ] ||
20784                 error "expect mode $old_file_mode get $new_file_mode"
20785
20786         diff /etc/passwd $migrate_dir/$tfile ||
20787                 error "$tfile different after migration"
20788
20789         diff /etc/passwd $other_dir/luna ||
20790                 error "luna different after migration"
20791
20792         diff /etc/passwd $migrate_dir/sofia ||
20793                 error "sofia different after migration"
20794
20795         diff /etc/passwd $migrate_dir/david ||
20796                 error "david different after migration"
20797
20798         diff /etc/passwd $other_dir/zachary ||
20799                 error "zachary different after migration"
20800
20801         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20802                 error "${tfile}_ln different after migration"
20803
20804         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20805                 error "${tfile}_ln_other different after migration"
20806
20807         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20808         [ $stripe_count = 2 ] ||
20809                 error "dir strpe_count $d != 2 after migration."
20810
20811         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20812         [ $stripe_count = 2 ] ||
20813                 error "file strpe_count $d != 2 after migration."
20814
20815         #migrate back to MDT0
20816         MDTIDX=0
20817
20818         $LFS migrate -m $MDTIDX $migrate_dir ||
20819                 error "fails on migrating remote dir to MDT0"
20820
20821         echo "migrate back to MDT0, checking.."
20822         for file in $(find $migrate_dir); do
20823                 mdt_index=$($LFS getstripe -m $file)
20824                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20825                         error "$file is not on MDT${MDTIDX}"
20826         done
20827
20828         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20829         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20830                 error " expect $old_dir_flag get $new_dir_flag"
20831
20832         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20833         [ "$old_file_flag" = "$new_file_flag" ] ||
20834                 error " expect $old_file_flag get $new_file_flag"
20835
20836         local new_dir_mode=$(stat -c%f $migrate_dir)
20837         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20838                 error "expect mode $old_dir_mode get $new_dir_mode"
20839
20840         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20841         [ "$old_file_mode" = "$new_file_mode" ] ||
20842                 error "expect mode $old_file_mode get $new_file_mode"
20843
20844         diff /etc/passwd ${migrate_dir}/$tfile ||
20845                 error "$tfile different after migration"
20846
20847         diff /etc/passwd ${other_dir}/luna ||
20848                 error "luna different after migration"
20849
20850         diff /etc/passwd ${migrate_dir}/sofia ||
20851                 error "sofia different after migration"
20852
20853         diff /etc/passwd ${other_dir}/zachary ||
20854                 error "zachary different after migration"
20855
20856         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20857                 error "${tfile}_ln different after migration"
20858
20859         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20860                 error "${tfile}_ln_other different after migration"
20861
20862         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20863         [ $stripe_count = 2 ] ||
20864                 error "dir strpe_count $d != 2 after migration."
20865
20866         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20867         [ $stripe_count = 2 ] ||
20868                 error "file strpe_count $d != 2 after migration."
20869
20870         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20871 }
20872 run_test 230b "migrate directory"
20873
20874 test_230c() {
20875         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20876         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20877         remote_mds_nodsh && skip "remote MDS with nodsh"
20878         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20879                 skip "Need MDS version at least 2.11.52"
20880
20881         local MDTIDX=1
20882         local total=3
20883         local mdt_index
20884         local file
20885         local migrate_dir=$DIR/$tdir/migrate_dir
20886
20887         #If migrating directory fails in the middle, all entries of
20888         #the directory is still accessiable.
20889         test_mkdir $DIR/$tdir
20890         test_mkdir -i0 -c1 $migrate_dir
20891         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20892         stat $migrate_dir
20893         createmany -o $migrate_dir/f $total ||
20894                 error "create files under ${migrate_dir} failed"
20895
20896         # fail after migrating top dir, and this will fail only once, so the
20897         # first sub file migration will fail (currently f3), others succeed.
20898         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20899         do_facet mds1 lctl set_param fail_loc=0x1801
20900         local t=$(ls $migrate_dir | wc -l)
20901         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20902                 error "migrate should fail"
20903         local u=$(ls $migrate_dir | wc -l)
20904         [ "$u" == "$t" ] || error "$u != $t during migration"
20905
20906         # add new dir/file should succeed
20907         mkdir $migrate_dir/dir ||
20908                 error "mkdir failed under migrating directory"
20909         touch $migrate_dir/file ||
20910                 error "create file failed under migrating directory"
20911
20912         # add file with existing name should fail
20913         for file in $migrate_dir/f*; do
20914                 stat $file > /dev/null || error "stat $file failed"
20915                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20916                         error "open(O_CREAT|O_EXCL) $file should fail"
20917                 $MULTIOP $file m && error "create $file should fail"
20918                 touch $DIR/$tdir/remote_dir/$tfile ||
20919                         error "touch $tfile failed"
20920                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20921                         error "link $file should fail"
20922                 mdt_index=$($LFS getstripe -m $file)
20923                 if [ $mdt_index == 0 ]; then
20924                         # file failed to migrate is not allowed to rename to
20925                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20926                                 error "rename to $file should fail"
20927                 else
20928                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20929                                 error "rename to $file failed"
20930                 fi
20931                 echo hello >> $file || error "write $file failed"
20932         done
20933
20934         # resume migration with different options should fail
20935         $LFS migrate -m 0 $migrate_dir &&
20936                 error "migrate -m 0 $migrate_dir should fail"
20937
20938         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20939                 error "migrate -c 2 $migrate_dir should fail"
20940
20941         # resume migration should succeed
20942         $LFS migrate -m $MDTIDX $migrate_dir ||
20943                 error "migrate $migrate_dir failed"
20944
20945         echo "Finish migration, then checking.."
20946         for file in $(find $migrate_dir); do
20947                 mdt_index=$($LFS getstripe -m $file)
20948                 [ $mdt_index == $MDTIDX ] ||
20949                         error "$file is not on MDT${MDTIDX}"
20950         done
20951
20952         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20953 }
20954 run_test 230c "check directory accessiblity if migration failed"
20955
20956 test_230d() {
20957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20959         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20960                 skip "Need MDS version at least 2.11.52"
20961         # LU-11235
20962         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20963
20964         local migrate_dir=$DIR/$tdir/migrate_dir
20965         local old_index
20966         local new_index
20967         local old_count
20968         local new_count
20969         local new_hash
20970         local mdt_index
20971         local i
20972         local j
20973
20974         old_index=$((RANDOM % MDSCOUNT))
20975         old_count=$((MDSCOUNT - old_index))
20976         new_index=$((RANDOM % MDSCOUNT))
20977         new_count=$((MDSCOUNT - new_index))
20978         new_hash=1 # for all_char
20979
20980         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20981         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20982
20983         test_mkdir $DIR/$tdir
20984         test_mkdir -i $old_index -c $old_count $migrate_dir
20985
20986         for ((i=0; i<100; i++)); do
20987                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20988                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20989                         error "create files under remote dir failed $i"
20990         done
20991
20992         echo -n "Migrate from MDT$old_index "
20993         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20994         echo -n "to MDT$new_index"
20995         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20996         echo
20997
20998         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
20999         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21000                 error "migrate remote dir error"
21001
21002         echo "Finish migration, then checking.."
21003         for file in $(find $migrate_dir -maxdepth 1); do
21004                 mdt_index=$($LFS getstripe -m $file)
21005                 if [ $mdt_index -lt $new_index ] ||
21006                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21007                         error "$file is on MDT$mdt_index"
21008                 fi
21009         done
21010
21011         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21012 }
21013 run_test 230d "check migrate big directory"
21014
21015 test_230e() {
21016         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21017         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21018         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21019                 skip "Need MDS version at least 2.11.52"
21020
21021         local i
21022         local j
21023         local a_fid
21024         local b_fid
21025
21026         mkdir_on_mdt0 $DIR/$tdir
21027         mkdir $DIR/$tdir/migrate_dir
21028         mkdir $DIR/$tdir/other_dir
21029         touch $DIR/$tdir/migrate_dir/a
21030         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21031         ls $DIR/$tdir/other_dir
21032
21033         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21034                 error "migrate dir fails"
21035
21036         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21037         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21038
21039         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21040         [ $mdt_index == 0 ] || error "a is not on MDT0"
21041
21042         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21043                 error "migrate dir fails"
21044
21045         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21046         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21047
21048         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21049         [ $mdt_index == 1 ] || error "a is not on MDT1"
21050
21051         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21052         [ $mdt_index == 1 ] || error "b is not on MDT1"
21053
21054         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21055         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21056
21057         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21058
21059         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21060 }
21061 run_test 230e "migrate mulitple local link files"
21062
21063 test_230f() {
21064         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21065         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21066         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21067                 skip "Need MDS version at least 2.11.52"
21068
21069         local a_fid
21070         local ln_fid
21071
21072         mkdir -p $DIR/$tdir
21073         mkdir $DIR/$tdir/migrate_dir
21074         $LFS mkdir -i1 $DIR/$tdir/other_dir
21075         touch $DIR/$tdir/migrate_dir/a
21076         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21077         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21078         ls $DIR/$tdir/other_dir
21079
21080         # a should be migrated to MDT1, since no other links on MDT0
21081         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21082                 error "#1 migrate dir fails"
21083         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21084         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21085         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21086         [ $mdt_index == 1 ] || error "a is not on MDT1"
21087
21088         # a should stay on MDT1, because it is a mulitple link file
21089         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21090                 error "#2 migrate dir fails"
21091         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21092         [ $mdt_index == 1 ] || error "a is not on MDT1"
21093
21094         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21095                 error "#3 migrate dir fails"
21096
21097         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21098         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21099         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21100
21101         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21102         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21103
21104         # a should be migrated to MDT0, since no other links on MDT1
21105         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21106                 error "#4 migrate dir fails"
21107         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21108         [ $mdt_index == 0 ] || error "a is not on MDT0"
21109
21110         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21111 }
21112 run_test 230f "migrate mulitple remote link files"
21113
21114 test_230g() {
21115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21116         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21117         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21118                 skip "Need MDS version at least 2.11.52"
21119
21120         mkdir -p $DIR/$tdir/migrate_dir
21121
21122         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21123                 error "migrating dir to non-exist MDT succeeds"
21124         true
21125 }
21126 run_test 230g "migrate dir to non-exist MDT"
21127
21128 test_230h() {
21129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21130         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21131         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21132                 skip "Need MDS version at least 2.11.52"
21133
21134         local mdt_index
21135
21136         mkdir -p $DIR/$tdir/migrate_dir
21137
21138         $LFS migrate -m1 $DIR &&
21139                 error "migrating mountpoint1 should fail"
21140
21141         $LFS migrate -m1 $DIR/$tdir/.. &&
21142                 error "migrating mountpoint2 should fail"
21143
21144         # same as mv
21145         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21146                 error "migrating $tdir/migrate_dir/.. should fail"
21147
21148         true
21149 }
21150 run_test 230h "migrate .. and root"
21151
21152 test_230i() {
21153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21154         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21155         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21156                 skip "Need MDS version at least 2.11.52"
21157
21158         mkdir -p $DIR/$tdir/migrate_dir
21159
21160         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21161                 error "migration fails with a tailing slash"
21162
21163         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21164                 error "migration fails with two tailing slashes"
21165 }
21166 run_test 230i "lfs migrate -m tolerates trailing slashes"
21167
21168 test_230j() {
21169         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21170         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21171                 skip "Need MDS version at least 2.11.52"
21172
21173         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21174         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21175                 error "create $tfile failed"
21176         cat /etc/passwd > $DIR/$tdir/$tfile
21177
21178         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21179
21180         cmp /etc/passwd $DIR/$tdir/$tfile ||
21181                 error "DoM file mismatch after migration"
21182 }
21183 run_test 230j "DoM file data not changed after dir migration"
21184
21185 test_230k() {
21186         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21187         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21188                 skip "Need MDS version at least 2.11.56"
21189
21190         local total=20
21191         local files_on_starting_mdt=0
21192
21193         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21194         $LFS getdirstripe $DIR/$tdir
21195         for i in $(seq $total); do
21196                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21197                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21198                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21199         done
21200
21201         echo "$files_on_starting_mdt files on MDT0"
21202
21203         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21204         $LFS getdirstripe $DIR/$tdir
21205
21206         files_on_starting_mdt=0
21207         for i in $(seq $total); do
21208                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21209                         error "file $tfile.$i mismatch after migration"
21210                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21211                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21212         done
21213
21214         echo "$files_on_starting_mdt files on MDT1 after migration"
21215         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21216
21217         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21218         $LFS getdirstripe $DIR/$tdir
21219
21220         files_on_starting_mdt=0
21221         for i in $(seq $total); do
21222                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21223                         error "file $tfile.$i mismatch after 2nd migration"
21224                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21225                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21226         done
21227
21228         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21229         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21230
21231         true
21232 }
21233 run_test 230k "file data not changed after dir migration"
21234
21235 test_230l() {
21236         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21237         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21238                 skip "Need MDS version at least 2.11.56"
21239
21240         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21241         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21242                 error "create files under remote dir failed $i"
21243         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21244 }
21245 run_test 230l "readdir between MDTs won't crash"
21246
21247 test_230m() {
21248         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21249         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21250                 skip "Need MDS version at least 2.11.56"
21251
21252         local MDTIDX=1
21253         local mig_dir=$DIR/$tdir/migrate_dir
21254         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21255         local shortstr="b"
21256         local val
21257
21258         echo "Creating files and dirs with xattrs"
21259         test_mkdir $DIR/$tdir
21260         test_mkdir -i0 -c1 $mig_dir
21261         mkdir $mig_dir/dir
21262         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21263                 error "cannot set xattr attr1 on dir"
21264         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21265                 error "cannot set xattr attr2 on dir"
21266         touch $mig_dir/dir/f0
21267         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21268                 error "cannot set xattr attr1 on file"
21269         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21270                 error "cannot set xattr attr2 on file"
21271         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21272         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21273         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21274         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21275         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21276         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21277         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21278         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21279         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21280
21281         echo "Migrating to MDT1"
21282         $LFS migrate -m $MDTIDX $mig_dir ||
21283                 error "fails on migrating dir to MDT1"
21284
21285         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21286         echo "Checking xattrs"
21287         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21288         [ "$val" = $longstr ] ||
21289                 error "expecting xattr1 $longstr on dir, found $val"
21290         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21291         [ "$val" = $shortstr ] ||
21292                 error "expecting xattr2 $shortstr on dir, found $val"
21293         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21294         [ "$val" = $longstr ] ||
21295                 error "expecting xattr1 $longstr on file, found $val"
21296         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21297         [ "$val" = $shortstr ] ||
21298                 error "expecting xattr2 $shortstr on file, found $val"
21299 }
21300 run_test 230m "xattrs not changed after dir migration"
21301
21302 test_230n() {
21303         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21304         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21305                 skip "Need MDS version at least 2.13.53"
21306
21307         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21308         cat /etc/hosts > $DIR/$tdir/$tfile
21309         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21310         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21311
21312         cmp /etc/hosts $DIR/$tdir/$tfile ||
21313                 error "File data mismatch after migration"
21314 }
21315 run_test 230n "Dir migration with mirrored file"
21316
21317 test_230o() {
21318         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21319         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21320                 skip "Need MDS version at least 2.13.52"
21321
21322         local mdts=$(comma_list $(mdts_nodes))
21323         local timeout=100
21324         local restripe_status
21325         local delta
21326         local i
21327
21328         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21329
21330         # in case "crush" hash type is not set
21331         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21332
21333         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21334                            mdt.*MDT0000.enable_dir_restripe)
21335         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21336         stack_trap "do_nodes $mdts $LCTL set_param \
21337                     mdt.*.enable_dir_restripe=$restripe_status"
21338
21339         mkdir $DIR/$tdir
21340         createmany -m $DIR/$tdir/f 100 ||
21341                 error "create files under remote dir failed $i"
21342         createmany -d $DIR/$tdir/d 100 ||
21343                 error "create dirs under remote dir failed $i"
21344
21345         for i in $(seq 2 $MDSCOUNT); do
21346                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21347                 $LFS setdirstripe -c $i $DIR/$tdir ||
21348                         error "split -c $i $tdir failed"
21349                 wait_update $HOSTNAME \
21350                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21351                         error "dir split not finished"
21352                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21353                         awk '/migrate/ {sum += $2} END { print sum }')
21354                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21355                 # delta is around total_files/stripe_count
21356                 (( $delta < 200 / (i - 1) + 4 )) ||
21357                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21358         done
21359 }
21360 run_test 230o "dir split"
21361
21362 test_230p() {
21363         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21364         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21365                 skip "Need MDS version at least 2.13.52"
21366
21367         local mdts=$(comma_list $(mdts_nodes))
21368         local timeout=100
21369         local restripe_status
21370         local delta
21371         local c
21372
21373         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21374
21375         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21376
21377         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21378                            mdt.*MDT0000.enable_dir_restripe)
21379         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21380         stack_trap "do_nodes $mdts $LCTL set_param \
21381                     mdt.*.enable_dir_restripe=$restripe_status"
21382
21383         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21384         createmany -m $DIR/$tdir/f 100 ||
21385                 error "create files under remote dir failed"
21386         createmany -d $DIR/$tdir/d 100 ||
21387                 error "create dirs under remote dir failed"
21388
21389         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21390                 local mdt_hash="crush"
21391
21392                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21393                 $LFS setdirstripe -c $c $DIR/$tdir ||
21394                         error "split -c $c $tdir failed"
21395                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21396                         mdt_hash="$mdt_hash,fixed"
21397                 elif [ $c -eq 1 ]; then
21398                         mdt_hash="none"
21399                 fi
21400                 wait_update $HOSTNAME \
21401                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21402                         error "dir merge not finished"
21403                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21404                         awk '/migrate/ {sum += $2} END { print sum }')
21405                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21406                 # delta is around total_files/stripe_count
21407                 (( delta < 200 / c + 4 )) ||
21408                         error "$delta files migrated >= $((200 / c + 4))"
21409         done
21410 }
21411 run_test 230p "dir merge"
21412
21413 test_230q() {
21414         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21415         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21416                 skip "Need MDS version at least 2.13.52"
21417
21418         local mdts=$(comma_list $(mdts_nodes))
21419         local saved_threshold=$(do_facet mds1 \
21420                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21421         local saved_delta=$(do_facet mds1 \
21422                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21423         local threshold=100
21424         local delta=2
21425         local total=0
21426         local stripe_count=0
21427         local stripe_index
21428         local nr_files
21429         local create
21430
21431         # test with fewer files on ZFS
21432         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21433
21434         stack_trap "do_nodes $mdts $LCTL set_param \
21435                     mdt.*.dir_split_count=$saved_threshold"
21436         stack_trap "do_nodes $mdts $LCTL set_param \
21437                     mdt.*.dir_split_delta=$saved_delta"
21438         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21439         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21440         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21441         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21442         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21443         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21444
21445         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21446         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21447
21448         create=$((threshold * 3 / 2))
21449         while [ $stripe_count -lt $MDSCOUNT ]; do
21450                 createmany -m $DIR/$tdir/f $total $create ||
21451                         error "create sub files failed"
21452                 stat $DIR/$tdir > /dev/null
21453                 total=$((total + create))
21454                 stripe_count=$((stripe_count + delta))
21455                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21456
21457                 wait_update $HOSTNAME \
21458                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21459                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21460
21461                 wait_update $HOSTNAME \
21462                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21463                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21464
21465                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21466                 echo "$nr_files/$total files on MDT$stripe_index after split"
21467                 # allow 10% margin of imbalance with crush hash
21468                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21469                         error "$nr_files files on MDT$stripe_index after split"
21470
21471                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21472                 [ $nr_files -eq $total ] ||
21473                         error "total sub files $nr_files != $total"
21474         done
21475
21476         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21477
21478         echo "fixed layout directory won't auto split"
21479         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21480         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21481                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21482         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21483                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21484 }
21485 run_test 230q "dir auto split"
21486
21487 test_230r() {
21488         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21489         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21490         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21491                 skip "Need MDS version at least 2.13.54"
21492
21493         # maximum amount of local locks:
21494         # parent striped dir - 2 locks
21495         # new stripe in parent to migrate to - 1 lock
21496         # source and target - 2 locks
21497         # Total 5 locks for regular file
21498         mkdir -p $DIR/$tdir
21499         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21500         touch $DIR/$tdir/dir1/eee
21501
21502         # create 4 hardlink for 4 more locks
21503         # Total: 9 locks > RS_MAX_LOCKS (8)
21504         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21505         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21506         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21507         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21508         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21509         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21510         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21511         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21512
21513         cancel_lru_locks mdc
21514
21515         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21516                 error "migrate dir fails"
21517
21518         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21519 }
21520 run_test 230r "migrate with too many local locks"
21521
21522 test_230s() {
21523         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21524                 skip "Need MDS version at least 2.14.52"
21525
21526         local mdts=$(comma_list $(mdts_nodes))
21527         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21528                                 mdt.*MDT0000.enable_dir_restripe)
21529
21530         stack_trap "do_nodes $mdts $LCTL set_param \
21531                     mdt.*.enable_dir_restripe=$restripe_status"
21532
21533         local st
21534         for st in 0 1; do
21535                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21536                 test_mkdir $DIR/$tdir
21537                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21538                         error "$LFS mkdir should return EEXIST if target exists"
21539                 rmdir $DIR/$tdir
21540         done
21541 }
21542 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21543
21544 test_230t()
21545 {
21546         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21547         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21548                 skip "Need MDS version at least 2.14.50"
21549
21550         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21551         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21552         $LFS project -p 1 -s $DIR/$tdir ||
21553                 error "set $tdir project id failed"
21554         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21555                 error "set subdir project id failed"
21556         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21557 }
21558 run_test 230t "migrate directory with project ID set"
21559
21560 test_230u()
21561 {
21562         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21563         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21564                 skip "Need MDS version at least 2.14.53"
21565
21566         local count
21567
21568         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21569         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21570         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21571         for i in $(seq 0 $((MDSCOUNT - 1))); do
21572                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21573                 echo "$count dirs migrated to MDT$i"
21574         done
21575         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21576         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21577 }
21578 run_test 230u "migrate directory by QOS"
21579
21580 test_230v()
21581 {
21582         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21583         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21584                 skip "Need MDS version at least 2.14.53"
21585
21586         local count
21587
21588         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21589         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21590         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21591         for i in $(seq 0 $((MDSCOUNT - 1))); do
21592                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21593                 echo "$count subdirs migrated to MDT$i"
21594                 (( i == 3 )) && (( count > 0 )) &&
21595                         error "subdir shouldn't be migrated to MDT3"
21596         done
21597         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21598         (( count == 3 )) || error "dirs migrated to $count MDTs"
21599 }
21600 run_test 230v "subdir migrated to the MDT where its parent is located"
21601
21602 test_230w() {
21603         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21604         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21605                 skip "Need MDS version at least 2.15.0"
21606
21607         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21608         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21609         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21610
21611         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21612                 error "migrate failed"
21613
21614         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21615                 error "$tdir stripe count mismatch"
21616
21617         for i in $(seq 0 9); do
21618                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21619                         error "d$i is striped"
21620         done
21621 }
21622 run_test 230w "non-recursive mode dir migration"
21623
21624 test_230x() {
21625         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21626         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21627                 skip "Need MDS version at least 2.15.0"
21628
21629         mkdir -p $DIR/$tdir || error "mkdir failed"
21630         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21631
21632         local mdt_name=$(mdtname_from_index 0)
21633         local low=$(do_facet mds2 $LCTL get_param -n \
21634                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21635         local high=$(do_facet mds2 $LCTL get_param -n \
21636                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21637         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21638         local maxage=$(do_facet mds2 $LCTL get_param -n \
21639                 osp.*$mdt_name-osp-MDT0001.maxage)
21640
21641         stack_trap "do_facet mds2 $LCTL set_param -n \
21642                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21643                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21644         stack_trap "do_facet mds2 $LCTL set_param -n \
21645                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21646
21647         do_facet mds2 $LCTL set_param -n \
21648                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21649         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21650         sleep 4
21651         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21652                 error "migrate $tdir should fail"
21653
21654         do_facet mds2 $LCTL set_param -n \
21655                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21656         do_facet mds2 $LCTL set_param -n \
21657                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21658         sleep 4
21659         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21660                 error "migrate failed"
21661         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21662                 error "$tdir stripe count mismatch"
21663 }
21664 run_test 230x "dir migration check space"
21665
21666 test_231a()
21667 {
21668         # For simplicity this test assumes that max_pages_per_rpc
21669         # is the same across all OSCs
21670         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21671         local bulk_size=$((max_pages * PAGE_SIZE))
21672         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21673                                        head -n 1)
21674
21675         mkdir -p $DIR/$tdir
21676         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21677                 error "failed to set stripe with -S ${brw_size}M option"
21678
21679         # clear the OSC stats
21680         $LCTL set_param osc.*.stats=0 &>/dev/null
21681         stop_writeback
21682
21683         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21684         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21685                 oflag=direct &>/dev/null || error "dd failed"
21686
21687         sync; sleep 1; sync # just to be safe
21688         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21689         if [ x$nrpcs != "x1" ]; then
21690                 $LCTL get_param osc.*.stats
21691                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21692         fi
21693
21694         start_writeback
21695         # Drop the OSC cache, otherwise we will read from it
21696         cancel_lru_locks osc
21697
21698         # clear the OSC stats
21699         $LCTL set_param osc.*.stats=0 &>/dev/null
21700
21701         # Client reads $bulk_size.
21702         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21703                 iflag=direct &>/dev/null || error "dd failed"
21704
21705         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21706         if [ x$nrpcs != "x1" ]; then
21707                 $LCTL get_param osc.*.stats
21708                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21709         fi
21710 }
21711 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21712
21713 test_231b() {
21714         mkdir -p $DIR/$tdir
21715         local i
21716         for i in {0..1023}; do
21717                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21718                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21719                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21720         done
21721         sync
21722 }
21723 run_test 231b "must not assert on fully utilized OST request buffer"
21724
21725 test_232a() {
21726         mkdir -p $DIR/$tdir
21727         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21728
21729         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21730         do_facet ost1 $LCTL set_param fail_loc=0x31c
21731
21732         # ignore dd failure
21733         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21734
21735         do_facet ost1 $LCTL set_param fail_loc=0
21736         umount_client $MOUNT || error "umount failed"
21737         mount_client $MOUNT || error "mount failed"
21738         stop ost1 || error "cannot stop ost1"
21739         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21740 }
21741 run_test 232a "failed lock should not block umount"
21742
21743 test_232b() {
21744         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21745                 skip "Need MDS version at least 2.10.58"
21746
21747         mkdir -p $DIR/$tdir
21748         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21749         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21750         sync
21751         cancel_lru_locks osc
21752
21753         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21754         do_facet ost1 $LCTL set_param fail_loc=0x31c
21755
21756         # ignore failure
21757         $LFS data_version $DIR/$tdir/$tfile || true
21758
21759         do_facet ost1 $LCTL set_param fail_loc=0
21760         umount_client $MOUNT || error "umount failed"
21761         mount_client $MOUNT || error "mount failed"
21762         stop ost1 || error "cannot stop ost1"
21763         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21764 }
21765 run_test 232b "failed data version lock should not block umount"
21766
21767 test_233a() {
21768         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21769                 skip "Need MDS version at least 2.3.64"
21770         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21771
21772         local fid=$($LFS path2fid $MOUNT)
21773
21774         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21775                 error "cannot access $MOUNT using its FID '$fid'"
21776 }
21777 run_test 233a "checking that OBF of the FS root succeeds"
21778
21779 test_233b() {
21780         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21781                 skip "Need MDS version at least 2.5.90"
21782         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21783
21784         local fid=$($LFS path2fid $MOUNT/.lustre)
21785
21786         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21787                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21788
21789         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21790         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21791                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21792 }
21793 run_test 233b "checking that OBF of the FS .lustre succeeds"
21794
21795 test_234() {
21796         local p="$TMP/sanityN-$TESTNAME.parameters"
21797         save_lustre_params client "llite.*.xattr_cache" > $p
21798         lctl set_param llite.*.xattr_cache 1 ||
21799                 skip_env "xattr cache is not supported"
21800
21801         mkdir -p $DIR/$tdir || error "mkdir failed"
21802         touch $DIR/$tdir/$tfile || error "touch failed"
21803         # OBD_FAIL_LLITE_XATTR_ENOMEM
21804         $LCTL set_param fail_loc=0x1405
21805         getfattr -n user.attr $DIR/$tdir/$tfile &&
21806                 error "getfattr should have failed with ENOMEM"
21807         $LCTL set_param fail_loc=0x0
21808         rm -rf $DIR/$tdir
21809
21810         restore_lustre_params < $p
21811         rm -f $p
21812 }
21813 run_test 234 "xattr cache should not crash on ENOMEM"
21814
21815 test_235() {
21816         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21817                 skip "Need MDS version at least 2.4.52"
21818
21819         flock_deadlock $DIR/$tfile
21820         local RC=$?
21821         case $RC in
21822                 0)
21823                 ;;
21824                 124) error "process hangs on a deadlock"
21825                 ;;
21826                 *) error "error executing flock_deadlock $DIR/$tfile"
21827                 ;;
21828         esac
21829 }
21830 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21831
21832 #LU-2935
21833 test_236() {
21834         check_swap_layouts_support
21835
21836         local ref1=/etc/passwd
21837         local ref2=/etc/group
21838         local file1=$DIR/$tdir/f1
21839         local file2=$DIR/$tdir/f2
21840
21841         test_mkdir -c1 $DIR/$tdir
21842         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21843         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21844         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21845         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21846         local fd=$(free_fd)
21847         local cmd="exec $fd<>$file2"
21848         eval $cmd
21849         rm $file2
21850         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21851                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21852         cmd="exec $fd>&-"
21853         eval $cmd
21854         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21855
21856         #cleanup
21857         rm -rf $DIR/$tdir
21858 }
21859 run_test 236 "Layout swap on open unlinked file"
21860
21861 # LU-4659 linkea consistency
21862 test_238() {
21863         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21864                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21865                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21866                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21867
21868         touch $DIR/$tfile
21869         ln $DIR/$tfile $DIR/$tfile.lnk
21870         touch $DIR/$tfile.new
21871         mv $DIR/$tfile.new $DIR/$tfile
21872         local fid1=$($LFS path2fid $DIR/$tfile)
21873         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21874         local path1=$($LFS fid2path $FSNAME "$fid1")
21875         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21876         local path2=$($LFS fid2path $FSNAME "$fid2")
21877         [ $tfile.lnk == $path2 ] ||
21878                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21879         rm -f $DIR/$tfile*
21880 }
21881 run_test 238 "Verify linkea consistency"
21882
21883 test_239A() { # was test_239
21884         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21885                 skip "Need MDS version at least 2.5.60"
21886
21887         local list=$(comma_list $(mdts_nodes))
21888
21889         mkdir -p $DIR/$tdir
21890         createmany -o $DIR/$tdir/f- 5000
21891         unlinkmany $DIR/$tdir/f- 5000
21892         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21893                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21894         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21895                         osp.*MDT*.sync_in_flight" | calc_sum)
21896         [ "$changes" -eq 0 ] || error "$changes not synced"
21897 }
21898 run_test 239A "osp_sync test"
21899
21900 test_239a() { #LU-5297
21901         remote_mds_nodsh && skip "remote MDS with nodsh"
21902
21903         touch $DIR/$tfile
21904         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21905         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21906         chgrp $RUNAS_GID $DIR/$tfile
21907         wait_delete_completed
21908 }
21909 run_test 239a "process invalid osp sync record correctly"
21910
21911 test_239b() { #LU-5297
21912         remote_mds_nodsh && skip "remote MDS with nodsh"
21913
21914         touch $DIR/$tfile1
21915         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21916         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21917         chgrp $RUNAS_GID $DIR/$tfile1
21918         wait_delete_completed
21919         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21920         touch $DIR/$tfile2
21921         chgrp $RUNAS_GID $DIR/$tfile2
21922         wait_delete_completed
21923 }
21924 run_test 239b "process osp sync record with ENOMEM error correctly"
21925
21926 test_240() {
21927         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21928         remote_mds_nodsh && skip "remote MDS with nodsh"
21929
21930         mkdir -p $DIR/$tdir
21931
21932         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21933                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21934         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21935                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21936
21937         umount_client $MOUNT || error "umount failed"
21938         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21939         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21940         mount_client $MOUNT || error "failed to mount client"
21941
21942         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21943         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21944 }
21945 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21946
21947 test_241_bio() {
21948         local count=$1
21949         local bsize=$2
21950
21951         for LOOP in $(seq $count); do
21952                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21953                 cancel_lru_locks $OSC || true
21954         done
21955 }
21956
21957 test_241_dio() {
21958         local count=$1
21959         local bsize=$2
21960
21961         for LOOP in $(seq $1); do
21962                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21963                         2>/dev/null
21964         done
21965 }
21966
21967 test_241a() { # was test_241
21968         local bsize=$PAGE_SIZE
21969
21970         (( bsize < 40960 )) && bsize=40960
21971         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21972         ls -la $DIR/$tfile
21973         cancel_lru_locks $OSC
21974         test_241_bio 1000 $bsize &
21975         PID=$!
21976         test_241_dio 1000 $bsize
21977         wait $PID
21978 }
21979 run_test 241a "bio vs dio"
21980
21981 test_241b() {
21982         local bsize=$PAGE_SIZE
21983
21984         (( bsize < 40960 )) && bsize=40960
21985         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21986         ls -la $DIR/$tfile
21987         test_241_dio 1000 $bsize &
21988         PID=$!
21989         test_241_dio 1000 $bsize
21990         wait $PID
21991 }
21992 run_test 241b "dio vs dio"
21993
21994 test_242() {
21995         remote_mds_nodsh && skip "remote MDS with nodsh"
21996
21997         mkdir_on_mdt0 $DIR/$tdir
21998         touch $DIR/$tdir/$tfile
21999
22000         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22001         do_facet mds1 lctl set_param fail_loc=0x105
22002         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22003
22004         do_facet mds1 lctl set_param fail_loc=0
22005         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22006 }
22007 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22008
22009 test_243()
22010 {
22011         test_mkdir $DIR/$tdir
22012         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22013 }
22014 run_test 243 "various group lock tests"
22015
22016 test_244a()
22017 {
22018         test_mkdir $DIR/$tdir
22019         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22020         sendfile_grouplock $DIR/$tdir/$tfile || \
22021                 error "sendfile+grouplock failed"
22022         rm -rf $DIR/$tdir
22023 }
22024 run_test 244a "sendfile with group lock tests"
22025
22026 test_244b()
22027 {
22028         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22029
22030         local threads=50
22031         local size=$((1024*1024))
22032
22033         test_mkdir $DIR/$tdir
22034         for i in $(seq 1 $threads); do
22035                 local file=$DIR/$tdir/file_$((i / 10))
22036                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22037                 local pids[$i]=$!
22038         done
22039         for i in $(seq 1 $threads); do
22040                 wait ${pids[$i]}
22041         done
22042 }
22043 run_test 244b "multi-threaded write with group lock"
22044
22045 test_245a() {
22046         local flagname="multi_mod_rpcs"
22047         local connect_data_name="max_mod_rpcs"
22048         local out
22049
22050         # check if multiple modify RPCs flag is set
22051         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22052                 grep "connect_flags:")
22053         echo "$out"
22054
22055         echo "$out" | grep -qw $flagname
22056         if [ $? -ne 0 ]; then
22057                 echo "connect flag $flagname is not set"
22058                 return
22059         fi
22060
22061         # check if multiple modify RPCs data is set
22062         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22063         echo "$out"
22064
22065         echo "$out" | grep -qw $connect_data_name ||
22066                 error "import should have connect data $connect_data_name"
22067 }
22068 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22069
22070 test_245b() {
22071         local flagname="multi_mod_rpcs"
22072         local connect_data_name="max_mod_rpcs"
22073         local out
22074
22075         remote_mds_nodsh && skip "remote MDS with nodsh"
22076         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22077
22078         # check if multiple modify RPCs flag is set
22079         out=$(do_facet mds1 \
22080               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22081               grep "connect_flags:")
22082         echo "$out"
22083
22084         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22085
22086         # check if multiple modify RPCs data is set
22087         out=$(do_facet mds1 \
22088               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22089
22090         [[ "$out" =~ $connect_data_name ]] ||
22091                 {
22092                         echo "$out"
22093                         error "missing connect data $connect_data_name"
22094                 }
22095 }
22096 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22097
22098 cleanup_247() {
22099         local submount=$1
22100
22101         trap 0
22102         umount_client $submount
22103         rmdir $submount
22104 }
22105
22106 test_247a() {
22107         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22108                 grep -q subtree ||
22109                 skip_env "Fileset feature is not supported"
22110
22111         local submount=${MOUNT}_$tdir
22112
22113         mkdir $MOUNT/$tdir
22114         mkdir -p $submount || error "mkdir $submount failed"
22115         FILESET="$FILESET/$tdir" mount_client $submount ||
22116                 error "mount $submount failed"
22117         trap "cleanup_247 $submount" EXIT
22118         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22119         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22120                 error "read $MOUNT/$tdir/$tfile failed"
22121         cleanup_247 $submount
22122 }
22123 run_test 247a "mount subdir as fileset"
22124
22125 test_247b() {
22126         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22127                 skip_env "Fileset feature is not supported"
22128
22129         local submount=${MOUNT}_$tdir
22130
22131         rm -rf $MOUNT/$tdir
22132         mkdir -p $submount || error "mkdir $submount failed"
22133         SKIP_FILESET=1
22134         FILESET="$FILESET/$tdir" mount_client $submount &&
22135                 error "mount $submount should fail"
22136         rmdir $submount
22137 }
22138 run_test 247b "mount subdir that dose not exist"
22139
22140 test_247c() {
22141         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22142                 skip_env "Fileset feature is not supported"
22143
22144         local submount=${MOUNT}_$tdir
22145
22146         mkdir -p $MOUNT/$tdir/dir1
22147         mkdir -p $submount || error "mkdir $submount failed"
22148         trap "cleanup_247 $submount" EXIT
22149         FILESET="$FILESET/$tdir" mount_client $submount ||
22150                 error "mount $submount failed"
22151         local fid=$($LFS path2fid $MOUNT/)
22152         $LFS fid2path $submount $fid && error "fid2path should fail"
22153         cleanup_247 $submount
22154 }
22155 run_test 247c "running fid2path outside subdirectory root"
22156
22157 test_247d() {
22158         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22159                 skip "Fileset feature is not supported"
22160
22161         local submount=${MOUNT}_$tdir
22162
22163         mkdir -p $MOUNT/$tdir/dir1
22164         mkdir -p $submount || error "mkdir $submount failed"
22165         FILESET="$FILESET/$tdir" mount_client $submount ||
22166                 error "mount $submount failed"
22167         trap "cleanup_247 $submount" EXIT
22168
22169         local td=$submount/dir1
22170         local fid=$($LFS path2fid $td)
22171         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22172
22173         # check that we get the same pathname back
22174         local rootpath
22175         local found
22176         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22177                 echo "$rootpath $fid"
22178                 found=$($LFS fid2path $rootpath "$fid")
22179                 [ -n "$found" ] || error "fid2path should succeed"
22180                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22181         done
22182         # check wrong root path format
22183         rootpath=$submount"_wrong"
22184         found=$($LFS fid2path $rootpath "$fid")
22185         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22186
22187         cleanup_247 $submount
22188 }
22189 run_test 247d "running fid2path inside subdirectory root"
22190
22191 # LU-8037
22192 test_247e() {
22193         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22194                 grep -q subtree ||
22195                 skip "Fileset feature is not supported"
22196
22197         local submount=${MOUNT}_$tdir
22198
22199         mkdir $MOUNT/$tdir
22200         mkdir -p $submount || error "mkdir $submount failed"
22201         FILESET="$FILESET/.." mount_client $submount &&
22202                 error "mount $submount should fail"
22203         rmdir $submount
22204 }
22205 run_test 247e "mount .. as fileset"
22206
22207 test_247f() {
22208         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22209         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22210                 skip "Need at least version 2.14.50.162"
22211         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22212                 skip "Fileset feature is not supported"
22213
22214         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22215         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22216                 error "mkdir remote failed"
22217         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22218                 error "mkdir remote/subdir failed"
22219         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22220                 error "mkdir striped failed"
22221         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22222
22223         local submount=${MOUNT}_$tdir
22224
22225         mkdir -p $submount || error "mkdir $submount failed"
22226         stack_trap "rmdir $submount"
22227
22228         local dir
22229         local fileset=$FILESET
22230         local mdts=$(comma_list $(mdts_nodes))
22231
22232         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22233         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22234                 $tdir/striped/subdir $tdir/striped/.; do
22235                 FILESET="$fileset/$dir" mount_client $submount ||
22236                         error "mount $dir failed"
22237                 umount_client $submount
22238         done
22239 }
22240 run_test 247f "mount striped or remote directory as fileset"
22241
22242 test_subdir_mount_lock()
22243 {
22244         local testdir=$1
22245         local submount=${MOUNT}_$(basename $testdir)
22246
22247         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22248
22249         mkdir -p $submount || error "mkdir $submount failed"
22250         stack_trap "rmdir $submount"
22251
22252         FILESET="$fileset/$testdir" mount_client $submount ||
22253                 error "mount $FILESET failed"
22254         stack_trap "umount $submount"
22255
22256         local mdts=$(comma_list $(mdts_nodes))
22257
22258         local nrpcs
22259
22260         stat $submount > /dev/null || error "stat $submount failed"
22261         cancel_lru_locks $MDC
22262         stat $submount > /dev/null || error "stat $submount failed"
22263         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22264         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22265         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22266         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22267                 awk '/getattr/ {sum += $2} END {print sum}')
22268
22269         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22270 }
22271
22272 test_247g() {
22273         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22274
22275         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22276                 error "mkdir $tdir failed"
22277         test_subdir_mount_lock $tdir
22278 }
22279 run_test 247g "striped directory submount revalidate ROOT from cache"
22280
22281 test_247h() {
22282         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22283         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22284                 skip "Need MDS version at least 2.15.51"
22285
22286         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22287         test_subdir_mount_lock $tdir
22288         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22289         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22290                 error "mkdir $tdir.1 failed"
22291         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22292 }
22293 run_test 247h "remote directory submount revalidate ROOT from cache"
22294
22295 test_248a() {
22296         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22297         [ -z "$fast_read_sav" ] && skip "no fast read support"
22298
22299         # create a large file for fast read verification
22300         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22301
22302         # make sure the file is created correctly
22303         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22304                 { rm -f $DIR/$tfile; skip "file creation error"; }
22305
22306         echo "Test 1: verify that fast read is 4 times faster on cache read"
22307
22308         # small read with fast read enabled
22309         $LCTL set_param -n llite.*.fast_read=1
22310         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22311                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22312                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22313         # small read with fast read disabled
22314         $LCTL set_param -n llite.*.fast_read=0
22315         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22316                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22317                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22318
22319         # verify that fast read is 4 times faster for cache read
22320         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22321                 error_not_in_vm "fast read was not 4 times faster: " \
22322                            "$t_fast vs $t_slow"
22323
22324         echo "Test 2: verify the performance between big and small read"
22325         $LCTL set_param -n llite.*.fast_read=1
22326
22327         # 1k non-cache read
22328         cancel_lru_locks osc
22329         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22330                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22331                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22332
22333         # 1M non-cache read
22334         cancel_lru_locks osc
22335         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22336                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22337                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22338
22339         # verify that big IO is not 4 times faster than small IO
22340         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22341                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22342
22343         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22344         rm -f $DIR/$tfile
22345 }
22346 run_test 248a "fast read verification"
22347
22348 test_248b() {
22349         # Default short_io_bytes=16384, try both smaller and larger sizes.
22350         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22351         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22352         echo "bs=53248 count=113 normal buffered write"
22353         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22354                 error "dd of initial data file failed"
22355         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22356
22357         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22358         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22359                 error "dd with sync normal writes failed"
22360         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22361
22362         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22363         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22364                 error "dd with sync small writes failed"
22365         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22366
22367         cancel_lru_locks osc
22368
22369         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22370         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22371         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22372         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22373                 iflag=direct || error "dd with O_DIRECT small read failed"
22374         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22375         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22376                 error "compare $TMP/$tfile.1 failed"
22377
22378         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22379         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22380
22381         # just to see what the maximum tunable value is, and test parsing
22382         echo "test invalid parameter 2MB"
22383         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22384                 error "too-large short_io_bytes allowed"
22385         echo "test maximum parameter 512KB"
22386         # if we can set a larger short_io_bytes, run test regardless of version
22387         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22388                 # older clients may not allow setting it this large, that's OK
22389                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22390                         skip "Need at least client version 2.13.50"
22391                 error "medium short_io_bytes failed"
22392         fi
22393         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22394         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22395
22396         echo "test large parameter 64KB"
22397         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22398         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22399
22400         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22401         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22402                 error "dd with sync large writes failed"
22403         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22404
22405         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22406         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22407         num=$((113 * 4096 / PAGE_SIZE))
22408         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22409         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22410                 error "dd with O_DIRECT large writes failed"
22411         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22412                 error "compare $DIR/$tfile.3 failed"
22413
22414         cancel_lru_locks osc
22415
22416         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22417         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22418                 error "dd with O_DIRECT large read failed"
22419         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22420                 error "compare $TMP/$tfile.2 failed"
22421
22422         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22423         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22424                 error "dd with O_DIRECT large read failed"
22425         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22426                 error "compare $TMP/$tfile.3 failed"
22427 }
22428 run_test 248b "test short_io read and write for both small and large sizes"
22429
22430 test_249() { # LU-7890
22431         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22432                 skip "Need at least version 2.8.54"
22433
22434         rm -f $DIR/$tfile
22435         $LFS setstripe -c 1 $DIR/$tfile
22436         # Offset 2T == 4k * 512M
22437         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22438                 error "dd to 2T offset failed"
22439 }
22440 run_test 249 "Write above 2T file size"
22441
22442 test_250() {
22443         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22444          && skip "no 16TB file size limit on ZFS"
22445
22446         $LFS setstripe -c 1 $DIR/$tfile
22447         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22448         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22449         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22450         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22451                 conv=notrunc,fsync && error "append succeeded"
22452         return 0
22453 }
22454 run_test 250 "Write above 16T limit"
22455
22456 test_251() {
22457         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22458
22459         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22460         #Skip once - writing the first stripe will succeed
22461         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22462         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22463                 error "short write happened"
22464
22465         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22466         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22467                 error "short read happened"
22468
22469         rm -f $DIR/$tfile
22470 }
22471 run_test 251 "Handling short read and write correctly"
22472
22473 test_252() {
22474         remote_mds_nodsh && skip "remote MDS with nodsh"
22475         remote_ost_nodsh && skip "remote OST with nodsh"
22476         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22477                 skip_env "ldiskfs only test"
22478         fi
22479
22480         local tgt
22481         local dev
22482         local out
22483         local uuid
22484         local num
22485         local gen
22486
22487         # check lr_reader on OST0000
22488         tgt=ost1
22489         dev=$(facet_device $tgt)
22490         out=$(do_facet $tgt $LR_READER $dev)
22491         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22492         echo "$out"
22493         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22494         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22495                 error "Invalid uuid returned by $LR_READER on target $tgt"
22496         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22497
22498         # check lr_reader -c on MDT0000
22499         tgt=mds1
22500         dev=$(facet_device $tgt)
22501         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22502                 skip "$LR_READER does not support additional options"
22503         fi
22504         out=$(do_facet $tgt $LR_READER -c $dev)
22505         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22506         echo "$out"
22507         num=$(echo "$out" | grep -c "mdtlov")
22508         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22509                 error "Invalid number of mdtlov clients returned by $LR_READER"
22510         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22511
22512         # check lr_reader -cr on MDT0000
22513         out=$(do_facet $tgt $LR_READER -cr $dev)
22514         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22515         echo "$out"
22516         echo "$out" | grep -q "^reply_data:$" ||
22517                 error "$LR_READER should have returned 'reply_data' section"
22518         num=$(echo "$out" | grep -c "client_generation")
22519         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22520 }
22521 run_test 252 "check lr_reader tool"
22522
22523 test_253() {
22524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22525         remote_mds_nodsh && skip "remote MDS with nodsh"
22526         remote_mgs_nodsh && skip "remote MGS with nodsh"
22527
22528         local ostidx=0
22529         local rc=0
22530         local ost_name=$(ostname_from_index $ostidx)
22531
22532         # on the mdt's osc
22533         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22534         do_facet $SINGLEMDS $LCTL get_param -n \
22535                 osp.$mdtosc_proc1.reserved_mb_high ||
22536                 skip  "remote MDS does not support reserved_mb_high"
22537
22538         rm -rf $DIR/$tdir
22539         wait_mds_ost_sync
22540         wait_delete_completed
22541         mkdir $DIR/$tdir
22542
22543         pool_add $TESTNAME || error "Pool creation failed"
22544         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22545
22546         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22547                 error "Setstripe failed"
22548
22549         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22550
22551         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22552                     grep "watermarks")
22553         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22554
22555         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22556                         osp.$mdtosc_proc1.prealloc_status)
22557         echo "prealloc_status $oa_status"
22558
22559         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22560                 error "File creation should fail"
22561
22562         #object allocation was stopped, but we still able to append files
22563         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22564                 oflag=append || error "Append failed"
22565
22566         rm -f $DIR/$tdir/$tfile.0
22567
22568         # For this test, we want to delete the files we created to go out of
22569         # space but leave the watermark, so we remain nearly out of space
22570         ost_watermarks_enospc_delete_files $tfile $ostidx
22571
22572         wait_delete_completed
22573
22574         sleep_maxage
22575
22576         for i in $(seq 10 12); do
22577                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22578                         2>/dev/null || error "File creation failed after rm"
22579         done
22580
22581         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22582                         osp.$mdtosc_proc1.prealloc_status)
22583         echo "prealloc_status $oa_status"
22584
22585         if (( oa_status != 0 )); then
22586                 error "Object allocation still disable after rm"
22587         fi
22588 }
22589 run_test 253 "Check object allocation limit"
22590
22591 test_254() {
22592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22593         remote_mds_nodsh && skip "remote MDS with nodsh"
22594
22595         local mdt=$(facet_svc $SINGLEMDS)
22596
22597         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22598                 skip "MDS does not support changelog_size"
22599
22600         local cl_user
22601
22602         changelog_register || error "changelog_register failed"
22603
22604         changelog_clear 0 || error "changelog_clear failed"
22605
22606         local size1=$(do_facet $SINGLEMDS \
22607                       $LCTL get_param -n mdd.$mdt.changelog_size)
22608         echo "Changelog size $size1"
22609
22610         rm -rf $DIR/$tdir
22611         $LFS mkdir -i 0 $DIR/$tdir
22612         # change something
22613         mkdir -p $DIR/$tdir/pics/2008/zachy
22614         touch $DIR/$tdir/pics/2008/zachy/timestamp
22615         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22616         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22617         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22618         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22619         rm $DIR/$tdir/pics/desktop.jpg
22620
22621         local size2=$(do_facet $SINGLEMDS \
22622                       $LCTL get_param -n mdd.$mdt.changelog_size)
22623         echo "Changelog size after work $size2"
22624
22625         (( $size2 > $size1 )) ||
22626                 error "new Changelog size=$size2 less than old size=$size1"
22627 }
22628 run_test 254 "Check changelog size"
22629
22630 ladvise_no_type()
22631 {
22632         local type=$1
22633         local file=$2
22634
22635         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22636                 awk -F: '{print $2}' | grep $type > /dev/null
22637         if [ $? -ne 0 ]; then
22638                 return 0
22639         fi
22640         return 1
22641 }
22642
22643 ladvise_no_ioctl()
22644 {
22645         local file=$1
22646
22647         lfs ladvise -a willread $file > /dev/null 2>&1
22648         if [ $? -eq 0 ]; then
22649                 return 1
22650         fi
22651
22652         lfs ladvise -a willread $file 2>&1 |
22653                 grep "Inappropriate ioctl for device" > /dev/null
22654         if [ $? -eq 0 ]; then
22655                 return 0
22656         fi
22657         return 1
22658 }
22659
22660 percent() {
22661         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22662 }
22663
22664 # run a random read IO workload
22665 # usage: random_read_iops <filename> <filesize> <iosize>
22666 random_read_iops() {
22667         local file=$1
22668         local fsize=$2
22669         local iosize=${3:-4096}
22670
22671         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22672                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22673 }
22674
22675 drop_file_oss_cache() {
22676         local file="$1"
22677         local nodes="$2"
22678
22679         $LFS ladvise -a dontneed $file 2>/dev/null ||
22680                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22681 }
22682
22683 ladvise_willread_performance()
22684 {
22685         local repeat=10
22686         local average_origin=0
22687         local average_cache=0
22688         local average_ladvise=0
22689
22690         for ((i = 1; i <= $repeat; i++)); do
22691                 echo "Iter $i/$repeat: reading without willread hint"
22692                 cancel_lru_locks osc
22693                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22694                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22695                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22696                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22697
22698                 cancel_lru_locks osc
22699                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22700                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22701                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22702
22703                 cancel_lru_locks osc
22704                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22705                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22706                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22707                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22708                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22709         done
22710         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22711         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22712         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22713
22714         speedup_cache=$(percent $average_cache $average_origin)
22715         speedup_ladvise=$(percent $average_ladvise $average_origin)
22716
22717         echo "Average uncached read: $average_origin"
22718         echo "Average speedup with OSS cached read: " \
22719                 "$average_cache = +$speedup_cache%"
22720         echo "Average speedup with ladvise willread: " \
22721                 "$average_ladvise = +$speedup_ladvise%"
22722
22723         local lowest_speedup=20
22724         if (( ${average_cache%.*} < $lowest_speedup )); then
22725                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22726                      " got $average_cache%. Skipping ladvise willread check."
22727                 return 0
22728         fi
22729
22730         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22731         # it is still good to run until then to exercise 'ladvise willread'
22732         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22733                 [ "$ost1_FSTYPE" = "zfs" ] &&
22734                 echo "osd-zfs does not support dontneed or drop_caches" &&
22735                 return 0
22736
22737         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22738         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22739                 error_not_in_vm "Speedup with willread is less than " \
22740                         "$lowest_speedup%, got $average_ladvise%"
22741 }
22742
22743 test_255a() {
22744         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22745                 skip "lustre < 2.8.54 does not support ladvise "
22746         remote_ost_nodsh && skip "remote OST with nodsh"
22747
22748         stack_trap "rm -f $DIR/$tfile"
22749         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22750
22751         ladvise_no_type willread $DIR/$tfile &&
22752                 skip "willread ladvise is not supported"
22753
22754         ladvise_no_ioctl $DIR/$tfile &&
22755                 skip "ladvise ioctl is not supported"
22756
22757         local size_mb=100
22758         local size=$((size_mb * 1048576))
22759         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22760                 error "dd to $DIR/$tfile failed"
22761
22762         lfs ladvise -a willread $DIR/$tfile ||
22763                 error "Ladvise failed with no range argument"
22764
22765         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22766                 error "Ladvise failed with no -l or -e argument"
22767
22768         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22769                 error "Ladvise failed with only -e argument"
22770
22771         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22772                 error "Ladvise failed with only -l argument"
22773
22774         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22775                 error "End offset should not be smaller than start offset"
22776
22777         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22778                 error "End offset should not be equal to start offset"
22779
22780         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22781                 error "Ladvise failed with overflowing -s argument"
22782
22783         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22784                 error "Ladvise failed with overflowing -e argument"
22785
22786         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22787                 error "Ladvise failed with overflowing -l argument"
22788
22789         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22790                 error "Ladvise succeeded with conflicting -l and -e arguments"
22791
22792         echo "Synchronous ladvise should wait"
22793         local delay=4
22794 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22795         do_nodes $(comma_list $(osts_nodes)) \
22796                 $LCTL set_param fail_val=$delay fail_loc=0x237
22797
22798         local start_ts=$SECONDS
22799         lfs ladvise -a willread $DIR/$tfile ||
22800                 error "Ladvise failed with no range argument"
22801         local end_ts=$SECONDS
22802         local inteval_ts=$((end_ts - start_ts))
22803
22804         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22805                 error "Synchronous advice didn't wait reply"
22806         fi
22807
22808         echo "Asynchronous ladvise shouldn't wait"
22809         local start_ts=$SECONDS
22810         lfs ladvise -a willread -b $DIR/$tfile ||
22811                 error "Ladvise failed with no range argument"
22812         local end_ts=$SECONDS
22813         local inteval_ts=$((end_ts - start_ts))
22814
22815         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22816                 error "Asynchronous advice blocked"
22817         fi
22818
22819         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22820         ladvise_willread_performance
22821 }
22822 run_test 255a "check 'lfs ladvise -a willread'"
22823
22824 facet_meminfo() {
22825         local facet=$1
22826         local info=$2
22827
22828         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22829 }
22830
22831 test_255b() {
22832         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22833                 skip "lustre < 2.8.54 does not support ladvise "
22834         remote_ost_nodsh && skip "remote OST with nodsh"
22835
22836         stack_trap "rm -f $DIR/$tfile"
22837         lfs setstripe -c 1 -i 0 $DIR/$tfile
22838
22839         ladvise_no_type dontneed $DIR/$tfile &&
22840                 skip "dontneed ladvise is not supported"
22841
22842         ladvise_no_ioctl $DIR/$tfile &&
22843                 skip "ladvise ioctl is not supported"
22844
22845         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22846                 [ "$ost1_FSTYPE" = "zfs" ] &&
22847                 skip "zfs-osd does not support 'ladvise dontneed'"
22848
22849         local size_mb=100
22850         local size=$((size_mb * 1048576))
22851         # In order to prevent disturbance of other processes, only check 3/4
22852         # of the memory usage
22853         local kibibytes=$((size_mb * 1024 * 3 / 4))
22854
22855         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22856                 error "dd to $DIR/$tfile failed"
22857
22858         #force write to complete before dropping OST cache & checking memory
22859         sync
22860
22861         local total=$(facet_meminfo ost1 MemTotal)
22862         echo "Total memory: $total KiB"
22863
22864         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22865         local before_read=$(facet_meminfo ost1 Cached)
22866         echo "Cache used before read: $before_read KiB"
22867
22868         lfs ladvise -a willread $DIR/$tfile ||
22869                 error "Ladvise willread failed"
22870         local after_read=$(facet_meminfo ost1 Cached)
22871         echo "Cache used after read: $after_read KiB"
22872
22873         lfs ladvise -a dontneed $DIR/$tfile ||
22874                 error "Ladvise dontneed again failed"
22875         local no_read=$(facet_meminfo ost1 Cached)
22876         echo "Cache used after dontneed ladvise: $no_read KiB"
22877
22878         if [ $total -lt $((before_read + kibibytes)) ]; then
22879                 echo "Memory is too small, abort checking"
22880                 return 0
22881         fi
22882
22883         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22884                 error "Ladvise willread should use more memory" \
22885                         "than $kibibytes KiB"
22886         fi
22887
22888         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22889                 error "Ladvise dontneed should release more memory" \
22890                         "than $kibibytes KiB"
22891         fi
22892 }
22893 run_test 255b "check 'lfs ladvise -a dontneed'"
22894
22895 test_255c() {
22896         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22897                 skip "lustre < 2.10.50 does not support lockahead"
22898
22899         local ost1_imp=$(get_osc_import_name client ost1)
22900         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22901                          cut -d'.' -f2)
22902         local count
22903         local new_count
22904         local difference
22905         local i
22906         local rc
22907
22908         test_mkdir -p $DIR/$tdir
22909         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22910
22911         #test 10 returns only success/failure
22912         i=10
22913         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22914         rc=$?
22915         if [ $rc -eq 255 ]; then
22916                 error "Ladvise test${i} failed, ${rc}"
22917         fi
22918
22919         #test 11 counts lock enqueue requests, all others count new locks
22920         i=11
22921         count=$(do_facet ost1 \
22922                 $LCTL get_param -n ost.OSS.ost.stats)
22923         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22924
22925         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22926         rc=$?
22927         if [ $rc -eq 255 ]; then
22928                 error "Ladvise test${i} failed, ${rc}"
22929         fi
22930
22931         new_count=$(do_facet ost1 \
22932                 $LCTL get_param -n ost.OSS.ost.stats)
22933         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22934                    awk '{ print $2 }')
22935
22936         difference="$((new_count - count))"
22937         if [ $difference -ne $rc ]; then
22938                 error "Ladvise test${i}, bad enqueue count, returned " \
22939                       "${rc}, actual ${difference}"
22940         fi
22941
22942         for i in $(seq 12 21); do
22943                 # If we do not do this, we run the risk of having too many
22944                 # locks and starting lock cancellation while we are checking
22945                 # lock counts.
22946                 cancel_lru_locks osc
22947
22948                 count=$($LCTL get_param -n \
22949                        ldlm.namespaces.$imp_name.lock_unused_count)
22950
22951                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22952                 rc=$?
22953                 if [ $rc -eq 255 ]; then
22954                         error "Ladvise test ${i} failed, ${rc}"
22955                 fi
22956
22957                 new_count=$($LCTL get_param -n \
22958                        ldlm.namespaces.$imp_name.lock_unused_count)
22959                 difference="$((new_count - count))"
22960
22961                 # Test 15 output is divided by 100 to map down to valid return
22962                 if [ $i -eq 15 ]; then
22963                         rc="$((rc * 100))"
22964                 fi
22965
22966                 if [ $difference -ne $rc ]; then
22967                         error "Ladvise test ${i}, bad lock count, returned " \
22968                               "${rc}, actual ${difference}"
22969                 fi
22970         done
22971
22972         #test 22 returns only success/failure
22973         i=22
22974         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22975         rc=$?
22976         if [ $rc -eq 255 ]; then
22977                 error "Ladvise test${i} failed, ${rc}"
22978         fi
22979 }
22980 run_test 255c "suite of ladvise lockahead tests"
22981
22982 test_256() {
22983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22984         remote_mds_nodsh && skip "remote MDS with nodsh"
22985         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22986         changelog_users $SINGLEMDS | grep "^cl" &&
22987                 skip "active changelog user"
22988
22989         local cl_user
22990         local cat_sl
22991         local mdt_dev
22992
22993         mdt_dev=$(facet_device $SINGLEMDS)
22994         echo $mdt_dev
22995
22996         changelog_register || error "changelog_register failed"
22997
22998         rm -rf $DIR/$tdir
22999         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23000
23001         changelog_clear 0 || error "changelog_clear failed"
23002
23003         # change something
23004         touch $DIR/$tdir/{1..10}
23005
23006         # stop the MDT
23007         stop $SINGLEMDS || error "Fail to stop MDT"
23008
23009         # remount the MDT
23010         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23011                 error "Fail to start MDT"
23012
23013         #after mount new plainllog is used
23014         touch $DIR/$tdir/{11..19}
23015         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23016         stack_trap "rm -f $tmpfile"
23017         cat_sl=$(do_facet $SINGLEMDS "sync; \
23018                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23019                  llog_reader $tmpfile | grep -c type=1064553b")
23020         do_facet $SINGLEMDS llog_reader $tmpfile
23021
23022         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23023
23024         changelog_clear 0 || error "changelog_clear failed"
23025
23026         cat_sl=$(do_facet $SINGLEMDS "sync; \
23027                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23028                  llog_reader $tmpfile | grep -c type=1064553b")
23029
23030         if (( cat_sl == 2 )); then
23031                 error "Empty plain llog was not deleted from changelog catalog"
23032         elif (( cat_sl != 1 )); then
23033                 error "Active plain llog shouldn't be deleted from catalog"
23034         fi
23035 }
23036 run_test 256 "Check llog delete for empty and not full state"
23037
23038 test_257() {
23039         remote_mds_nodsh && skip "remote MDS with nodsh"
23040         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23041                 skip "Need MDS version at least 2.8.55"
23042
23043         test_mkdir $DIR/$tdir
23044
23045         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23046                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23047         stat $DIR/$tdir
23048
23049 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23050         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23051         local facet=mds$((mdtidx + 1))
23052         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23053         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23054
23055         stop $facet || error "stop MDS failed"
23056         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23057                 error "start MDS fail"
23058         wait_recovery_complete $facet
23059 }
23060 run_test 257 "xattr locks are not lost"
23061
23062 # Verify we take the i_mutex when security requires it
23063 test_258a() {
23064 #define OBD_FAIL_IMUTEX_SEC 0x141c
23065         $LCTL set_param fail_loc=0x141c
23066         touch $DIR/$tfile
23067         chmod u+s $DIR/$tfile
23068         chmod a+rwx $DIR/$tfile
23069         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23070         RC=$?
23071         if [ $RC -ne 0 ]; then
23072                 error "error, failed to take i_mutex, rc=$?"
23073         fi
23074         rm -f $DIR/$tfile
23075 }
23076 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23077
23078 # Verify we do NOT take the i_mutex in the normal case
23079 test_258b() {
23080 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23081         $LCTL set_param fail_loc=0x141d
23082         touch $DIR/$tfile
23083         chmod a+rwx $DIR
23084         chmod a+rw $DIR/$tfile
23085         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23086         RC=$?
23087         if [ $RC -ne 0 ]; then
23088                 error "error, took i_mutex unnecessarily, rc=$?"
23089         fi
23090         rm -f $DIR/$tfile
23091
23092 }
23093 run_test 258b "verify i_mutex security behavior"
23094
23095 test_259() {
23096         local file=$DIR/$tfile
23097         local before
23098         local after
23099
23100         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23101
23102         stack_trap "rm -f $file" EXIT
23103
23104         wait_delete_completed
23105         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23106         echo "before: $before"
23107
23108         $LFS setstripe -i 0 -c 1 $file
23109         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23110         sync_all_data
23111         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23112         echo "after write: $after"
23113
23114 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23115         do_facet ost1 $LCTL set_param fail_loc=0x2301
23116         $TRUNCATE $file 0
23117         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23118         echo "after truncate: $after"
23119
23120         stop ost1
23121         do_facet ost1 $LCTL set_param fail_loc=0
23122         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23123         sleep 2
23124         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23125         echo "after restart: $after"
23126         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23127                 error "missing truncate?"
23128
23129         return 0
23130 }
23131 run_test 259 "crash at delayed truncate"
23132
23133 test_260() {
23134 #define OBD_FAIL_MDC_CLOSE               0x806
23135         $LCTL set_param fail_loc=0x80000806
23136         touch $DIR/$tfile
23137
23138 }
23139 run_test 260 "Check mdc_close fail"
23140
23141 ### Data-on-MDT sanity tests ###
23142 test_270a() {
23143         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23144                 skip "Need MDS version at least 2.10.55 for DoM"
23145
23146         # create DoM file
23147         local dom=$DIR/$tdir/dom_file
23148         local tmp=$DIR/$tdir/tmp_file
23149
23150         mkdir_on_mdt0 $DIR/$tdir
23151
23152         # basic checks for DoM component creation
23153         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23154                 error "Can set MDT layout to non-first entry"
23155
23156         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23157                 error "Can define multiple entries as MDT layout"
23158
23159         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23160
23161         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23162         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23163         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23164
23165         local mdtidx=$($LFS getstripe -m $dom)
23166         local mdtname=MDT$(printf %04x $mdtidx)
23167         local facet=mds$((mdtidx + 1))
23168         local space_check=1
23169
23170         # Skip free space checks with ZFS
23171         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23172
23173         # write
23174         sync
23175         local size_tmp=$((65536 * 3))
23176         local mdtfree1=$(do_facet $facet \
23177                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23178
23179         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23180         # check also direct IO along write
23181         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23182         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23183         sync
23184         cmp $tmp $dom || error "file data is different"
23185         [ $(stat -c%s $dom) == $size_tmp ] ||
23186                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23187         if [ $space_check == 1 ]; then
23188                 local mdtfree2=$(do_facet $facet \
23189                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23190
23191                 # increase in usage from by $size_tmp
23192                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23193                         error "MDT free space wrong after write: " \
23194                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23195         fi
23196
23197         # truncate
23198         local size_dom=10000
23199
23200         $TRUNCATE $dom $size_dom
23201         [ $(stat -c%s $dom) == $size_dom ] ||
23202                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23203         if [ $space_check == 1 ]; then
23204                 mdtfree1=$(do_facet $facet \
23205                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23206                 # decrease in usage from $size_tmp to new $size_dom
23207                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23208                   $(((size_tmp - size_dom) / 1024)) ] ||
23209                         error "MDT free space is wrong after truncate: " \
23210                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23211         fi
23212
23213         # append
23214         cat $tmp >> $dom
23215         sync
23216         size_dom=$((size_dom + size_tmp))
23217         [ $(stat -c%s $dom) == $size_dom ] ||
23218                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23219         if [ $space_check == 1 ]; then
23220                 mdtfree2=$(do_facet $facet \
23221                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23222                 # increase in usage by $size_tmp from previous
23223                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23224                         error "MDT free space is wrong after append: " \
23225                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23226         fi
23227
23228         # delete
23229         rm $dom
23230         if [ $space_check == 1 ]; then
23231                 mdtfree1=$(do_facet $facet \
23232                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23233                 # decrease in usage by $size_dom from previous
23234                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23235                         error "MDT free space is wrong after removal: " \
23236                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23237         fi
23238
23239         # combined striping
23240         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23241                 error "Can't create DoM + OST striping"
23242
23243         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23244         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23245         # check also direct IO along write
23246         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23247         sync
23248         cmp $tmp $dom || error "file data is different"
23249         [ $(stat -c%s $dom) == $size_tmp ] ||
23250                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23251         rm $dom $tmp
23252
23253         return 0
23254 }
23255 run_test 270a "DoM: basic functionality tests"
23256
23257 test_270b() {
23258         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23259                 skip "Need MDS version at least 2.10.55"
23260
23261         local dom=$DIR/$tdir/dom_file
23262         local max_size=1048576
23263
23264         mkdir -p $DIR/$tdir
23265         $LFS setstripe -E $max_size -L mdt $dom
23266
23267         # truncate over the limit
23268         $TRUNCATE $dom $(($max_size + 1)) &&
23269                 error "successful truncate over the maximum size"
23270         # write over the limit
23271         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23272                 error "successful write over the maximum size"
23273         # append over the limit
23274         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23275         echo "12345" >> $dom && error "successful append over the maximum size"
23276         rm $dom
23277
23278         return 0
23279 }
23280 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23281
23282 test_270c() {
23283         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23284                 skip "Need MDS version at least 2.10.55"
23285
23286         mkdir -p $DIR/$tdir
23287         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23288
23289         # check files inherit DoM EA
23290         touch $DIR/$tdir/first
23291         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23292                 error "bad pattern"
23293         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23294                 error "bad stripe count"
23295         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23296                 error "bad stripe size"
23297
23298         # check directory inherits DoM EA and uses it as default
23299         mkdir $DIR/$tdir/subdir
23300         touch $DIR/$tdir/subdir/second
23301         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23302                 error "bad pattern in sub-directory"
23303         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23304                 error "bad stripe count in sub-directory"
23305         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23306                 error "bad stripe size in sub-directory"
23307         return 0
23308 }
23309 run_test 270c "DoM: DoM EA inheritance tests"
23310
23311 test_270d() {
23312         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23313                 skip "Need MDS version at least 2.10.55"
23314
23315         mkdir -p $DIR/$tdir
23316         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23317
23318         # inherit default DoM striping
23319         mkdir $DIR/$tdir/subdir
23320         touch $DIR/$tdir/subdir/f1
23321
23322         # change default directory striping
23323         $LFS setstripe -c 1 $DIR/$tdir/subdir
23324         touch $DIR/$tdir/subdir/f2
23325         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23326                 error "wrong default striping in file 2"
23327         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23328                 error "bad pattern in file 2"
23329         return 0
23330 }
23331 run_test 270d "DoM: change striping from DoM to RAID0"
23332
23333 test_270e() {
23334         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23335                 skip "Need MDS version at least 2.10.55"
23336
23337         mkdir -p $DIR/$tdir/dom
23338         mkdir -p $DIR/$tdir/norm
23339         DOMFILES=20
23340         NORMFILES=10
23341         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23342         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23343
23344         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23345         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23346
23347         # find DoM files by layout
23348         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23349         [ $NUM -eq  $DOMFILES ] ||
23350                 error "lfs find -L: found $NUM, expected $DOMFILES"
23351         echo "Test 1: lfs find 20 DOM files by layout: OK"
23352
23353         # there should be 1 dir with default DOM striping
23354         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23355         [ $NUM -eq  1 ] ||
23356                 error "lfs find -L: found $NUM, expected 1 dir"
23357         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23358
23359         # find DoM files by stripe size
23360         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23361         [ $NUM -eq  $DOMFILES ] ||
23362                 error "lfs find -S: found $NUM, expected $DOMFILES"
23363         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23364
23365         # find files by stripe offset except DoM files
23366         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23367         [ $NUM -eq  $NORMFILES ] ||
23368                 error "lfs find -i: found $NUM, expected $NORMFILES"
23369         echo "Test 5: lfs find no DOM files by stripe index: OK"
23370         return 0
23371 }
23372 run_test 270e "DoM: lfs find with DoM files test"
23373
23374 test_270f() {
23375         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23376                 skip "Need MDS version at least 2.10.55"
23377
23378         local mdtname=${FSNAME}-MDT0000-mdtlov
23379         local dom=$DIR/$tdir/dom_file
23380         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23381                                                 lod.$mdtname.dom_stripesize)
23382         local dom_limit=131072
23383
23384         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23385         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23386                                                 lod.$mdtname.dom_stripesize)
23387         [ ${dom_limit} -eq ${dom_current} ] ||
23388                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23389
23390         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23391         $LFS setstripe -d $DIR/$tdir
23392         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23393                 error "Can't set directory default striping"
23394
23395         # exceed maximum stripe size
23396         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23397                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23398         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23399                 error "Able to create DoM component size more than LOD limit"
23400
23401         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23402         dom_current=$(do_facet mds1 $LCTL get_param -n \
23403                                                 lod.$mdtname.dom_stripesize)
23404         [ 0 -eq ${dom_current} ] ||
23405                 error "Can't set zero DoM stripe limit"
23406         rm $dom
23407
23408         # attempt to create DoM file on server with disabled DoM should
23409         # remove DoM entry from layout and be succeed
23410         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23411                 error "Can't create DoM file (DoM is disabled)"
23412         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23413                 error "File has DoM component while DoM is disabled"
23414         rm $dom
23415
23416         # attempt to create DoM file with only DoM stripe should return error
23417         $LFS setstripe -E $dom_limit -L mdt $dom &&
23418                 error "Able to create DoM-only file while DoM is disabled"
23419
23420         # too low values to be aligned with smallest stripe size 64K
23421         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23422         dom_current=$(do_facet mds1 $LCTL get_param -n \
23423                                                 lod.$mdtname.dom_stripesize)
23424         [ 30000 -eq ${dom_current} ] &&
23425                 error "Can set too small DoM stripe limit"
23426
23427         # 64K is a minimal stripe size in Lustre, expect limit of that size
23428         [ 65536 -eq ${dom_current} ] ||
23429                 error "Limit is not set to 64K but ${dom_current}"
23430
23431         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23432         dom_current=$(do_facet mds1 $LCTL get_param -n \
23433                                                 lod.$mdtname.dom_stripesize)
23434         echo $dom_current
23435         [ 2147483648 -eq ${dom_current} ] &&
23436                 error "Can set too large DoM stripe limit"
23437
23438         do_facet mds1 $LCTL set_param -n \
23439                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23440         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23441                 error "Can't create DoM component size after limit change"
23442         do_facet mds1 $LCTL set_param -n \
23443                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23444         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23445                 error "Can't create DoM file after limit decrease"
23446         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23447                 error "Can create big DoM component after limit decrease"
23448         touch ${dom}_def ||
23449                 error "Can't create file with old default layout"
23450
23451         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23452         return 0
23453 }
23454 run_test 270f "DoM: maximum DoM stripe size checks"
23455
23456 test_270g() {
23457         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23458                 skip "Need MDS version at least 2.13.52"
23459         local dom=$DIR/$tdir/$tfile
23460
23461         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23462         local lodname=${FSNAME}-MDT0000-mdtlov
23463
23464         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23465         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23466         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23467         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23468
23469         local dom_limit=1024
23470         local dom_threshold="50%"
23471
23472         $LFS setstripe -d $DIR/$tdir
23473         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23474                 error "Can't set directory default striping"
23475
23476         do_facet mds1 $LCTL set_param -n \
23477                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23478         # set 0 threshold and create DOM file to change tunable stripesize
23479         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23480         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23481                 error "Failed to create $dom file"
23482         # now tunable dom_cur_stripesize should reach maximum
23483         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23484                                         lod.${lodname}.dom_stripesize_cur_kb)
23485         [[ $dom_current == $dom_limit ]] ||
23486                 error "Current DOM stripesize is not maximum"
23487         rm $dom
23488
23489         # set threshold for further tests
23490         do_facet mds1 $LCTL set_param -n \
23491                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23492         echo "DOM threshold is $dom_threshold free space"
23493         local dom_def
23494         local dom_set
23495         # Spoof bfree to exceed threshold
23496         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23497         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23498         for spfree in 40 20 0 15 30 55; do
23499                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23500                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23501                         error "Failed to create $dom file"
23502                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23503                                         lod.${lodname}.dom_stripesize_cur_kb)
23504                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23505                 [[ $dom_def != $dom_current ]] ||
23506                         error "Default stripe size was not changed"
23507                 if (( spfree > 0 )) ; then
23508                         dom_set=$($LFS getstripe -S $dom)
23509                         (( dom_set == dom_def * 1024 )) ||
23510                                 error "DOM component size is still old"
23511                 else
23512                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23513                                 error "DoM component is set with no free space"
23514                 fi
23515                 rm $dom
23516                 dom_current=$dom_def
23517         done
23518 }
23519 run_test 270g "DoM: default DoM stripe size depends on free space"
23520
23521 test_270h() {
23522         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23523                 skip "Need MDS version at least 2.13.53"
23524
23525         local mdtname=${FSNAME}-MDT0000-mdtlov
23526         local dom=$DIR/$tdir/$tfile
23527         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23528
23529         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23530         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23531
23532         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23533         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23534                 error "can't create OST file"
23535         # mirrored file with DOM entry in the second mirror
23536         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23537                 error "can't create mirror with DoM component"
23538
23539         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23540
23541         # DOM component in the middle and has other enries in the same mirror,
23542         # should succeed but lost DoM component
23543         $LFS setstripe --copy=${dom}_1 $dom ||
23544                 error "Can't create file from OST|DOM mirror layout"
23545         # check new file has no DoM layout after all
23546         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23547                 error "File has DoM component while DoM is disabled"
23548 }
23549 run_test 270h "DoM: DoM stripe removal when disabled on server"
23550
23551 test_270i() {
23552         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23553                 skip "Need MDS version at least 2.14.54"
23554
23555         mkdir $DIR/$tdir
23556         # DoM with plain layout
23557         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23558                 error "default plain layout with DoM must fail"
23559         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23560                 error "setstripe plain file layout with DoM must fail"
23561         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23562                 error "default DoM layout with bad striping must fail"
23563         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23564                 error "setstripe to DoM layout with bad striping must fail"
23565         return 0
23566 }
23567 run_test 270i "DoM: setting invalid DoM striping should fail"
23568
23569 test_271a() {
23570         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23571                 skip "Need MDS version at least 2.10.55"
23572
23573         local dom=$DIR/$tdir/dom
23574
23575         mkdir -p $DIR/$tdir
23576
23577         $LFS setstripe -E 1024K -L mdt $dom
23578
23579         lctl set_param -n mdc.*.stats=clear
23580         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23581         cat $dom > /dev/null
23582         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23583         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23584         ls $dom
23585         rm -f $dom
23586 }
23587 run_test 271a "DoM: data is cached for read after write"
23588
23589 test_271b() {
23590         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23591                 skip "Need MDS version at least 2.10.55"
23592
23593         local dom=$DIR/$tdir/dom
23594
23595         mkdir -p $DIR/$tdir
23596
23597         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23598
23599         lctl set_param -n mdc.*.stats=clear
23600         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23601         cancel_lru_locks mdc
23602         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23603         # second stat to check size is cached on client
23604         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23605         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23606         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23607         rm -f $dom
23608 }
23609 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23610
23611 test_271ba() {
23612         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23613                 skip "Need MDS version at least 2.10.55"
23614
23615         local dom=$DIR/$tdir/dom
23616
23617         mkdir -p $DIR/$tdir
23618
23619         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23620
23621         lctl set_param -n mdc.*.stats=clear
23622         lctl set_param -n osc.*.stats=clear
23623         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23624         cancel_lru_locks mdc
23625         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23626         # second stat to check size is cached on client
23627         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23628         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23629         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23630         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23631         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23632         rm -f $dom
23633 }
23634 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23635
23636
23637 get_mdc_stats() {
23638         local mdtidx=$1
23639         local param=$2
23640         local mdt=MDT$(printf %04x $mdtidx)
23641
23642         if [ -z $param ]; then
23643                 lctl get_param -n mdc.*$mdt*.stats
23644         else
23645                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23646         fi
23647 }
23648
23649 test_271c() {
23650         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23651                 skip "Need MDS version at least 2.10.55"
23652
23653         local dom=$DIR/$tdir/dom
23654
23655         mkdir -p $DIR/$tdir
23656
23657         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23658
23659         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23660         local facet=mds$((mdtidx + 1))
23661
23662         cancel_lru_locks mdc
23663         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23664         createmany -o $dom 1000
23665         lctl set_param -n mdc.*.stats=clear
23666         smalliomany -w $dom 1000 200
23667         get_mdc_stats $mdtidx
23668         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23669         # Each file has 1 open, 1 IO enqueues, total 2000
23670         # but now we have also +1 getxattr for security.capability, total 3000
23671         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23672         unlinkmany $dom 1000
23673
23674         cancel_lru_locks mdc
23675         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23676         createmany -o $dom 1000
23677         lctl set_param -n mdc.*.stats=clear
23678         smalliomany -w $dom 1000 200
23679         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23680         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23681         # for OPEN and IO lock.
23682         [ $((enq - enq_2)) -ge 1000 ] ||
23683                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23684         unlinkmany $dom 1000
23685         return 0
23686 }
23687 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23688
23689 cleanup_271def_tests() {
23690         trap 0
23691         rm -f $1
23692 }
23693
23694 test_271d() {
23695         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23696                 skip "Need MDS version at least 2.10.57"
23697
23698         local dom=$DIR/$tdir/dom
23699         local tmp=$TMP/$tfile
23700         trap "cleanup_271def_tests $tmp" EXIT
23701
23702         mkdir -p $DIR/$tdir
23703
23704         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23705
23706         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23707
23708         cancel_lru_locks mdc
23709         dd if=/dev/urandom of=$tmp bs=1000 count=1
23710         dd if=$tmp of=$dom bs=1000 count=1
23711         cancel_lru_locks mdc
23712
23713         cat /etc/hosts >> $tmp
23714         lctl set_param -n mdc.*.stats=clear
23715
23716         # append data to the same file it should update local page
23717         echo "Append to the same page"
23718         cat /etc/hosts >> $dom
23719         local num=$(get_mdc_stats $mdtidx ost_read)
23720         local ra=$(get_mdc_stats $mdtidx req_active)
23721         local rw=$(get_mdc_stats $mdtidx req_waittime)
23722
23723         [ -z $num ] || error "$num READ RPC occured"
23724         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23725         echo "... DONE"
23726
23727         # compare content
23728         cmp $tmp $dom || error "file miscompare"
23729
23730         cancel_lru_locks mdc
23731         lctl set_param -n mdc.*.stats=clear
23732
23733         echo "Open and read file"
23734         cat $dom > /dev/null
23735         local num=$(get_mdc_stats $mdtidx ost_read)
23736         local ra=$(get_mdc_stats $mdtidx req_active)
23737         local rw=$(get_mdc_stats $mdtidx req_waittime)
23738
23739         [ -z $num ] || error "$num READ RPC occured"
23740         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23741         echo "... DONE"
23742
23743         # compare content
23744         cmp $tmp $dom || error "file miscompare"
23745
23746         return 0
23747 }
23748 run_test 271d "DoM: read on open (1K file in reply buffer)"
23749
23750 test_271f() {
23751         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23752                 skip "Need MDS version at least 2.10.57"
23753
23754         local dom=$DIR/$tdir/dom
23755         local tmp=$TMP/$tfile
23756         trap "cleanup_271def_tests $tmp" EXIT
23757
23758         mkdir -p $DIR/$tdir
23759
23760         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23761
23762         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23763
23764         cancel_lru_locks mdc
23765         dd if=/dev/urandom of=$tmp bs=265000 count=1
23766         dd if=$tmp of=$dom bs=265000 count=1
23767         cancel_lru_locks mdc
23768         cat /etc/hosts >> $tmp
23769         lctl set_param -n mdc.*.stats=clear
23770
23771         echo "Append to the same page"
23772         cat /etc/hosts >> $dom
23773         local num=$(get_mdc_stats $mdtidx ost_read)
23774         local ra=$(get_mdc_stats $mdtidx req_active)
23775         local rw=$(get_mdc_stats $mdtidx req_waittime)
23776
23777         [ -z $num ] || error "$num READ RPC occured"
23778         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23779         echo "... DONE"
23780
23781         # compare content
23782         cmp $tmp $dom || error "file miscompare"
23783
23784         cancel_lru_locks mdc
23785         lctl set_param -n mdc.*.stats=clear
23786
23787         echo "Open and read file"
23788         cat $dom > /dev/null
23789         local num=$(get_mdc_stats $mdtidx ost_read)
23790         local ra=$(get_mdc_stats $mdtidx req_active)
23791         local rw=$(get_mdc_stats $mdtidx req_waittime)
23792
23793         [ -z $num ] && num=0
23794         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23795         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23796         echo "... DONE"
23797
23798         # compare content
23799         cmp $tmp $dom || error "file miscompare"
23800
23801         return 0
23802 }
23803 run_test 271f "DoM: read on open (200K file and read tail)"
23804
23805 test_271g() {
23806         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23807                 skip "Skipping due to old client or server version"
23808
23809         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23810         # to get layout
23811         $CHECKSTAT -t file $DIR1/$tfile
23812
23813         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23814         MULTIOP_PID=$!
23815         sleep 1
23816         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23817         $LCTL set_param fail_loc=0x80000314
23818         rm $DIR1/$tfile || error "Unlink fails"
23819         RC=$?
23820         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23821         [ $RC -eq 0 ] || error "Failed write to stale object"
23822 }
23823 run_test 271g "Discard DoM data vs client flush race"
23824
23825 test_272a() {
23826         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23827                 skip "Need MDS version at least 2.11.50"
23828
23829         local dom=$DIR/$tdir/dom
23830         mkdir -p $DIR/$tdir
23831
23832         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23833         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23834                 error "failed to write data into $dom"
23835         local old_md5=$(md5sum $dom)
23836
23837         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23838                 error "failed to migrate to the same DoM component"
23839
23840         local new_md5=$(md5sum $dom)
23841
23842         [ "$old_md5" == "$new_md5" ] ||
23843                 error "md5sum differ: $old_md5, $new_md5"
23844
23845         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23846                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23847 }
23848 run_test 272a "DoM migration: new layout with the same DOM component"
23849
23850 test_272b() {
23851         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23852                 skip "Need MDS version at least 2.11.50"
23853
23854         local dom=$DIR/$tdir/dom
23855         mkdir -p $DIR/$tdir
23856         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23857
23858         local mdtidx=$($LFS getstripe -m $dom)
23859         local mdtname=MDT$(printf %04x $mdtidx)
23860         local facet=mds$((mdtidx + 1))
23861
23862         local mdtfree1=$(do_facet $facet \
23863                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23864         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23865                 error "failed to write data into $dom"
23866         local old_md5=$(md5sum $dom)
23867         cancel_lru_locks mdc
23868         local mdtfree1=$(do_facet $facet \
23869                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23870
23871         $LFS migrate -c2 $dom ||
23872                 error "failed to migrate to the new composite layout"
23873         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23874                 error "MDT stripe was not removed"
23875
23876         cancel_lru_locks mdc
23877         local new_md5=$(md5sum $dom)
23878         [ "$old_md5" == "$new_md5" ] ||
23879                 error "$old_md5 != $new_md5"
23880
23881         # Skip free space checks with ZFS
23882         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23883                 local mdtfree2=$(do_facet $facet \
23884                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23885                 [ $mdtfree2 -gt $mdtfree1 ] ||
23886                         error "MDT space is not freed after migration"
23887         fi
23888         return 0
23889 }
23890 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23891
23892 test_272c() {
23893         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23894                 skip "Need MDS version at least 2.11.50"
23895
23896         local dom=$DIR/$tdir/$tfile
23897         mkdir -p $DIR/$tdir
23898         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23899
23900         local mdtidx=$($LFS getstripe -m $dom)
23901         local mdtname=MDT$(printf %04x $mdtidx)
23902         local facet=mds$((mdtidx + 1))
23903
23904         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23905                 error "failed to write data into $dom"
23906         local old_md5=$(md5sum $dom)
23907         cancel_lru_locks mdc
23908         local mdtfree1=$(do_facet $facet \
23909                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23910
23911         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23912                 error "failed to migrate to the new composite layout"
23913         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23914                 error "MDT stripe was not removed"
23915
23916         cancel_lru_locks mdc
23917         local new_md5=$(md5sum $dom)
23918         [ "$old_md5" == "$new_md5" ] ||
23919                 error "$old_md5 != $new_md5"
23920
23921         # Skip free space checks with ZFS
23922         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23923                 local mdtfree2=$(do_facet $facet \
23924                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23925                 [ $mdtfree2 -gt $mdtfree1 ] ||
23926                         error "MDS space is not freed after migration"
23927         fi
23928         return 0
23929 }
23930 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23931
23932 test_272d() {
23933         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23934                 skip "Need MDS version at least 2.12.55"
23935
23936         local dom=$DIR/$tdir/$tfile
23937         mkdir -p $DIR/$tdir
23938         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23939
23940         local mdtidx=$($LFS getstripe -m $dom)
23941         local mdtname=MDT$(printf %04x $mdtidx)
23942         local facet=mds$((mdtidx + 1))
23943
23944         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23945                 error "failed to write data into $dom"
23946         local old_md5=$(md5sum $dom)
23947         cancel_lru_locks mdc
23948         local mdtfree1=$(do_facet $facet \
23949                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23950
23951         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23952                 error "failed mirroring to the new composite layout"
23953         $LFS mirror resync $dom ||
23954                 error "failed mirror resync"
23955         $LFS mirror split --mirror-id 1 -d $dom ||
23956                 error "failed mirror split"
23957
23958         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23959                 error "MDT stripe was not removed"
23960
23961         cancel_lru_locks mdc
23962         local new_md5=$(md5sum $dom)
23963         [ "$old_md5" == "$new_md5" ] ||
23964                 error "$old_md5 != $new_md5"
23965
23966         # Skip free space checks with ZFS
23967         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23968                 local mdtfree2=$(do_facet $facet \
23969                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23970                 [ $mdtfree2 -gt $mdtfree1 ] ||
23971                         error "MDS space is not freed after DOM mirror deletion"
23972         fi
23973         return 0
23974 }
23975 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23976
23977 test_272e() {
23978         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23979                 skip "Need MDS version at least 2.12.55"
23980
23981         local dom=$DIR/$tdir/$tfile
23982         mkdir -p $DIR/$tdir
23983         $LFS setstripe -c 2 $dom
23984
23985         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23986                 error "failed to write data into $dom"
23987         local old_md5=$(md5sum $dom)
23988         cancel_lru_locks
23989
23990         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23991                 error "failed mirroring to the DOM layout"
23992         $LFS mirror resync $dom ||
23993                 error "failed mirror resync"
23994         $LFS mirror split --mirror-id 1 -d $dom ||
23995                 error "failed mirror split"
23996
23997         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
23998                 error "MDT stripe wasn't set"
23999
24000         cancel_lru_locks
24001         local new_md5=$(md5sum $dom)
24002         [ "$old_md5" == "$new_md5" ] ||
24003                 error "$old_md5 != $new_md5"
24004
24005         return 0
24006 }
24007 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24008
24009 test_272f() {
24010         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24011                 skip "Need MDS version at least 2.12.55"
24012
24013         local dom=$DIR/$tdir/$tfile
24014         mkdir -p $DIR/$tdir
24015         $LFS setstripe -c 2 $dom
24016
24017         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24018                 error "failed to write data into $dom"
24019         local old_md5=$(md5sum $dom)
24020         cancel_lru_locks
24021
24022         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24023                 error "failed migrating to the DOM file"
24024
24025         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24026                 error "MDT stripe wasn't set"
24027
24028         cancel_lru_locks
24029         local new_md5=$(md5sum $dom)
24030         [ "$old_md5" != "$new_md5" ] &&
24031                 error "$old_md5 != $new_md5"
24032
24033         return 0
24034 }
24035 run_test 272f "DoM migration: OST-striped file to DOM file"
24036
24037 test_273a() {
24038         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24039                 skip "Need MDS version at least 2.11.50"
24040
24041         # Layout swap cannot be done if either file has DOM component,
24042         # this will never be supported, migration should be used instead
24043
24044         local dom=$DIR/$tdir/$tfile
24045         mkdir -p $DIR/$tdir
24046
24047         $LFS setstripe -c2 ${dom}_plain
24048         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24049         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24050                 error "can swap layout with DoM component"
24051         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24052                 error "can swap layout with DoM component"
24053
24054         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24055         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24056                 error "can swap layout with DoM component"
24057         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24058                 error "can swap layout with DoM component"
24059         return 0
24060 }
24061 run_test 273a "DoM: layout swapping should fail with DOM"
24062
24063 test_273b() {
24064         mkdir -p $DIR/$tdir
24065         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24066
24067 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24068         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24069
24070         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24071 }
24072 run_test 273b "DoM: race writeback and object destroy"
24073
24074 test_273c() {
24075         mkdir -p $DIR/$tdir
24076         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24077
24078         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24079         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24080
24081         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24082 }
24083 run_test 273c "race writeback and object destroy"
24084
24085 test_275() {
24086         remote_ost_nodsh && skip "remote OST with nodsh"
24087         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24088                 skip "Need OST version >= 2.10.57"
24089
24090         local file=$DIR/$tfile
24091         local oss
24092
24093         oss=$(comma_list $(osts_nodes))
24094
24095         dd if=/dev/urandom of=$file bs=1M count=2 ||
24096                 error "failed to create a file"
24097         cancel_lru_locks osc
24098
24099         #lock 1
24100         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24101                 error "failed to read a file"
24102
24103 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24104         $LCTL set_param fail_loc=0x8000031f
24105
24106         cancel_lru_locks osc &
24107         sleep 1
24108
24109 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24110         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24111         #IO takes another lock, but matches the PENDING one
24112         #and places it to the IO RPC
24113         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24114                 error "failed to read a file with PENDING lock"
24115 }
24116 run_test 275 "Read on a canceled duplicate lock"
24117
24118 test_276() {
24119         remote_ost_nodsh && skip "remote OST with nodsh"
24120         local pid
24121
24122         do_facet ost1 "(while true; do \
24123                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24124                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24125         pid=$!
24126
24127         for LOOP in $(seq 20); do
24128                 stop ost1
24129                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24130         done
24131         kill -9 $pid
24132         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24133                 rm $TMP/sanity_276_pid"
24134 }
24135 run_test 276 "Race between mount and obd_statfs"
24136
24137 test_277() {
24138         $LCTL set_param ldlm.namespaces.*.lru_size=0
24139         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24140         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24141                         grep ^used_mb | awk '{print $2}')
24142         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24143         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24144                 oflag=direct conv=notrunc
24145         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24146                         grep ^used_mb | awk '{print $2}')
24147         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24148 }
24149 run_test 277 "Direct IO shall drop page cache"
24150
24151 test_278() {
24152         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24153         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24154         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24155                 skip "needs the same host for mdt1 mdt2" && return
24156
24157         local pid1
24158         local pid2
24159
24160 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24161         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24162         stop mds2 &
24163         pid2=$!
24164
24165         stop mds1
24166
24167         echo "Starting MDTs"
24168         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24169         wait $pid2
24170 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24171 #will return NULL
24172         do_facet mds2 $LCTL set_param fail_loc=0
24173
24174         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24175         wait_recovery_complete mds2
24176 }
24177 run_test 278 "Race starting MDS between MDTs stop/start"
24178
24179 test_280() {
24180         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24181                 skip "Need MGS version at least 2.13.52"
24182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24183         combined_mgs_mds || skip "needs combined MGS/MDT"
24184
24185         umount_client $MOUNT
24186 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24187         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24188
24189         mount_client $MOUNT &
24190         sleep 1
24191         stop mgs || error "stop mgs failed"
24192         #for a race mgs would crash
24193         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24194         # make sure we unmount client before remounting
24195         wait
24196         umount_client $MOUNT
24197         mount_client $MOUNT || error "mount client failed"
24198 }
24199 run_test 280 "Race between MGS umount and client llog processing"
24200
24201 cleanup_test_300() {
24202         trap 0
24203         umask $SAVE_UMASK
24204 }
24205 test_striped_dir() {
24206         local mdt_index=$1
24207         local stripe_count
24208         local stripe_index
24209
24210         mkdir -p $DIR/$tdir
24211
24212         SAVE_UMASK=$(umask)
24213         trap cleanup_test_300 RETURN EXIT
24214
24215         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24216                                                 $DIR/$tdir/striped_dir ||
24217                 error "set striped dir error"
24218
24219         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24220         [ "$mode" = "755" ] || error "expect 755 got $mode"
24221
24222         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24223                 error "getdirstripe failed"
24224         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24225         if [ "$stripe_count" != "2" ]; then
24226                 error "1:stripe_count is $stripe_count, expect 2"
24227         fi
24228         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24229         if [ "$stripe_count" != "2" ]; then
24230                 error "2:stripe_count is $stripe_count, expect 2"
24231         fi
24232
24233         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24234         if [ "$stripe_index" != "$mdt_index" ]; then
24235                 error "stripe_index is $stripe_index, expect $mdt_index"
24236         fi
24237
24238         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24239                 error "nlink error after create striped dir"
24240
24241         mkdir $DIR/$tdir/striped_dir/a
24242         mkdir $DIR/$tdir/striped_dir/b
24243
24244         stat $DIR/$tdir/striped_dir/a ||
24245                 error "create dir under striped dir failed"
24246         stat $DIR/$tdir/striped_dir/b ||
24247                 error "create dir under striped dir failed"
24248
24249         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24250                 error "nlink error after mkdir"
24251
24252         rmdir $DIR/$tdir/striped_dir/a
24253         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24254                 error "nlink error after rmdir"
24255
24256         rmdir $DIR/$tdir/striped_dir/b
24257         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24258                 error "nlink error after rmdir"
24259
24260         chattr +i $DIR/$tdir/striped_dir
24261         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24262                 error "immutable flags not working under striped dir!"
24263         chattr -i $DIR/$tdir/striped_dir
24264
24265         rmdir $DIR/$tdir/striped_dir ||
24266                 error "rmdir striped dir error"
24267
24268         cleanup_test_300
24269
24270         true
24271 }
24272
24273 test_300a() {
24274         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24275                 skip "skipped for lustre < 2.7.0"
24276         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24277         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24278
24279         test_striped_dir 0 || error "failed on striped dir on MDT0"
24280         test_striped_dir 1 || error "failed on striped dir on MDT0"
24281 }
24282 run_test 300a "basic striped dir sanity test"
24283
24284 test_300b() {
24285         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24286                 skip "skipped for lustre < 2.7.0"
24287         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24288         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24289
24290         local i
24291         local mtime1
24292         local mtime2
24293         local mtime3
24294
24295         test_mkdir $DIR/$tdir || error "mkdir fail"
24296         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24297                 error "set striped dir error"
24298         for i in {0..9}; do
24299                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24300                 sleep 1
24301                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24302                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24303                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24304                 sleep 1
24305                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24306                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24307                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24308         done
24309         true
24310 }
24311 run_test 300b "check ctime/mtime for striped dir"
24312
24313 test_300c() {
24314         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24315                 skip "skipped for lustre < 2.7.0"
24316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24317         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24318
24319         local file_count
24320
24321         mkdir_on_mdt0 $DIR/$tdir
24322         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24323                 error "set striped dir error"
24324
24325         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24326                 error "chown striped dir failed"
24327
24328         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24329                 error "create 5k files failed"
24330
24331         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24332
24333         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24334
24335         rm -rf $DIR/$tdir
24336 }
24337 run_test 300c "chown && check ls under striped directory"
24338
24339 test_300d() {
24340         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24341                 skip "skipped for lustre < 2.7.0"
24342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24343         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24344
24345         local stripe_count
24346         local file
24347
24348         mkdir -p $DIR/$tdir
24349         $LFS setstripe -c 2 $DIR/$tdir
24350
24351         #local striped directory
24352         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24353                 error "set striped dir error"
24354         #look at the directories for debug purposes
24355         ls -l $DIR/$tdir
24356         $LFS getdirstripe $DIR/$tdir
24357         ls -l $DIR/$tdir/striped_dir
24358         $LFS getdirstripe $DIR/$tdir/striped_dir
24359         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24360                 error "create 10 files failed"
24361
24362         #remote striped directory
24363         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24364                 error "set striped dir error"
24365         #look at the directories for debug purposes
24366         ls -l $DIR/$tdir
24367         $LFS getdirstripe $DIR/$tdir
24368         ls -l $DIR/$tdir/remote_striped_dir
24369         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24370         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24371                 error "create 10 files failed"
24372
24373         for file in $(find $DIR/$tdir); do
24374                 stripe_count=$($LFS getstripe -c $file)
24375                 [ $stripe_count -eq 2 ] ||
24376                         error "wrong stripe $stripe_count for $file"
24377         done
24378
24379         rm -rf $DIR/$tdir
24380 }
24381 run_test 300d "check default stripe under striped directory"
24382
24383 test_300e() {
24384         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24385                 skip "Need MDS version at least 2.7.55"
24386         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24387         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24388
24389         local stripe_count
24390         local file
24391
24392         mkdir -p $DIR/$tdir
24393
24394         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24395                 error "set striped dir error"
24396
24397         touch $DIR/$tdir/striped_dir/a
24398         touch $DIR/$tdir/striped_dir/b
24399         touch $DIR/$tdir/striped_dir/c
24400
24401         mkdir $DIR/$tdir/striped_dir/dir_a
24402         mkdir $DIR/$tdir/striped_dir/dir_b
24403         mkdir $DIR/$tdir/striped_dir/dir_c
24404
24405         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24406                 error "set striped adir under striped dir error"
24407
24408         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24409                 error "set striped bdir under striped dir error"
24410
24411         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24412                 error "set striped cdir under striped dir error"
24413
24414         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24415                 error "rename dir under striped dir fails"
24416
24417         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24418                 error "rename dir under different stripes fails"
24419
24420         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24421                 error "rename file under striped dir should succeed"
24422
24423         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24424                 error "rename dir under striped dir should succeed"
24425
24426         rm -rf $DIR/$tdir
24427 }
24428 run_test 300e "check rename under striped directory"
24429
24430 test_300f() {
24431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24432         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24433         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24434                 skip "Need MDS version at least 2.7.55"
24435
24436         local stripe_count
24437         local file
24438
24439         rm -rf $DIR/$tdir
24440         mkdir -p $DIR/$tdir
24441
24442         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24443                 error "set striped dir error"
24444
24445         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24446                 error "set striped dir error"
24447
24448         touch $DIR/$tdir/striped_dir/a
24449         mkdir $DIR/$tdir/striped_dir/dir_a
24450         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24451                 error "create striped dir under striped dir fails"
24452
24453         touch $DIR/$tdir/striped_dir1/b
24454         mkdir $DIR/$tdir/striped_dir1/dir_b
24455         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24456                 error "create striped dir under striped dir fails"
24457
24458         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24459                 error "rename dir under different striped dir should fail"
24460
24461         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24462                 error "rename striped dir under diff striped dir should fail"
24463
24464         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24465                 error "rename file under diff striped dirs fails"
24466
24467         rm -rf $DIR/$tdir
24468 }
24469 run_test 300f "check rename cross striped directory"
24470
24471 test_300_check_default_striped_dir()
24472 {
24473         local dirname=$1
24474         local default_count=$2
24475         local default_index=$3
24476         local stripe_count
24477         local stripe_index
24478         local dir_stripe_index
24479         local dir
24480
24481         echo "checking $dirname $default_count $default_index"
24482         $LFS setdirstripe -D -c $default_count -i $default_index \
24483                                 -H all_char $DIR/$tdir/$dirname ||
24484                 error "set default stripe on striped dir error"
24485         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24486         [ $stripe_count -eq $default_count ] ||
24487                 error "expect $default_count get $stripe_count for $dirname"
24488
24489         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24490         [ $stripe_index -eq $default_index ] ||
24491                 error "expect $default_index get $stripe_index for $dirname"
24492
24493         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24494                                                 error "create dirs failed"
24495
24496         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24497         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24498         for dir in $(find $DIR/$tdir/$dirname/*); do
24499                 stripe_count=$($LFS getdirstripe -c $dir)
24500                 (( $stripe_count == $default_count )) ||
24501                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24502                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24503                 error "stripe count $default_count != $stripe_count for $dir"
24504
24505                 stripe_index=$($LFS getdirstripe -i $dir)
24506                 [ $default_index -eq -1 ] ||
24507                         [ $stripe_index -eq $default_index ] ||
24508                         error "$stripe_index != $default_index for $dir"
24509
24510                 #check default stripe
24511                 stripe_count=$($LFS getdirstripe -D -c $dir)
24512                 [ $stripe_count -eq $default_count ] ||
24513                 error "default count $default_count != $stripe_count for $dir"
24514
24515                 stripe_index=$($LFS getdirstripe -D -i $dir)
24516                 [ $stripe_index -eq $default_index ] ||
24517                 error "default index $default_index != $stripe_index for $dir"
24518         done
24519         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24520 }
24521
24522 test_300g() {
24523         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24524         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24525                 skip "Need MDS version at least 2.7.55"
24526
24527         local dir
24528         local stripe_count
24529         local stripe_index
24530
24531         mkdir_on_mdt0 $DIR/$tdir
24532         mkdir $DIR/$tdir/normal_dir
24533
24534         #Checking when client cache stripe index
24535         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24536         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24537                 error "create striped_dir failed"
24538
24539         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24540                 error "create dir0 fails"
24541         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24542         [ $stripe_index -eq 0 ] ||
24543                 error "dir0 expect index 0 got $stripe_index"
24544
24545         mkdir $DIR/$tdir/striped_dir/dir1 ||
24546                 error "create dir1 fails"
24547         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24548         [ $stripe_index -eq 1 ] ||
24549                 error "dir1 expect index 1 got $stripe_index"
24550
24551         #check default stripe count/stripe index
24552         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24553         test_300_check_default_striped_dir normal_dir 1 0
24554         test_300_check_default_striped_dir normal_dir -1 1
24555         test_300_check_default_striped_dir normal_dir 2 -1
24556
24557         #delete default stripe information
24558         echo "delete default stripeEA"
24559         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24560                 error "set default stripe on striped dir error"
24561
24562         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24563         for dir in $(find $DIR/$tdir/normal_dir/*); do
24564                 stripe_count=$($LFS getdirstripe -c $dir)
24565                 [ $stripe_count -eq 0 ] ||
24566                         error "expect 1 get $stripe_count for $dir"
24567         done
24568 }
24569 run_test 300g "check default striped directory for normal directory"
24570
24571 test_300h() {
24572         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24573         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24574                 skip "Need MDS version at least 2.7.55"
24575
24576         local dir
24577         local stripe_count
24578
24579         mkdir $DIR/$tdir
24580         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24581                 error "set striped dir error"
24582
24583         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24584         test_300_check_default_striped_dir striped_dir 1 0
24585         test_300_check_default_striped_dir striped_dir -1 1
24586         test_300_check_default_striped_dir striped_dir 2 -1
24587
24588         #delete default stripe information
24589         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24590                 error "set default stripe on striped dir error"
24591
24592         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24593         for dir in $(find $DIR/$tdir/striped_dir/*); do
24594                 stripe_count=$($LFS getdirstripe -c $dir)
24595                 [ $stripe_count -eq 0 ] ||
24596                         error "expect 1 get $stripe_count for $dir"
24597         done
24598 }
24599 run_test 300h "check default striped directory for striped directory"
24600
24601 test_300i() {
24602         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24603         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24604         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24605                 skip "Need MDS version at least 2.7.55"
24606
24607         local stripe_count
24608         local file
24609
24610         mkdir $DIR/$tdir
24611
24612         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24613                 error "set striped dir error"
24614
24615         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24616                 error "create files under striped dir failed"
24617
24618         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24619                 error "set striped hashdir error"
24620
24621         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24622                 error "create dir0 under hash dir failed"
24623         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24624                 error "create dir1 under hash dir failed"
24625         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24626                 error "create dir2 under hash dir failed"
24627
24628         # unfortunately, we need to umount to clear dir layout cache for now
24629         # once we fully implement dir layout, we can drop this
24630         umount_client $MOUNT || error "umount failed"
24631         mount_client $MOUNT || error "mount failed"
24632
24633         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24634         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24635         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24636
24637         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24638                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24639                         error "create crush2 dir $tdir/hashdir/d3 failed"
24640                 $LFS find -H crush2 $DIR/$tdir/hashdir
24641                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24642                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24643
24644                 # mkdir with an invalid hash type (hash=fail_val) from client
24645                 # should be replaced on MDS with a valid (default) hash type
24646                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24647                 $LCTL set_param fail_loc=0x1901 fail_val=99
24648                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24649
24650                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24651                 local expect=$(do_facet mds1 \
24652                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24653                 [[ $hash == $expect ]] ||
24654                         error "d99 hash '$hash' != expected hash '$expect'"
24655         fi
24656
24657         #set the stripe to be unknown hash type on read
24658         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24659         $LCTL set_param fail_loc=0x1901 fail_val=99
24660         for ((i = 0; i < 10; i++)); do
24661                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24662                         error "stat f-$i failed"
24663                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24664         done
24665
24666         touch $DIR/$tdir/striped_dir/f0 &&
24667                 error "create under striped dir with unknown hash should fail"
24668
24669         $LCTL set_param fail_loc=0
24670
24671         umount_client $MOUNT || error "umount failed"
24672         mount_client $MOUNT || error "mount failed"
24673
24674         return 0
24675 }
24676 run_test 300i "client handle unknown hash type striped directory"
24677
24678 test_300j() {
24679         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24680         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24681         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24682                 skip "Need MDS version at least 2.7.55"
24683
24684         local stripe_count
24685         local file
24686
24687         mkdir $DIR/$tdir
24688
24689         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24690         $LCTL set_param fail_loc=0x1702
24691         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24692                 error "set striped dir error"
24693
24694         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24695                 error "create files under striped dir failed"
24696
24697         $LCTL set_param fail_loc=0
24698
24699         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24700
24701         return 0
24702 }
24703 run_test 300j "test large update record"
24704
24705 test_300k() {
24706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24707         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24708         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24709                 skip "Need MDS version at least 2.7.55"
24710
24711         # this test needs a huge transaction
24712         local kb
24713         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24714              osd*.$FSNAME-MDT0000.kbytestotal")
24715         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24716
24717         local stripe_count
24718         local file
24719
24720         mkdir $DIR/$tdir
24721
24722         #define OBD_FAIL_LARGE_STRIPE   0x1703
24723         $LCTL set_param fail_loc=0x1703
24724         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24725                 error "set striped dir error"
24726         $LCTL set_param fail_loc=0
24727
24728         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24729                 error "getstripeddir fails"
24730         rm -rf $DIR/$tdir/striped_dir ||
24731                 error "unlink striped dir fails"
24732
24733         return 0
24734 }
24735 run_test 300k "test large striped directory"
24736
24737 test_300l() {
24738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24739         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24740         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24741                 skip "Need MDS version at least 2.7.55"
24742
24743         local stripe_index
24744
24745         test_mkdir -p $DIR/$tdir/striped_dir
24746         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24747                         error "chown $RUNAS_ID failed"
24748         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24749                 error "set default striped dir failed"
24750
24751         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24752         $LCTL set_param fail_loc=0x80000158
24753         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24754
24755         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24756         [ $stripe_index -eq 1 ] ||
24757                 error "expect 1 get $stripe_index for $dir"
24758 }
24759 run_test 300l "non-root user to create dir under striped dir with stale layout"
24760
24761 test_300m() {
24762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24763         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24764         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24765                 skip "Need MDS version at least 2.7.55"
24766
24767         mkdir -p $DIR/$tdir/striped_dir
24768         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24769                 error "set default stripes dir error"
24770
24771         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24772
24773         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24774         [ $stripe_count -eq 0 ] ||
24775                         error "expect 0 get $stripe_count for a"
24776
24777         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24778                 error "set default stripes dir error"
24779
24780         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24781
24782         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24783         [ $stripe_count -eq 0 ] ||
24784                         error "expect 0 get $stripe_count for b"
24785
24786         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24787                 error "set default stripes dir error"
24788
24789         mkdir $DIR/$tdir/striped_dir/c &&
24790                 error "default stripe_index is invalid, mkdir c should fails"
24791
24792         rm -rf $DIR/$tdir || error "rmdir fails"
24793 }
24794 run_test 300m "setstriped directory on single MDT FS"
24795
24796 cleanup_300n() {
24797         local list=$(comma_list $(mdts_nodes))
24798
24799         trap 0
24800         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24801 }
24802
24803 test_300n() {
24804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24805         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24806         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24807                 skip "Need MDS version at least 2.7.55"
24808         remote_mds_nodsh && skip "remote MDS with nodsh"
24809
24810         local stripe_index
24811         local list=$(comma_list $(mdts_nodes))
24812
24813         trap cleanup_300n RETURN EXIT
24814         mkdir -p $DIR/$tdir
24815         chmod 777 $DIR/$tdir
24816         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24817                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24818                 error "create striped dir succeeds with gid=0"
24819
24820         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24821         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24822                 error "create striped dir fails with gid=-1"
24823
24824         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24825         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24826                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24827                 error "set default striped dir succeeds with gid=0"
24828
24829
24830         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24831         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24832                 error "set default striped dir fails with gid=-1"
24833
24834
24835         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24836         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24837                                         error "create test_dir fails"
24838         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24839                                         error "create test_dir1 fails"
24840         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24841                                         error "create test_dir2 fails"
24842         cleanup_300n
24843 }
24844 run_test 300n "non-root user to create dir under striped dir with default EA"
24845
24846 test_300o() {
24847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24848         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24849         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24850                 skip "Need MDS version at least 2.7.55"
24851
24852         local numfree1
24853         local numfree2
24854
24855         mkdir -p $DIR/$tdir
24856
24857         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24858         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24859         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24860                 skip "not enough free inodes $numfree1 $numfree2"
24861         fi
24862
24863         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24864         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24865         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24866                 skip "not enough free space $numfree1 $numfree2"
24867         fi
24868
24869         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24870                 error "setdirstripe fails"
24871
24872         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24873                 error "create dirs fails"
24874
24875         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24876         ls $DIR/$tdir/striped_dir > /dev/null ||
24877                 error "ls striped dir fails"
24878         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24879                 error "unlink big striped dir fails"
24880 }
24881 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24882
24883 test_300p() {
24884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24885         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24886         remote_mds_nodsh && skip "remote MDS with nodsh"
24887
24888         mkdir_on_mdt0 $DIR/$tdir
24889
24890         #define OBD_FAIL_OUT_ENOSPC     0x1704
24891         do_facet mds2 lctl set_param fail_loc=0x80001704
24892         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24893                  && error "create striped directory should fail"
24894
24895         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24896
24897         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24898         true
24899 }
24900 run_test 300p "create striped directory without space"
24901
24902 test_300q() {
24903         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24904         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24905
24906         local fd=$(free_fd)
24907         local cmd="exec $fd<$tdir"
24908         cd $DIR
24909         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24910         eval $cmd
24911         cmd="exec $fd<&-"
24912         trap "eval $cmd" EXIT
24913         cd $tdir || error "cd $tdir fails"
24914         rmdir  ../$tdir || error "rmdir $tdir fails"
24915         mkdir local_dir && error "create dir succeeds"
24916         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24917         eval $cmd
24918         return 0
24919 }
24920 run_test 300q "create remote directory under orphan directory"
24921
24922 test_300r() {
24923         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24924                 skip "Need MDS version at least 2.7.55" && return
24925         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24926
24927         mkdir $DIR/$tdir
24928
24929         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24930                 error "set striped dir error"
24931
24932         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24933                 error "getstripeddir fails"
24934
24935         local stripe_count
24936         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24937                       awk '/lmv_stripe_count:/ { print $2 }')
24938
24939         [ $MDSCOUNT -ne $stripe_count ] &&
24940                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24941
24942         rm -rf $DIR/$tdir/striped_dir ||
24943                 error "unlink striped dir fails"
24944 }
24945 run_test 300r "test -1 striped directory"
24946
24947 test_300s_helper() {
24948         local count=$1
24949
24950         local stripe_dir=$DIR/$tdir/striped_dir.$count
24951
24952         $LFS mkdir -c $count $stripe_dir ||
24953                 error "lfs mkdir -c error"
24954
24955         $LFS getdirstripe $stripe_dir ||
24956                 error "lfs getdirstripe fails"
24957
24958         local stripe_count
24959         stripe_count=$($LFS getdirstripe $stripe_dir |
24960                       awk '/lmv_stripe_count:/ { print $2 }')
24961
24962         [ $count -ne $stripe_count ] &&
24963                 error_noexit "bad stripe count $stripe_count expected $count"
24964
24965         local dupe_stripes
24966         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24967                 awk '/0x/ {count[$1] += 1}; END {
24968                         for (idx in count) {
24969                                 if (count[idx]>1) {
24970                                         print "index " idx " count " count[idx]
24971                                 }
24972                         }
24973                 }')
24974
24975         if [[ -n "$dupe_stripes" ]] ; then
24976                 lfs getdirstripe $stripe_dir
24977                 error_noexit "Dupe MDT above: $dupe_stripes "
24978         fi
24979
24980         rm -rf $stripe_dir ||
24981                 error_noexit "unlink $stripe_dir fails"
24982 }
24983
24984 test_300s() {
24985         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24986                 skip "Need MDS version at least 2.7.55" && return
24987         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24988
24989         mkdir $DIR/$tdir
24990         for count in $(seq 2 $MDSCOUNT); do
24991                 test_300s_helper $count
24992         done
24993 }
24994 run_test 300s "test lfs mkdir -c without -i"
24995
24996 test_300t() {
24997         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
24998                 skip "need MDS 2.14.55 or later"
24999         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25000
25001         local testdir="$DIR/$tdir/striped_dir"
25002         local dir1=$testdir/dir1
25003         local dir2=$testdir/dir2
25004
25005         mkdir -p $testdir
25006
25007         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25008                 error "failed to set default stripe count for $testdir"
25009
25010         mkdir $dir1
25011         local stripe_count=$($LFS getdirstripe -c $dir1)
25012
25013         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25014
25015         local max_count=$((MDSCOUNT - 1))
25016         local mdts=$(comma_list $(mdts_nodes))
25017
25018         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25019         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25020
25021         mkdir $dir2
25022         stripe_count=$($LFS getdirstripe -c $dir2)
25023
25024         (( $stripe_count == $max_count )) || error "wrong stripe count"
25025 }
25026 run_test 300t "test max_mdt_stripecount"
25027
25028 prepare_remote_file() {
25029         mkdir $DIR/$tdir/src_dir ||
25030                 error "create remote source failed"
25031
25032         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25033                  error "cp to remote source failed"
25034         touch $DIR/$tdir/src_dir/a
25035
25036         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25037                 error "create remote target dir failed"
25038
25039         touch $DIR/$tdir/tgt_dir/b
25040
25041         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25042                 error "rename dir cross MDT failed!"
25043
25044         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25045                 error "src_child still exists after rename"
25046
25047         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25048                 error "missing file(a) after rename"
25049
25050         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25051                 error "diff after rename"
25052 }
25053
25054 test_310a() {
25055         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25056         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25057
25058         local remote_file=$DIR/$tdir/tgt_dir/b
25059
25060         mkdir -p $DIR/$tdir
25061
25062         prepare_remote_file || error "prepare remote file failed"
25063
25064         #open-unlink file
25065         $OPENUNLINK $remote_file $remote_file ||
25066                 error "openunlink $remote_file failed"
25067         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25068 }
25069 run_test 310a "open unlink remote file"
25070
25071 test_310b() {
25072         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25074
25075         local remote_file=$DIR/$tdir/tgt_dir/b
25076
25077         mkdir -p $DIR/$tdir
25078
25079         prepare_remote_file || error "prepare remote file failed"
25080
25081         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25082         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25083         $CHECKSTAT -t file $remote_file || error "check file failed"
25084 }
25085 run_test 310b "unlink remote file with multiple links while open"
25086
25087 test_310c() {
25088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25089         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25090
25091         local remote_file=$DIR/$tdir/tgt_dir/b
25092
25093         mkdir -p $DIR/$tdir
25094
25095         prepare_remote_file || error "prepare remote file failed"
25096
25097         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25098         multiop_bg_pause $remote_file O_uc ||
25099                         error "mulitop failed for remote file"
25100         MULTIPID=$!
25101         $MULTIOP $DIR/$tfile Ouc
25102         kill -USR1 $MULTIPID
25103         wait $MULTIPID
25104 }
25105 run_test 310c "open-unlink remote file with multiple links"
25106
25107 #LU-4825
25108 test_311() {
25109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25110         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25111         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25112                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25113         remote_mds_nodsh && skip "remote MDS with nodsh"
25114
25115         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25116         local mdts=$(comma_list $(mdts_nodes))
25117
25118         mkdir -p $DIR/$tdir
25119         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25120         createmany -o $DIR/$tdir/$tfile. 1000
25121
25122         # statfs data is not real time, let's just calculate it
25123         old_iused=$((old_iused + 1000))
25124
25125         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25126                         osp.*OST0000*MDT0000.create_count")
25127         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25128                                 osp.*OST0000*MDT0000.max_create_count")
25129         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25130
25131         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25132         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25133         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25134
25135         unlinkmany $DIR/$tdir/$tfile. 1000
25136
25137         do_nodes $mdts "$LCTL set_param -n \
25138                         osp.*OST0000*.max_create_count=$max_count"
25139         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25140                 do_nodes $mdts "$LCTL set_param -n \
25141                                 osp.*OST0000*.create_count=$count"
25142         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25143                         grep "=0" && error "create_count is zero"
25144
25145         local new_iused
25146         for i in $(seq 120); do
25147                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25148                 # system may be too busy to destroy all objs in time, use
25149                 # a somewhat small value to not fail autotest
25150                 [ $((old_iused - new_iused)) -gt 400 ] && break
25151                 sleep 1
25152         done
25153
25154         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25155         [ $((old_iused - new_iused)) -gt 400 ] ||
25156                 error "objs not destroyed after unlink"
25157 }
25158 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25159
25160 zfs_get_objid()
25161 {
25162         local ost=$1
25163         local tf=$2
25164         local fid=($($LFS getstripe $tf | grep 0x))
25165         local seq=${fid[3]#0x}
25166         local objid=${fid[1]}
25167
25168         local vdevdir=$(dirname $(facet_vdevice $ost))
25169         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25170         local zfs_zapid=$(do_facet $ost $cmd |
25171                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25172                           awk '/Object/{getline; print $1}')
25173         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25174                           awk "/$objid = /"'{printf $3}')
25175
25176         echo $zfs_objid
25177 }
25178
25179 zfs_object_blksz() {
25180         local ost=$1
25181         local objid=$2
25182
25183         local vdevdir=$(dirname $(facet_vdevice $ost))
25184         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25185         local blksz=$(do_facet $ost $cmd $objid |
25186                       awk '/dblk/{getline; printf $4}')
25187
25188         case "${blksz: -1}" in
25189                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25190                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25191                 *) ;;
25192         esac
25193
25194         echo $blksz
25195 }
25196
25197 test_312() { # LU-4856
25198         remote_ost_nodsh && skip "remote OST with nodsh"
25199         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25200
25201         local max_blksz=$(do_facet ost1 \
25202                           $ZFS get -p recordsize $(facet_device ost1) |
25203                           awk '!/VALUE/{print $3}')
25204         local tf=$DIR/$tfile
25205
25206         $LFS setstripe -c1 $tf
25207         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25208
25209         # Get ZFS object id
25210         local zfs_objid=$(zfs_get_objid $facet $tf)
25211         # block size change by sequential overwrite
25212         local bs
25213
25214         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25215                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25216
25217                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25218                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25219         done
25220         rm -f $tf
25221
25222         $LFS setstripe -c1 $tf
25223         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25224
25225         # block size change by sequential append write
25226         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25227         zfs_objid=$(zfs_get_objid $facet $tf)
25228         local count
25229
25230         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25231                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25232                         oflag=sync conv=notrunc
25233
25234                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25235                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25236                         error "blksz error, actual $blksz, " \
25237                                 "expected: 2 * $count * $PAGE_SIZE"
25238         done
25239         rm -f $tf
25240
25241         # random write
25242         $LFS setstripe -c1 $tf
25243         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25244         zfs_objid=$(zfs_get_objid $facet $tf)
25245
25246         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25247         blksz=$(zfs_object_blksz $facet $zfs_objid)
25248         (( blksz == PAGE_SIZE )) ||
25249                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25250
25251         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25252         blksz=$(zfs_object_blksz $facet $zfs_objid)
25253         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25254
25255         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25256         blksz=$(zfs_object_blksz $facet $zfs_objid)
25257         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25258 }
25259 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25260
25261 test_313() {
25262         remote_ost_nodsh && skip "remote OST with nodsh"
25263
25264         local file=$DIR/$tfile
25265
25266         rm -f $file
25267         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25268
25269         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25270         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25271         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25272                 error "write should failed"
25273         do_facet ost1 "$LCTL set_param fail_loc=0"
25274         rm -f $file
25275 }
25276 run_test 313 "io should fail after last_rcvd update fail"
25277
25278 test_314() {
25279         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25280
25281         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25282         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25283         rm -f $DIR/$tfile
25284         wait_delete_completed
25285         do_facet ost1 "$LCTL set_param fail_loc=0"
25286 }
25287 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25288
25289 test_315() { # LU-618
25290         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25291
25292         local file=$DIR/$tfile
25293         rm -f $file
25294
25295         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25296                 error "multiop file write failed"
25297         $MULTIOP $file oO_RDONLY:r4063232_c &
25298         PID=$!
25299
25300         sleep 2
25301
25302         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25303         kill -USR1 $PID
25304
25305         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25306         rm -f $file
25307 }
25308 run_test 315 "read should be accounted"
25309
25310 test_316() {
25311         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25312         large_xattr_enabled || skip "ea_inode feature disabled"
25313
25314         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25315         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25316         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25317         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25318
25319         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25320 }
25321 run_test 316 "lfs migrate of file with large_xattr enabled"
25322
25323 test_317() {
25324         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25325                 skip "Need MDS version at least 2.11.53"
25326         if [ "$ost1_FSTYPE" == "zfs" ]; then
25327                 skip "LU-10370: no implementation for ZFS"
25328         fi
25329
25330         local trunc_sz
25331         local grant_blk_size
25332
25333         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25334                         awk '/grant_block_size:/ { print $2; exit; }')
25335         #
25336         # Create File of size 5M. Truncate it to below size's and verify
25337         # blocks count.
25338         #
25339         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25340                 error "Create file $DIR/$tfile failed"
25341         stack_trap "rm -f $DIR/$tfile" EXIT
25342
25343         for trunc_sz in 2097152 4097 4000 509 0; do
25344                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25345                         error "truncate $tfile to $trunc_sz failed"
25346                 local sz=$(stat --format=%s $DIR/$tfile)
25347                 local blk=$(stat --format=%b $DIR/$tfile)
25348                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25349                                      grant_blk_size) * 8))
25350
25351                 if [[ $blk -ne $trunc_blk ]]; then
25352                         $(which stat) $DIR/$tfile
25353                         error "Expected Block $trunc_blk got $blk for $tfile"
25354                 fi
25355
25356                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25357                         error "Expected Size $trunc_sz got $sz for $tfile"
25358         done
25359
25360         #
25361         # sparse file test
25362         # Create file with a hole and write actual 65536 bytes which aligned
25363         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25364         #
25365         local bs=65536
25366         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25367                 error "Create file : $DIR/$tfile"
25368
25369         #
25370         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25371         # blocks. The block count must drop to 8.
25372         #
25373         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25374                 ((bs - grant_blk_size) + 1)))
25375         $TRUNCATE $DIR/$tfile $trunc_sz ||
25376                 error "truncate $tfile to $trunc_sz failed"
25377
25378         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25379         sz=$(stat --format=%s $DIR/$tfile)
25380         blk=$(stat --format=%b $DIR/$tfile)
25381
25382         if [[ $blk -ne $trunc_bsz ]]; then
25383                 $(which stat) $DIR/$tfile
25384                 error "Expected Block $trunc_bsz got $blk for $tfile"
25385         fi
25386
25387         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25388                 error "Expected Size $trunc_sz got $sz for $tfile"
25389 }
25390 run_test 317 "Verify blocks get correctly update after truncate"
25391
25392 test_318() {
25393         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25394         local old_max_active=$($LCTL get_param -n \
25395                             ${llite_name}.max_read_ahead_async_active \
25396                             2>/dev/null)
25397
25398         $LCTL set_param llite.*.max_read_ahead_async_active=256
25399         local max_active=$($LCTL get_param -n \
25400                            ${llite_name}.max_read_ahead_async_active \
25401                            2>/dev/null)
25402         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25403
25404         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25405                 error "set max_read_ahead_async_active should succeed"
25406
25407         $LCTL set_param llite.*.max_read_ahead_async_active=512
25408         max_active=$($LCTL get_param -n \
25409                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25410         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25411
25412         # restore @max_active
25413         [ $old_max_active -ne 0 ] && $LCTL set_param \
25414                 llite.*.max_read_ahead_async_active=$old_max_active
25415
25416         local old_threshold=$($LCTL get_param -n \
25417                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25418         local max_per_file_mb=$($LCTL get_param -n \
25419                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25420
25421         local invalid=$(($max_per_file_mb + 1))
25422         $LCTL set_param \
25423                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25424                         && error "set $invalid should fail"
25425
25426         local valid=$(($invalid - 1))
25427         $LCTL set_param \
25428                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25429                         error "set $valid should succeed"
25430         local threshold=$($LCTL get_param -n \
25431                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25432         [ $threshold -eq $valid ] || error \
25433                 "expect threshold $valid got $threshold"
25434         $LCTL set_param \
25435                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25436 }
25437 run_test 318 "Verify async readahead tunables"
25438
25439 test_319() {
25440         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25441
25442         local before=$(date +%s)
25443         local evict
25444         local mdir=$DIR/$tdir
25445         local file=$mdir/xxx
25446
25447         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25448         touch $file
25449
25450 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25451         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25452         $LFS migrate -m1 $mdir &
25453
25454         sleep 1
25455         dd if=$file of=/dev/null
25456         wait
25457         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25458           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25459
25460         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25461 }
25462 run_test 319 "lost lease lock on migrate error"
25463
25464 test_398a() { # LU-4198
25465         local ost1_imp=$(get_osc_import_name client ost1)
25466         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25467                          cut -d'.' -f2)
25468
25469         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25470         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25471
25472         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25473         # request a new lock on client
25474         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25475
25476         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25477         #local lock_count=$($LCTL get_param -n \
25478         #                  ldlm.namespaces.$imp_name.lru_size)
25479         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25480
25481         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25482
25483         # no lock cached, should use lockless DIO and not enqueue new lock
25484         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25485                 conv=notrunc ||
25486                 error "dio write failed"
25487         lock_count=$($LCTL get_param -n \
25488                      ldlm.namespaces.$imp_name.lru_size)
25489         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25490
25491         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25492
25493         # no lock cached, should use locked DIO append
25494         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25495                 conv=notrunc || error "DIO append failed"
25496         lock_count=$($LCTL get_param -n \
25497                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25498         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25499 }
25500 run_test 398a "direct IO should cancel lock otherwise lockless"
25501
25502 test_398b() { # LU-4198
25503         local before=$(date +%s)
25504         local njobs=4
25505         local size=48
25506
25507         which fio || skip_env "no fio installed"
25508         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25509         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25510
25511         # Single page, multiple pages, stripe size, 4*stripe size
25512         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25513                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25514                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25515                         --numjobs=$njobs --fallocate=none \
25516                         --iodepth=16 --allow_file_create=0 \
25517                         --size=$((size/njobs))M \
25518                         --filename=$DIR/$tfile &
25519                 bg_pid=$!
25520
25521                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25522                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25523                         --numjobs=$njobs --fallocate=none \
25524                         --iodepth=16 --allow_file_create=0 \
25525                         --size=$((size/njobs))M \
25526                         --filename=$DIR/$tfile || true
25527                 wait $bg_pid
25528         done
25529
25530         evict=$(do_facet client $LCTL get_param \
25531                 osc.$FSNAME-OST*-osc-*/state |
25532             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25533
25534         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25535                 (do_facet client $LCTL get_param \
25536                         osc.$FSNAME-OST*-osc-*/state;
25537                     error "eviction happened: $evict before:$before")
25538
25539         rm -f $DIR/$tfile
25540 }
25541 run_test 398b "DIO and buffer IO race"
25542
25543 test_398c() { # LU-4198
25544         local ost1_imp=$(get_osc_import_name client ost1)
25545         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25546                          cut -d'.' -f2)
25547
25548         which fio || skip_env "no fio installed"
25549
25550         saved_debug=$($LCTL get_param -n debug)
25551         $LCTL set_param debug=0
25552
25553         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25554         ((size /= 1024)) # by megabytes
25555         ((size /= 2)) # write half of the OST at most
25556         [ $size -gt 40 ] && size=40 #reduce test time anyway
25557
25558         $LFS setstripe -c 1 $DIR/$tfile
25559
25560         # it seems like ldiskfs reserves more space than necessary if the
25561         # writing blocks are not mapped, so it extends the file firstly
25562         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25563         cancel_lru_locks osc
25564
25565         # clear and verify rpc_stats later
25566         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25567
25568         local njobs=4
25569         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25570         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25571                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25572                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25573                 --filename=$DIR/$tfile
25574         [ $? -eq 0 ] || error "fio write error"
25575
25576         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25577                 error "Locks were requested while doing AIO"
25578
25579         # get the percentage of 1-page I/O
25580         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25581                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25582                 awk '{print $7}')
25583         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25584
25585         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25586         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25587                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25588                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25589                 --filename=$DIR/$tfile
25590         [ $? -eq 0 ] || error "fio mixed read write error"
25591
25592         echo "AIO with large block size ${size}M"
25593         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25594                 --numjobs=1 --fallocate=none --ioengine=libaio \
25595                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25596                 --filename=$DIR/$tfile
25597         [ $? -eq 0 ] || error "fio large block size failed"
25598
25599         rm -f $DIR/$tfile
25600         $LCTL set_param debug="$saved_debug"
25601 }
25602 run_test 398c "run fio to test AIO"
25603
25604 test_398d() { #  LU-13846
25605         which aiocp || skip_env "no aiocp installed"
25606         local aio_file=$DIR/$tfile.aio
25607
25608         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25609
25610         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25611         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25612         stack_trap "rm -f $DIR/$tfile $aio_file"
25613
25614         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25615
25616         # make sure we don't crash and fail properly
25617         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25618                 error "aio not aligned with PAGE SIZE should fail"
25619
25620         rm -f $DIR/$tfile $aio_file
25621 }
25622 run_test 398d "run aiocp to verify block size > stripe size"
25623
25624 test_398e() {
25625         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25626         touch $DIR/$tfile.new
25627         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25628 }
25629 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25630
25631 test_398f() { #  LU-14687
25632         which aiocp || skip_env "no aiocp installed"
25633         local aio_file=$DIR/$tfile.aio
25634
25635         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25636
25637         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25638         stack_trap "rm -f $DIR/$tfile $aio_file"
25639
25640         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25641         $LCTL set_param fail_loc=0x1418
25642         # make sure we don't crash and fail properly
25643         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25644                 error "aio with page allocation failure succeeded"
25645         $LCTL set_param fail_loc=0
25646         diff $DIR/$tfile $aio_file
25647         [[ $? != 0 ]] || error "no diff after failed aiocp"
25648 }
25649 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25650
25651 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25652 # stripe and i/o size must be > stripe size
25653 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25654 # single RPC in flight.  This test shows async DIO submission is working by
25655 # showing multiple RPCs in flight.
25656 test_398g() { #  LU-13798
25657         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25658
25659         # We need to do some i/o first to acquire enough grant to put our RPCs
25660         # in flight; otherwise a new connection may not have enough grant
25661         # available
25662         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25663                 error "parallel dio failed"
25664         stack_trap "rm -f $DIR/$tfile"
25665
25666         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25667         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25668         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25669         stack_trap "$LCTL set_param -n $pages_per_rpc"
25670
25671         # Recreate file so it's empty
25672         rm -f $DIR/$tfile
25673         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25674         #Pause rpc completion to guarantee we see multiple rpcs in flight
25675         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25676         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25677         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25678
25679         # Clear rpc stats
25680         $LCTL set_param osc.*.rpc_stats=c
25681
25682         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25683                 error "parallel dio failed"
25684         stack_trap "rm -f $DIR/$tfile"
25685
25686         $LCTL get_param osc.*-OST0000-*.rpc_stats
25687         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25688                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25689                 grep "8:" | awk '{print $8}')
25690         # We look at the "8 rpcs in flight" field, and verify A) it is present
25691         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25692         # as expected for an 8M DIO to a file with 1M stripes.
25693         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25694
25695         # Verify turning off parallel dio works as expected
25696         # Clear rpc stats
25697         $LCTL set_param osc.*.rpc_stats=c
25698         $LCTL set_param llite.*.parallel_dio=0
25699         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25700
25701         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25702                 error "dio with parallel dio disabled failed"
25703
25704         # Ideally, we would see only one RPC in flight here, but there is an
25705         # unavoidable race between i/o completion and RPC in flight counting,
25706         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25707         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25708         # So instead we just verify it's always < 8.
25709         $LCTL get_param osc.*-OST0000-*.rpc_stats
25710         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25711                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25712                 grep '^$' -B1 | grep . | awk '{print $1}')
25713         [ $ret != "8:" ] ||
25714                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25715 }
25716 run_test 398g "verify parallel dio async RPC submission"
25717
25718 test_398h() { #  LU-13798
25719         local dio_file=$DIR/$tfile.dio
25720
25721         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25722
25723         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25724         stack_trap "rm -f $DIR/$tfile $dio_file"
25725
25726         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25727                 error "parallel dio failed"
25728         diff $DIR/$tfile $dio_file
25729         [[ $? == 0 ]] || error "file diff after aiocp"
25730 }
25731 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25732
25733 test_398i() { #  LU-13798
25734         local dio_file=$DIR/$tfile.dio
25735
25736         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25737
25738         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25739         stack_trap "rm -f $DIR/$tfile $dio_file"
25740
25741         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25742         $LCTL set_param fail_loc=0x1418
25743         # make sure we don't crash and fail properly
25744         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25745                 error "parallel dio page allocation failure succeeded"
25746         diff $DIR/$tfile $dio_file
25747         [[ $? != 0 ]] || error "no diff after failed aiocp"
25748 }
25749 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25750
25751 test_398j() { #  LU-13798
25752         # Stripe size > RPC size but less than i/o size tests split across
25753         # stripes and RPCs for individual i/o op
25754         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25755
25756         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25757         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25758         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25759         stack_trap "$LCTL set_param -n $pages_per_rpc"
25760
25761         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25762                 error "parallel dio write failed"
25763         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25764
25765         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25766                 error "parallel dio read failed"
25767         diff $DIR/$tfile $DIR/$tfile.2
25768         [[ $? == 0 ]] || error "file diff after parallel dio read"
25769 }
25770 run_test 398j "test parallel dio where stripe size > rpc_size"
25771
25772 test_398k() { #  LU-13798
25773         wait_delete_completed
25774         wait_mds_ost_sync
25775
25776         # 4 stripe file; we will cause out of space on OST0
25777         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25778
25779         # Fill OST0 (if it's not too large)
25780         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25781                    head -n1)
25782         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25783                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25784         fi
25785         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25786         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25787                 error "dd should fill OST0"
25788         stack_trap "rm -f $DIR/$tfile.1"
25789
25790         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25791         err=$?
25792
25793         ls -la $DIR/$tfile
25794         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25795                 error "file is not 0 bytes in size"
25796
25797         # dd above should not succeed, but don't error until here so we can
25798         # get debug info above
25799         [[ $err != 0 ]] ||
25800                 error "parallel dio write with enospc succeeded"
25801         stack_trap "rm -f $DIR/$tfile"
25802 }
25803 run_test 398k "test enospc on first stripe"
25804
25805 test_398l() { #  LU-13798
25806         wait_delete_completed
25807         wait_mds_ost_sync
25808
25809         # 4 stripe file; we will cause out of space on OST0
25810         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25811         # happens on the second i/o chunk we issue
25812         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25813
25814         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25815         stack_trap "rm -f $DIR/$tfile"
25816
25817         # Fill OST0 (if it's not too large)
25818         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25819                    head -n1)
25820         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25821                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25822         fi
25823         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25824         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25825                 error "dd should fill OST0"
25826         stack_trap "rm -f $DIR/$tfile.1"
25827
25828         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25829         err=$?
25830         stack_trap "rm -f $DIR/$tfile.2"
25831
25832         # Check that short write completed as expected
25833         ls -la $DIR/$tfile.2
25834         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25835                 error "file is not 1M in size"
25836
25837         # dd above should not succeed, but don't error until here so we can
25838         # get debug info above
25839         [[ $err != 0 ]] ||
25840                 error "parallel dio write with enospc succeeded"
25841
25842         # Truncate source file to same length as output file and diff them
25843         $TRUNCATE $DIR/$tfile 1048576
25844         diff $DIR/$tfile $DIR/$tfile.2
25845         [[ $? == 0 ]] || error "data incorrect after short write"
25846 }
25847 run_test 398l "test enospc on intermediate stripe/RPC"
25848
25849 test_398m() { #  LU-13798
25850         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25851
25852         # Set up failure on OST0, the first stripe:
25853         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25854         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25855         # OST0 is on ost1, OST1 is on ost2.
25856         # So this fail_val specifies OST0
25857         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25858         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25859
25860         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25861                 error "parallel dio write with failure on first stripe succeeded"
25862         stack_trap "rm -f $DIR/$tfile"
25863         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25864
25865         # Place data in file for read
25866         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25867                 error "parallel dio write failed"
25868
25869         # Fail read on OST0, first stripe
25870         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25871         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25872         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25873                 error "parallel dio read with error on first stripe succeeded"
25874         rm -f $DIR/$tfile.2
25875         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25876
25877         # Switch to testing on OST1, second stripe
25878         # Clear file contents, maintain striping
25879         echo > $DIR/$tfile
25880         # Set up failure on OST1, second stripe:
25881         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25882         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25883
25884         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25885                 error "parallel dio write with failure on second stripe succeeded"
25886         stack_trap "rm -f $DIR/$tfile"
25887         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25888
25889         # Place data in file for read
25890         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25891                 error "parallel dio write failed"
25892
25893         # Fail read on OST1, second stripe
25894         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25895         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25896         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25897                 error "parallel dio read with error on second stripe succeeded"
25898         rm -f $DIR/$tfile.2
25899         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25900 }
25901 run_test 398m "test RPC failures with parallel dio"
25902
25903 # Parallel submission of DIO should not cause problems for append, but it's
25904 # important to verify.
25905 test_398n() { #  LU-13798
25906         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25907
25908         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25909                 error "dd to create source file failed"
25910         stack_trap "rm -f $DIR/$tfile"
25911
25912         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25913                 error "parallel dio write with failure on second stripe succeeded"
25914         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25915         diff $DIR/$tfile $DIR/$tfile.1
25916         [[ $? == 0 ]] || error "data incorrect after append"
25917
25918 }
25919 run_test 398n "test append with parallel DIO"
25920
25921 test_398o() {
25922         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25923 }
25924 run_test 398o "right kms with DIO"
25925
25926 test_fake_rw() {
25927         local read_write=$1
25928         if [ "$read_write" = "write" ]; then
25929                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25930         elif [ "$read_write" = "read" ]; then
25931                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25932         else
25933                 error "argument error"
25934         fi
25935
25936         # turn off debug for performance testing
25937         local saved_debug=$($LCTL get_param -n debug)
25938         $LCTL set_param debug=0
25939
25940         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25941
25942         # get ost1 size - $FSNAME-OST0000
25943         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25944         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25945         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25946
25947         if [ "$read_write" = "read" ]; then
25948                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25949         fi
25950
25951         local start_time=$(date +%s.%N)
25952         $dd_cmd bs=1M count=$blocks oflag=sync ||
25953                 error "real dd $read_write error"
25954         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25955
25956         if [ "$read_write" = "write" ]; then
25957                 rm -f $DIR/$tfile
25958         fi
25959
25960         # define OBD_FAIL_OST_FAKE_RW           0x238
25961         do_facet ost1 $LCTL set_param fail_loc=0x238
25962
25963         local start_time=$(date +%s.%N)
25964         $dd_cmd bs=1M count=$blocks oflag=sync ||
25965                 error "fake dd $read_write error"
25966         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25967
25968         if [ "$read_write" = "write" ]; then
25969                 # verify file size
25970                 cancel_lru_locks osc
25971                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25972                         error "$tfile size not $blocks MB"
25973         fi
25974         do_facet ost1 $LCTL set_param fail_loc=0
25975
25976         echo "fake $read_write $duration_fake vs. normal $read_write" \
25977                 "$duration in seconds"
25978         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25979                 error_not_in_vm "fake write is slower"
25980
25981         $LCTL set_param -n debug="$saved_debug"
25982         rm -f $DIR/$tfile
25983 }
25984 test_399a() { # LU-7655 for OST fake write
25985         remote_ost_nodsh && skip "remote OST with nodsh"
25986
25987         test_fake_rw write
25988 }
25989 run_test 399a "fake write should not be slower than normal write"
25990
25991 test_399b() { # LU-8726 for OST fake read
25992         remote_ost_nodsh && skip "remote OST with nodsh"
25993         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25994                 skip_env "ldiskfs only test"
25995         fi
25996
25997         test_fake_rw read
25998 }
25999 run_test 399b "fake read should not be slower than normal read"
26000
26001 test_400a() { # LU-1606, was conf-sanity test_74
26002         if ! which $CC > /dev/null 2>&1; then
26003                 skip_env "$CC is not installed"
26004         fi
26005
26006         local extra_flags=''
26007         local out=$TMP/$tfile
26008         local prefix=/usr/include/lustre
26009         local prog
26010
26011         # Oleg removes .c files in his test rig so test if any c files exist
26012         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26013                 skip_env "Needed .c test files are missing"
26014
26015         if ! [[ -d $prefix ]]; then
26016                 # Assume we're running in tree and fixup the include path.
26017                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26018                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26019                 extra_flags+=" -L$LUSTRE/utils/.libs"
26020         fi
26021
26022         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26023                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26024                         error "client api broken"
26025         done
26026         rm -f $out
26027 }
26028 run_test 400a "Lustre client api program can compile and link"
26029
26030 test_400b() { # LU-1606, LU-5011
26031         local header
26032         local out=$TMP/$tfile
26033         local prefix=/usr/include/linux/lustre
26034
26035         # We use a hard coded prefix so that this test will not fail
26036         # when run in tree. There are headers in lustre/include/lustre/
26037         # that are not packaged (like lustre_idl.h) and have more
26038         # complicated include dependencies (like config.h and lnet/types.h).
26039         # Since this test about correct packaging we just skip them when
26040         # they don't exist (see below) rather than try to fixup cppflags.
26041
26042         if ! which $CC > /dev/null 2>&1; then
26043                 skip_env "$CC is not installed"
26044         fi
26045
26046         for header in $prefix/*.h; do
26047                 if ! [[ -f "$header" ]]; then
26048                         continue
26049                 fi
26050
26051                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26052                         continue # lustre_ioctl.h is internal header
26053                 fi
26054
26055                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26056                         error "cannot compile '$header'"
26057         done
26058         rm -f $out
26059 }
26060 run_test 400b "packaged headers can be compiled"
26061
26062 test_401a() { #LU-7437
26063         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26064         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26065
26066         #count the number of parameters by "list_param -R"
26067         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26068         #count the number of parameters by listing proc files
26069         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26070         echo "proc_dirs='$proc_dirs'"
26071         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26072         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26073                       sort -u | wc -l)
26074
26075         [ $params -eq $procs ] ||
26076                 error "found $params parameters vs. $procs proc files"
26077
26078         # test the list_param -D option only returns directories
26079         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26080         #count the number of parameters by listing proc directories
26081         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26082                 sort -u | wc -l)
26083
26084         [ $params -eq $procs ] ||
26085                 error "found $params parameters vs. $procs proc files"
26086 }
26087 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26088
26089 test_401b() {
26090         # jobid_var may not allow arbitrary values, so use jobid_name
26091         # if available
26092         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26093                 local testname=jobid_name tmp='testing%p'
26094         else
26095                 local testname=jobid_var tmp=testing
26096         fi
26097
26098         local save=$($LCTL get_param -n $testname)
26099
26100         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26101                 error "no error returned when setting bad parameters"
26102
26103         local jobid_new=$($LCTL get_param -n foe $testname baz)
26104         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26105
26106         $LCTL set_param -n fog=bam $testname=$save bat=fog
26107         local jobid_old=$($LCTL get_param -n foe $testname bag)
26108         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26109 }
26110 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26111
26112 test_401c() {
26113         # jobid_var may not allow arbitrary values, so use jobid_name
26114         # if available
26115         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26116                 local testname=jobid_name
26117         else
26118                 local testname=jobid_var
26119         fi
26120
26121         local jobid_var_old=$($LCTL get_param -n $testname)
26122         local jobid_var_new
26123
26124         $LCTL set_param $testname= &&
26125                 error "no error returned for 'set_param a='"
26126
26127         jobid_var_new=$($LCTL get_param -n $testname)
26128         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26129                 error "$testname was changed by setting without value"
26130
26131         $LCTL set_param $testname &&
26132                 error "no error returned for 'set_param a'"
26133
26134         jobid_var_new=$($LCTL get_param -n $testname)
26135         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26136                 error "$testname was changed by setting without value"
26137 }
26138 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26139
26140 test_401d() {
26141         # jobid_var may not allow arbitrary values, so use jobid_name
26142         # if available
26143         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26144                 local testname=jobid_name new_value='foo=bar%p'
26145         else
26146                 local testname=jobid_var new_valuie=foo=bar
26147         fi
26148
26149         local jobid_var_old=$($LCTL get_param -n $testname)
26150         local jobid_var_new
26151
26152         $LCTL set_param $testname=$new_value ||
26153                 error "'set_param a=b' did not accept a value containing '='"
26154
26155         jobid_var_new=$($LCTL get_param -n $testname)
26156         [[ "$jobid_var_new" == "$new_value" ]] ||
26157                 error "'set_param a=b' failed on a value containing '='"
26158
26159         # Reset the $testname to test the other format
26160         $LCTL set_param $testname=$jobid_var_old
26161         jobid_var_new=$($LCTL get_param -n $testname)
26162         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26163                 error "failed to reset $testname"
26164
26165         $LCTL set_param $testname $new_value ||
26166                 error "'set_param a b' did not accept a value containing '='"
26167
26168         jobid_var_new=$($LCTL get_param -n $testname)
26169         [[ "$jobid_var_new" == "$new_value" ]] ||
26170                 error "'set_param a b' failed on a value containing '='"
26171
26172         $LCTL set_param $testname $jobid_var_old
26173         jobid_var_new=$($LCTL get_param -n $testname)
26174         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26175                 error "failed to reset $testname"
26176 }
26177 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26178
26179 test_401e() { # LU-14779
26180         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26181                 error "lctl list_param MGC* failed"
26182         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26183         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26184                 error "lctl get_param lru_size failed"
26185 }
26186 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26187
26188 test_402() {
26189         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26190         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26191                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26192         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26193                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26194                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26195         remote_mds_nodsh && skip "remote MDS with nodsh"
26196
26197         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26198 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26199         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26200         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26201                 echo "Touch failed - OK"
26202 }
26203 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26204
26205 test_403() {
26206         local file1=$DIR/$tfile.1
26207         local file2=$DIR/$tfile.2
26208         local tfile=$TMP/$tfile
26209
26210         rm -f $file1 $file2 $tfile
26211
26212         touch $file1
26213         ln $file1 $file2
26214
26215         # 30 sec OBD_TIMEOUT in ll_getattr()
26216         # right before populating st_nlink
26217         $LCTL set_param fail_loc=0x80001409
26218         stat -c %h $file1 > $tfile &
26219
26220         # create an alias, drop all locks and reclaim the dentry
26221         < $file2
26222         cancel_lru_locks mdc
26223         cancel_lru_locks osc
26224         sysctl -w vm.drop_caches=2
26225
26226         wait
26227
26228         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26229
26230         rm -f $tfile $file1 $file2
26231 }
26232 run_test 403 "i_nlink should not drop to zero due to aliasing"
26233
26234 test_404() { # LU-6601
26235         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26236                 skip "Need server version newer than 2.8.52"
26237         remote_mds_nodsh && skip "remote MDS with nodsh"
26238
26239         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26240                 awk '/osp .*-osc-MDT/ { print $4}')
26241
26242         local osp
26243         for osp in $mosps; do
26244                 echo "Deactivate: " $osp
26245                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26246                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26247                         awk -vp=$osp '$4 == p { print $2 }')
26248                 [ $stat = IN ] || {
26249                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26250                         error "deactivate error"
26251                 }
26252                 echo "Activate: " $osp
26253                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26254                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26255                         awk -vp=$osp '$4 == p { print $2 }')
26256                 [ $stat = UP ] || {
26257                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26258                         error "activate error"
26259                 }
26260         done
26261 }
26262 run_test 404 "validate manual {de}activated works properly for OSPs"
26263
26264 test_405() {
26265         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26266         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26267                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26268                         skip "Layout swap lock is not supported"
26269
26270         check_swap_layouts_support
26271         check_swap_layout_no_dom $DIR
26272
26273         test_mkdir $DIR/$tdir
26274         swap_lock_test -d $DIR/$tdir ||
26275                 error "One layout swap locked test failed"
26276 }
26277 run_test 405 "Various layout swap lock tests"
26278
26279 test_406() {
26280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26281         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26282         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26284         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26285                 skip "Need MDS version at least 2.8.50"
26286
26287         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26288         local test_pool=$TESTNAME
26289
26290         pool_add $test_pool || error "pool_add failed"
26291         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26292                 error "pool_add_targets failed"
26293
26294         save_layout_restore_at_exit $MOUNT
26295
26296         # parent set default stripe count only, child will stripe from both
26297         # parent and fs default
26298         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26299                 error "setstripe $MOUNT failed"
26300         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26301         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26302         for i in $(seq 10); do
26303                 local f=$DIR/$tdir/$tfile.$i
26304                 touch $f || error "touch failed"
26305                 local count=$($LFS getstripe -c $f)
26306                 [ $count -eq $OSTCOUNT ] ||
26307                         error "$f stripe count $count != $OSTCOUNT"
26308                 local offset=$($LFS getstripe -i $f)
26309                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26310                 local size=$($LFS getstripe -S $f)
26311                 [ $size -eq $((def_stripe_size * 2)) ] ||
26312                         error "$f stripe size $size != $((def_stripe_size * 2))"
26313                 local pool=$($LFS getstripe -p $f)
26314                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26315         done
26316
26317         # change fs default striping, delete parent default striping, now child
26318         # will stripe from new fs default striping only
26319         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26320                 error "change $MOUNT default stripe failed"
26321         $LFS setstripe -c 0 $DIR/$tdir ||
26322                 error "delete $tdir default stripe failed"
26323         for i in $(seq 11 20); do
26324                 local f=$DIR/$tdir/$tfile.$i
26325                 touch $f || error "touch $f failed"
26326                 local count=$($LFS getstripe -c $f)
26327                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26328                 local offset=$($LFS getstripe -i $f)
26329                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26330                 local size=$($LFS getstripe -S $f)
26331                 [ $size -eq $def_stripe_size ] ||
26332                         error "$f stripe size $size != $def_stripe_size"
26333                 local pool=$($LFS getstripe -p $f)
26334                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26335         done
26336
26337         unlinkmany $DIR/$tdir/$tfile. 1 20
26338
26339         local f=$DIR/$tdir/$tfile
26340         pool_remove_all_targets $test_pool $f
26341         pool_remove $test_pool $f
26342 }
26343 run_test 406 "DNE support fs default striping"
26344
26345 test_407() {
26346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26347         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26348                 skip "Need MDS version at least 2.8.55"
26349         remote_mds_nodsh && skip "remote MDS with nodsh"
26350
26351         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26352                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26353         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26354                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26355         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26356
26357         #define OBD_FAIL_DT_TXN_STOP    0x2019
26358         for idx in $(seq $MDSCOUNT); do
26359                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26360         done
26361         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26362         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26363                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26364         true
26365 }
26366 run_test 407 "transaction fail should cause operation fail"
26367
26368 test_408() {
26369         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26370
26371         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26372         lctl set_param fail_loc=0x8000040a
26373         # let ll_prepare_partial_page() fail
26374         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26375
26376         rm -f $DIR/$tfile
26377
26378         # create at least 100 unused inodes so that
26379         # shrink_icache_memory(0) should not return 0
26380         touch $DIR/$tfile-{0..100}
26381         rm -f $DIR/$tfile-{0..100}
26382         sync
26383
26384         echo 2 > /proc/sys/vm/drop_caches
26385 }
26386 run_test 408 "drop_caches should not hang due to page leaks"
26387
26388 test_409()
26389 {
26390         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26391
26392         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26393         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26394         touch $DIR/$tdir/guard || error "(2) Fail to create"
26395
26396         local PREFIX=$(str_repeat 'A' 128)
26397         echo "Create 1K hard links start at $(date)"
26398         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26399                 error "(3) Fail to hard link"
26400
26401         echo "Links count should be right although linkEA overflow"
26402         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26403         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26404         [ $linkcount -eq 1001 ] ||
26405                 error "(5) Unexpected hard links count: $linkcount"
26406
26407         echo "List all links start at $(date)"
26408         ls -l $DIR/$tdir/foo > /dev/null ||
26409                 error "(6) Fail to list $DIR/$tdir/foo"
26410
26411         echo "Unlink hard links start at $(date)"
26412         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26413                 error "(7) Fail to unlink"
26414         echo "Unlink hard links finished at $(date)"
26415 }
26416 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26417
26418 test_410()
26419 {
26420         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26421                 skip "Need client version at least 2.9.59"
26422         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26423                 skip "Need MODULES build"
26424
26425         # Create a file, and stat it from the kernel
26426         local testfile=$DIR/$tfile
26427         touch $testfile
26428
26429         local run_id=$RANDOM
26430         local my_ino=$(stat --format "%i" $testfile)
26431
26432         # Try to insert the module. This will always fail as the
26433         # module is designed to not be inserted.
26434         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26435             &> /dev/null
26436
26437         # Anything but success is a test failure
26438         dmesg | grep -q \
26439             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26440             error "no inode match"
26441 }
26442 run_test 410 "Test inode number returned from kernel thread"
26443
26444 cleanup_test411_cgroup() {
26445         trap 0
26446         rmdir "$1"
26447 }
26448
26449 test_411() {
26450         local cg_basedir=/sys/fs/cgroup/memory
26451         # LU-9966
26452         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26453                 skip "no setup for cgroup"
26454
26455         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26456                 error "test file creation failed"
26457         cancel_lru_locks osc
26458
26459         # Create a very small memory cgroup to force a slab allocation error
26460         local cgdir=$cg_basedir/osc_slab_alloc
26461         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26462         trap "cleanup_test411_cgroup $cgdir" EXIT
26463         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26464         echo 1M > $cgdir/memory.limit_in_bytes
26465
26466         # Should not LBUG, just be killed by oom-killer
26467         # dd will return 0 even allocation failure in some environment.
26468         # So don't check return value
26469         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26470         cleanup_test411_cgroup $cgdir
26471
26472         return 0
26473 }
26474 run_test 411 "Slab allocation error with cgroup does not LBUG"
26475
26476 test_412() {
26477         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26478         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26479                 skip "Need server version at least 2.10.55"
26480
26481         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26482                 error "mkdir failed"
26483         $LFS getdirstripe $DIR/$tdir
26484         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26485         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26486                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26487         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26488         [ $stripe_count -eq 2 ] ||
26489                 error "expect 2 get $stripe_count"
26490
26491         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26492
26493         local index
26494         local index2
26495
26496         # subdirs should be on the same MDT as parent
26497         for i in $(seq 0 $((MDSCOUNT - 1))); do
26498                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26499                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26500                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26501                 (( index == i )) || error "mdt$i/sub on MDT$index"
26502         done
26503
26504         # stripe offset -1, ditto
26505         for i in {1..10}; do
26506                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26507                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26508                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26509                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26510                 (( index == index2 )) ||
26511                         error "qos$i on MDT$index, sub on MDT$index2"
26512         done
26513
26514         local testdir=$DIR/$tdir/inherit
26515
26516         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26517         # inherit 2 levels
26518         for i in 1 2; do
26519                 testdir=$testdir/s$i
26520                 mkdir $testdir || error "mkdir $testdir failed"
26521                 index=$($LFS getstripe -m $testdir)
26522                 (( index == 1 )) ||
26523                         error "$testdir on MDT$index"
26524         done
26525
26526         # not inherit any more
26527         testdir=$testdir/s3
26528         mkdir $testdir || error "mkdir $testdir failed"
26529         getfattr -d -m dmv $testdir | grep dmv &&
26530                 error "default LMV set on $testdir" || true
26531 }
26532 run_test 412 "mkdir on specific MDTs"
26533
26534 TEST413_COUNT=${TEST413_COUNT:-200}
26535
26536 #
26537 # set_maxage() is used by test_413 only.
26538 # This is a helper function to set maxage. Does not return any value.
26539 # Input: maxage to set
26540 #
26541 set_maxage() {
26542         local lmv_qos_maxage
26543         local lod_qos_maxage
26544         local new_maxage=$1
26545
26546         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26547         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26548         stack_trap "$LCTL set_param \
26549                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26550         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26551                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26552         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26553                 lod.*.mdt_qos_maxage=$new_maxage
26554         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26555                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26556 }
26557
26558 generate_uneven_mdts() {
26559         local threshold=$1
26560         local ffree
26561         local bavail
26562         local max
26563         local min
26564         local max_index
26565         local min_index
26566         local tmp
26567         local i
26568
26569         echo
26570         echo "Check for uneven MDTs: "
26571
26572         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26573         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26574         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26575
26576         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26577         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26578         max_index=0
26579         min_index=0
26580         for ((i = 1; i < ${#ffree[@]}; i++)); do
26581                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26582                 if [ $tmp -gt $max ]; then
26583                         max=$tmp
26584                         max_index=$i
26585                 fi
26586                 if [ $tmp -lt $min ]; then
26587                         min=$tmp
26588                         min_index=$i
26589                 fi
26590         done
26591
26592         (( min > 0 )) || skip "low space on MDT$min_index"
26593         (( ${ffree[min_index]} > 0 )) ||
26594                 skip "no free files on MDT$min_index"
26595         (( ${ffree[min_index]} < 10000000 )) ||
26596                 skip "too many free files on MDT$min_index"
26597
26598         # Check if we need to generate uneven MDTs
26599         local diff=$(((max - min) * 100 / min))
26600         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26601         local testdir # individual folder within $testdirp
26602         local start
26603         local cmd
26604
26605         # fallocate is faster to consume space on MDT, if available
26606         if check_fallocate_supported mds$((min_index + 1)); then
26607                 cmd="fallocate -l 128K "
26608         else
26609                 cmd="dd if=/dev/zero bs=128K count=1 of="
26610         fi
26611
26612         echo "using cmd $cmd"
26613         for (( i = 0; diff < threshold; i++ )); do
26614                 testdir=${testdirp}/$i
26615                 [ -d $testdir ] && continue
26616
26617                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26618
26619                 mkdir -p $testdirp
26620                 # generate uneven MDTs, create till $threshold% diff
26621                 echo -n "weight diff=$diff% must be > $threshold% ..."
26622                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26623                 $LFS mkdir -i $min_index $testdir ||
26624                         error "mkdir $testdir failed"
26625                 $LFS setstripe -E 1M -L mdt $testdir ||
26626                         error "setstripe $testdir failed"
26627                 start=$SECONDS
26628                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26629                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26630                 done
26631                 sync; sleep 1; sync
26632
26633                 # wait for QOS to update
26634                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26635
26636                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26637                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26638                 max=$(((${ffree[max_index]} >> 8) *
26639                         (${bavail[max_index]} * bsize >> 16)))
26640                 min=$(((${ffree[min_index]} >> 8) *
26641                         (${bavail[min_index]} * bsize >> 16)))
26642                 (( min > 0 )) || skip "low space on MDT$min_index"
26643                 diff=$(((max - min) * 100 / min))
26644         done
26645
26646         echo "MDT filesfree available: ${ffree[*]}"
26647         echo "MDT blocks available: ${bavail[*]}"
26648         echo "weight diff=$diff%"
26649 }
26650
26651 test_qos_mkdir() {
26652         local mkdir_cmd=$1
26653         local stripe_count=$2
26654         local mdts=$(comma_list $(mdts_nodes))
26655
26656         local testdir
26657         local lmv_qos_prio_free
26658         local lmv_qos_threshold_rr
26659         local lod_qos_prio_free
26660         local lod_qos_threshold_rr
26661         local total
26662         local count
26663         local i
26664
26665         # @total is total directories created if it's testing plain
26666         # directories, otherwise it's total stripe object count for
26667         # striped directories test.
26668         # remote/striped directory unlinking is slow on zfs and may
26669         # timeout, test with fewer directories
26670         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26671
26672         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26673         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26674         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26675                 head -n1)
26676         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26677         stack_trap "$LCTL set_param \
26678                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26679         stack_trap "$LCTL set_param \
26680                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26681
26682         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26683                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26684         lod_qos_prio_free=${lod_qos_prio_free%%%}
26685         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26686                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26687         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26688         stack_trap "do_nodes $mdts $LCTL set_param \
26689                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26690         stack_trap "do_nodes $mdts $LCTL set_param \
26691                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26692
26693         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26694         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26695
26696         testdir=$DIR/$tdir-s$stripe_count/rr
26697
26698         local stripe_index=$($LFS getstripe -m $testdir)
26699         local test_mkdir_rr=true
26700
26701         getfattr -d -m dmv -e hex $testdir | grep dmv
26702         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26703                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26704                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26705                         test_mkdir_rr=false
26706         fi
26707
26708         echo
26709         $test_mkdir_rr &&
26710                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26711                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26712
26713         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26714         for (( i = 0; i < total / stripe_count; i++ )); do
26715                 eval $mkdir_cmd $testdir/subdir$i ||
26716                         error "$mkdir_cmd subdir$i failed"
26717         done
26718
26719         for (( i = 0; i < $MDSCOUNT; i++ )); do
26720                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26721                 echo "$count directories created on MDT$i"
26722                 if $test_mkdir_rr; then
26723                         (( count == total / stripe_count / MDSCOUNT )) ||
26724                                 error "subdirs are not evenly distributed"
26725                 elif (( i == stripe_index )); then
26726                         (( count == total / stripe_count )) ||
26727                                 error "$count subdirs created on MDT$i"
26728                 else
26729                         (( count == 0 )) ||
26730                                 error "$count subdirs created on MDT$i"
26731                 fi
26732
26733                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26734                         count=$($LFS getdirstripe $testdir/* |
26735                                 grep -c -P "^\s+$i\t")
26736                         echo "$count stripes created on MDT$i"
26737                         # deviation should < 5% of average
26738                         delta=$((count - total / MDSCOUNT))
26739                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26740                                 error "stripes are not evenly distributed"
26741                 fi
26742         done
26743
26744         echo
26745         echo "Check for uneven MDTs: "
26746
26747         local ffree
26748         local bavail
26749         local max
26750         local min
26751         local max_index
26752         local min_index
26753         local tmp
26754
26755         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26756         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26757         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26758
26759         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26760         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26761         max_index=0
26762         min_index=0
26763         for ((i = 1; i < ${#ffree[@]}; i++)); do
26764                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26765                 if [ $tmp -gt $max ]; then
26766                         max=$tmp
26767                         max_index=$i
26768                 fi
26769                 if [ $tmp -lt $min ]; then
26770                         min=$tmp
26771                         min_index=$i
26772                 fi
26773         done
26774         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26775
26776         (( min > 0 )) || skip "low space on MDT$min_index"
26777         (( ${ffree[min_index]} < 10000000 )) ||
26778                 skip "too many free files on MDT$min_index"
26779
26780         generate_uneven_mdts 120
26781
26782         echo "MDT filesfree available: ${ffree[*]}"
26783         echo "MDT blocks available: ${bavail[*]}"
26784         echo "weight diff=$(((max - min) * 100 / min))%"
26785         echo
26786         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26787
26788         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26789         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26790         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26791         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26792         # decrease statfs age, so that it can be updated in time
26793         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26794         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26795
26796         sleep 1
26797
26798         testdir=$DIR/$tdir-s$stripe_count/qos
26799
26800         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26801         for (( i = 0; i < total / stripe_count; i++ )); do
26802                 eval $mkdir_cmd $testdir/subdir$i ||
26803                         error "$mkdir_cmd subdir$i failed"
26804         done
26805
26806         max=0
26807         for (( i = 0; i < $MDSCOUNT; i++ )); do
26808                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26809                 (( count > max )) && max=$count
26810                 echo "$count directories created on MDT$i : curmax=$max"
26811         done
26812
26813         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26814
26815         # D-value should > 10% of average
26816         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
26817                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
26818
26819         # ditto for stripes
26820         if (( stripe_count > 1 )); then
26821                 max=0
26822                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26823                         count=$($LFS getdirstripe $testdir/* |
26824                                 grep -c -P "^\s+$i\t")
26825                         (( count > max )) && max=$count
26826                         echo "$count stripes created on MDT$i"
26827                 done
26828
26829                 min=$($LFS getdirstripe $testdir/* |
26830                         grep -c -P "^\s+$min_index\t")
26831                 (( max - min > total / MDSCOUNT / 10 )) ||
26832                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
26833         fi
26834 }
26835
26836 most_full_mdt() {
26837         local ffree
26838         local bavail
26839         local bsize
26840         local min
26841         local min_index
26842         local tmp
26843
26844         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26845         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26846         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26847
26848         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26849         min_index=0
26850         for ((i = 1; i < ${#ffree[@]}; i++)); do
26851                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26852                 (( tmp < min )) && min=$tmp && min_index=$i
26853         done
26854
26855         echo -n $min_index
26856 }
26857
26858 test_413a() {
26859         [ $MDSCOUNT -lt 2 ] &&
26860                 skip "We need at least 2 MDTs for this test"
26861
26862         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26863                 skip "Need server version at least 2.12.52"
26864
26865         local stripe_max=$((MDSCOUNT - 1))
26866         local stripe_count
26867
26868         # let caller set maxage for latest result
26869         set_maxage 1
26870
26871         # fill MDT unevenly
26872         generate_uneven_mdts 120
26873
26874         # test 4-stripe directory at most, otherwise it's too slow
26875         # We are being very defensive. Although Autotest uses 4 MDTs.
26876         # We make sure stripe_max does not go over 4.
26877         (( stripe_max > 4 )) && stripe_max=4
26878         # unlinking striped directory is slow on zfs, and may timeout, only test
26879         # plain directory
26880         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26881         for stripe_count in $(seq 1 $stripe_max); do
26882                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26883                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26884                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26885                         error "mkdir failed"
26886                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26887         done
26888 }
26889 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26890
26891 test_413b() {
26892         [ $MDSCOUNT -lt 2 ] &&
26893                 skip "We need at least 2 MDTs for this test"
26894
26895         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26896                 skip "Need server version at least 2.12.52"
26897
26898         local stripe_max=$((MDSCOUNT - 1))
26899         local testdir
26900         local stripe_count
26901
26902         # let caller set maxage for latest result
26903         set_maxage 1
26904
26905         # fill MDT unevenly
26906         generate_uneven_mdts 120
26907
26908         # test 4-stripe directory at most, otherwise it's too slow
26909         # We are being very defensive. Although Autotest uses 4 MDTs.
26910         # We make sure stripe_max does not go over 4.
26911         (( stripe_max > 4 )) && stripe_max=4
26912         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26913         for stripe_count in $(seq 1 $stripe_max); do
26914                 testdir=$DIR/$tdir-s$stripe_count
26915                 mkdir $testdir || error "mkdir $testdir failed"
26916                 mkdir $testdir/rr || error "mkdir rr failed"
26917                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26918                         error "mkdir qos failed"
26919                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26920                         $testdir/rr || error "setdirstripe rr failed"
26921                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26922                         error "setdirstripe failed"
26923                 test_qos_mkdir "mkdir" $stripe_count
26924         done
26925 }
26926 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26927
26928 test_413c() {
26929         (( $MDSCOUNT >= 2 )) ||
26930                 skip "We need at least 2 MDTs for this test"
26931
26932         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26933                 skip "Need server version at least 2.14.51"
26934
26935         local testdir
26936         local inherit
26937         local inherit_rr
26938         local lmv_qos_maxage
26939         local lod_qos_maxage
26940
26941         # let caller set maxage for latest result
26942         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26943         $LCTL set_param lmv.*.qos_maxage=1
26944         stack_trap "$LCTL set_param \
26945                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26946         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26947                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26948         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26949                 lod.*.mdt_qos_maxage=1
26950         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26951                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26952
26953         # fill MDT unevenly
26954         generate_uneven_mdts 120
26955
26956         testdir=$DIR/${tdir}-s1
26957         mkdir $testdir || error "mkdir $testdir failed"
26958         mkdir $testdir/rr || error "mkdir rr failed"
26959         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26960         # default max_inherit is -1, default max_inherit_rr is 0
26961         $LFS setdirstripe -D -c 1 $testdir/rr ||
26962                 error "setdirstripe rr failed"
26963         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26964                 error "setdirstripe qos failed"
26965         test_qos_mkdir "mkdir" 1
26966
26967         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26968         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26969         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26970         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26971         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26972
26973         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26974         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26975         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26976         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26977         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26978         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26979         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26980                 error "level2 shouldn't have default LMV" || true
26981 }
26982 run_test 413c "mkdir with default LMV max inherit rr"
26983
26984 test_413d() {
26985         (( MDSCOUNT >= 2 )) ||
26986                 skip "We need at least 2 MDTs for this test"
26987
26988         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26989                 skip "Need server version at least 2.14.51"
26990
26991         local lmv_qos_threshold_rr
26992
26993         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26994                 head -n1)
26995         stack_trap "$LCTL set_param \
26996                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
26997
26998         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26999         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27000         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27001                 error "$tdir shouldn't have default LMV"
27002         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27003                 error "mkdir sub failed"
27004
27005         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27006
27007         (( count == 100 )) || error "$count subdirs on MDT0"
27008 }
27009 run_test 413d "inherit ROOT default LMV"
27010
27011 test_413e() {
27012         (( MDSCOUNT >= 2 )) ||
27013                 skip "We need at least 2 MDTs for this test"
27014         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27015                 skip "Need server version at least 2.14.55"
27016
27017         local testdir=$DIR/$tdir
27018         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27019         local max_inherit
27020         local sub_max_inherit
27021
27022         mkdir -p $testdir || error "failed to create $testdir"
27023
27024         # set default max-inherit to -1 if stripe count is 0 or 1
27025         $LFS setdirstripe -D -c 1 $testdir ||
27026                 error "failed to set default LMV"
27027         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27028         (( max_inherit == -1 )) ||
27029                 error "wrong max_inherit value $max_inherit"
27030
27031         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27032         $LFS setdirstripe -D -c -1 $testdir ||
27033                 error "failed to set default LMV"
27034         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27035         (( max_inherit > 0 )) ||
27036                 error "wrong max_inherit value $max_inherit"
27037
27038         # and the subdir will decrease the max_inherit by 1
27039         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27040         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27041         (( sub_max_inherit == max_inherit - 1)) ||
27042                 error "wrong max-inherit of subdir $sub_max_inherit"
27043
27044         # check specified --max-inherit and warning message
27045         stack_trap "rm -f $tmpfile"
27046         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27047                 error "failed to set default LMV"
27048         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27049         (( max_inherit == -1 )) ||
27050                 error "wrong max_inherit value $max_inherit"
27051
27052         # check the warning messages
27053         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27054                 error "failed to detect warning string"
27055         fi
27056 }
27057 run_test 413e "check default max-inherit value"
27058
27059 test_fs_dmv_inherit()
27060 {
27061         local testdir=$DIR/$tdir
27062
27063         local count
27064         local inherit
27065         local inherit_rr
27066
27067         for i in 1 2; do
27068                 mkdir $testdir || error "mkdir $testdir failed"
27069                 count=$($LFS getdirstripe -D -c $testdir)
27070                 (( count == 1 )) ||
27071                         error "$testdir default LMV count mismatch $count != 1"
27072                 inherit=$($LFS getdirstripe -D -X $testdir)
27073                 (( inherit == 3 - i )) ||
27074                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27075                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27076                 (( inherit_rr == 3 - i )) ||
27077                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27078                 testdir=$testdir/sub
27079         done
27080
27081         mkdir $testdir || error "mkdir $testdir failed"
27082         count=$($LFS getdirstripe -D -c $testdir)
27083         (( count == 0 )) ||
27084                 error "$testdir default LMV count not zero: $count"
27085 }
27086
27087 test_413f() {
27088         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27089
27090         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27091                 skip "Need server version at least 2.14.55"
27092
27093         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27094                 error "dump $DIR default LMV failed"
27095         stack_trap "setfattr --restore=$TMP/dmv.ea"
27096
27097         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27098                 error "set $DIR default LMV failed"
27099
27100         test_fs_dmv_inherit
27101 }
27102 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27103
27104 test_413g() {
27105         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27106
27107         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27108         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27109                 error "dump $DIR default LMV failed"
27110         stack_trap "setfattr --restore=$TMP/dmv.ea"
27111
27112         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27113                 error "set $DIR default LMV failed"
27114
27115         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27116                 error "mount $MOUNT2 failed"
27117         stack_trap "umount_client $MOUNT2"
27118
27119         local saved_DIR=$DIR
27120
27121         export DIR=$MOUNT2
27122
27123         stack_trap "export DIR=$saved_DIR"
27124
27125         # first check filesystem-wide default LMV inheritance
27126         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27127
27128         # then check subdirs are spread to all MDTs
27129         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27130
27131         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27132
27133         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27134 }
27135 run_test 413g "enforce ROOT default LMV on subdir mount"
27136
27137 test_413h() {
27138         (( MDSCOUNT >= 2 )) ||
27139                 skip "We need at least 2 MDTs for this test"
27140
27141         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27142                 skip "Need server version at least 2.15.50.6"
27143
27144         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27145
27146         stack_trap "$LCTL set_param \
27147                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27148         $LCTL set_param lmv.*.qos_maxage=1
27149
27150         local depth=5
27151         local rr_depth=4
27152         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27153         local count=$((MDSCOUNT * 20))
27154
27155         generate_uneven_mdts 50
27156
27157         mkdir -p $dir || error "mkdir $dir failed"
27158         stack_trap "rm -rf $dir"
27159         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27160                 --max-inherit-rr=$rr_depth $dir
27161
27162         for ((d=0; d < depth + 2; d++)); do
27163                 log "dir=$dir:"
27164                 for ((sub=0; sub < count; sub++)); do
27165                         mkdir $dir/d$sub
27166                 done
27167                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27168                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27169                 # subdirs within $rr_depth should be created round-robin
27170                 if (( d < rr_depth )); then
27171                         (( ${num[0]} != count )) ||
27172                                 error "all objects created on MDT ${num[1]}"
27173                 fi
27174
27175                 dir=$dir/d0
27176         done
27177 }
27178 run_test 413h "don't stick to parent for round-robin dirs"
27179
27180 test_413i() {
27181         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27182
27183         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27184                 skip "Need server version at least 2.14.55"
27185
27186         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27187                 error "dump $DIR default LMV failed"
27188         stack_trap "setfattr --restore=$TMP/dmv.ea"
27189
27190         local testdir=$DIR/$tdir
27191         local def_max_rr=1
27192         local def_max=3
27193         local count
27194
27195         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27196                 --max-inherit-rr=$def_max_rr $DIR ||
27197                 error "set $DIR default LMV failed"
27198
27199         for i in $(seq 2 3); do
27200                 def_max=$((def_max - 1))
27201                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27202
27203                 mkdir $testdir
27204                 # RR is decremented and keeps zeroed once exhausted
27205                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27206                 (( count == def_max_rr )) ||
27207                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27208
27209                 # max-inherit is decremented
27210                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27211                 (( count == def_max )) ||
27212                         error_noexit "$testdir: max-inherit $count != $def_max"
27213
27214                 testdir=$testdir/d$i
27215         done
27216
27217         # d3 is the last inherited from ROOT, no inheritance anymore
27218         # i.e. no the default layout anymore
27219         mkdir -p $testdir/d4/d5
27220         count=$($LFS getdirstripe -D --max-inherit $testdir)
27221         (( count == -1 )) ||
27222                 error_noexit "$testdir: max-inherit $count != -1"
27223
27224         local p_count=$($LFS getdirstripe -i $testdir)
27225
27226         for i in $(seq 4 5); do
27227                 testdir=$testdir/d$i
27228
27229                 # the root default layout is not applied once exhausted
27230                 count=$($LFS getdirstripe -i $testdir)
27231                 (( count == p_count )) ||
27232                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27233         done
27234
27235         $LFS setdirstripe -i 0 $DIR/d2
27236         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27237         (( count == -1 )) ||
27238                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27239 }
27240 run_test 413i "check default layout inheritance"
27241
27242 test_413z() {
27243         local pids=""
27244         local subdir
27245         local pid
27246
27247         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27248                 unlinkmany $subdir/f. $TEST413_COUNT &
27249                 pids="$pids $!"
27250         done
27251
27252         for pid in $pids; do
27253                 wait $pid
27254         done
27255
27256         true
27257 }
27258 run_test 413z "413 test cleanup"
27259
27260 test_414() {
27261 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27262         $LCTL set_param fail_loc=0x80000521
27263         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27264         rm -f $DIR/$tfile
27265 }
27266 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27267
27268 test_415() {
27269         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27270         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27271                 skip "Need server version at least 2.11.52"
27272
27273         # LU-11102
27274         local total=500
27275         local max=120
27276
27277         # this test may be slow on ZFS
27278         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27279
27280         # though this test is designed for striped directory, let's test normal
27281         # directory too since lock is always saved as CoS lock.
27282         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27283         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27284         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27285         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27286         wait_delete_completed_mds
27287
27288         # run a loop without concurrent touch to measure rename duration.
27289         # only for test debug/robustness, NOT part of COS functional test.
27290         local start_time=$SECONDS
27291         for ((i = 0; i < total; i++)); do
27292                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27293                         > /dev/null
27294         done
27295         local baseline=$((SECONDS - start_time))
27296         echo "rename $total files without 'touch' took $baseline sec"
27297
27298         (
27299                 while true; do
27300                         touch $DIR/$tdir
27301                 done
27302         ) &
27303         local setattr_pid=$!
27304
27305         # rename files back to original name so unlinkmany works
27306         start_time=$SECONDS
27307         for ((i = 0; i < total; i++)); do
27308                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27309                         > /dev/null
27310         done
27311         local duration=$((SECONDS - start_time))
27312
27313         kill -9 $setattr_pid
27314
27315         echo "rename $total files with 'touch' took $duration sec"
27316         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27317         (( duration <= max )) || error "rename took $duration > $max sec"
27318 }
27319 run_test 415 "lock revoke is not missing"
27320
27321 test_416() {
27322         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27323                 skip "Need server version at least 2.11.55"
27324
27325         # define OBD_FAIL_OSD_TXN_START    0x19a
27326         do_facet mds1 lctl set_param fail_loc=0x19a
27327
27328         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27329
27330         true
27331 }
27332 run_test 416 "transaction start failure won't cause system hung"
27333
27334 cleanup_417() {
27335         trap 0
27336         do_nodes $(comma_list $(mdts_nodes)) \
27337                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27338         do_nodes $(comma_list $(mdts_nodes)) \
27339                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27340         do_nodes $(comma_list $(mdts_nodes)) \
27341                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27342 }
27343
27344 test_417() {
27345         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27346         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27347                 skip "Need MDS version at least 2.11.56"
27348
27349         trap cleanup_417 RETURN EXIT
27350
27351         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27352         do_nodes $(comma_list $(mdts_nodes)) \
27353                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27354         $LFS migrate -m 0 $DIR/$tdir.1 &&
27355                 error "migrate dir $tdir.1 should fail"
27356
27357         do_nodes $(comma_list $(mdts_nodes)) \
27358                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27359         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27360                 error "create remote dir $tdir.2 should fail"
27361
27362         do_nodes $(comma_list $(mdts_nodes)) \
27363                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27364         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27365                 error "create striped dir $tdir.3 should fail"
27366         true
27367 }
27368 run_test 417 "disable remote dir, striped dir and dir migration"
27369
27370 # Checks that the outputs of df [-i] and lfs df [-i] match
27371 #
27372 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27373 check_lfs_df() {
27374         local dir=$2
27375         local inodes
27376         local df_out
27377         local lfs_df_out
27378         local count
27379         local passed=false
27380
27381         # blocks or inodes
27382         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27383
27384         for count in {1..100}; do
27385                 do_nodes "$CLIENTS" \
27386                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27387                 sync; sleep 0.2
27388
27389                 # read the lines of interest
27390                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27391                         error "df $inodes $dir | tail -n +2 failed"
27392                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27393                         error "lfs df $inodes $dir | grep summary: failed"
27394
27395                 # skip first substrings of each output as they are different
27396                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27397                 # compare the two outputs
27398                 passed=true
27399                 #  skip "available" on MDT until LU-13997 is fixed.
27400                 #for i in {1..5}; do
27401                 for i in 1 2 4 5; do
27402                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27403                 done
27404                 $passed && break
27405         done
27406
27407         if ! $passed; then
27408                 df -P $inodes $dir
27409                 echo
27410                 lfs df $inodes $dir
27411                 error "df and lfs df $1 output mismatch: "      \
27412                       "df ${inodes}: ${df_out[*]}, "            \
27413                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27414         fi
27415 }
27416
27417 test_418() {
27418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27419
27420         local dir=$DIR/$tdir
27421         local numfiles=$((RANDOM % 4096 + 2))
27422         local numblocks=$((RANDOM % 256 + 1))
27423
27424         wait_delete_completed
27425         test_mkdir $dir
27426
27427         # check block output
27428         check_lfs_df blocks $dir
27429         # check inode output
27430         check_lfs_df inodes $dir
27431
27432         # create a single file and retest
27433         echo "Creating a single file and testing"
27434         createmany -o $dir/$tfile- 1 &>/dev/null ||
27435                 error "creating 1 file in $dir failed"
27436         check_lfs_df blocks $dir
27437         check_lfs_df inodes $dir
27438
27439         # create a random number of files
27440         echo "Creating $((numfiles - 1)) files and testing"
27441         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27442                 error "creating $((numfiles - 1)) files in $dir failed"
27443
27444         # write a random number of blocks to the first test file
27445         echo "Writing $numblocks 4K blocks and testing"
27446         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27447                 count=$numblocks &>/dev/null ||
27448                 error "dd to $dir/${tfile}-0 failed"
27449
27450         # retest
27451         check_lfs_df blocks $dir
27452         check_lfs_df inodes $dir
27453
27454         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27455                 error "unlinking $numfiles files in $dir failed"
27456 }
27457 run_test 418 "df and lfs df outputs match"
27458
27459 test_419()
27460 {
27461         local dir=$DIR/$tdir
27462
27463         mkdir -p $dir
27464         touch $dir/file
27465
27466         cancel_lru_locks mdc
27467
27468         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27469         $LCTL set_param fail_loc=0x1410
27470         cat $dir/file
27471         $LCTL set_param fail_loc=0
27472         rm -rf $dir
27473 }
27474 run_test 419 "Verify open file by name doesn't crash kernel"
27475
27476 test_420()
27477 {
27478         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27479                 skip "Need MDS version at least 2.12.53"
27480
27481         local SAVE_UMASK=$(umask)
27482         local dir=$DIR/$tdir
27483         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27484
27485         mkdir -p $dir
27486         umask 0000
27487         mkdir -m03777 $dir/testdir
27488         ls -dn $dir/testdir
27489         # Need to remove trailing '.' when SELinux is enabled
27490         local dirperms=$(ls -dn $dir/testdir |
27491                          awk '{ sub(/\.$/, "", $1); print $1}')
27492         [ $dirperms == "drwxrwsrwt" ] ||
27493                 error "incorrect perms on $dir/testdir"
27494
27495         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27496                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27497         ls -n $dir/testdir/testfile
27498         local fileperms=$(ls -n $dir/testdir/testfile |
27499                           awk '{ sub(/\.$/, "", $1); print $1}')
27500         [ $fileperms == "-rwxr-xr-x" ] ||
27501                 error "incorrect perms on $dir/testdir/testfile"
27502
27503         umask $SAVE_UMASK
27504 }
27505 run_test 420 "clear SGID bit on non-directories for non-members"
27506
27507 test_421a() {
27508         local cnt
27509         local fid1
27510         local fid2
27511
27512         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27513                 skip "Need MDS version at least 2.12.54"
27514
27515         test_mkdir $DIR/$tdir
27516         createmany -o $DIR/$tdir/f 3
27517         cnt=$(ls -1 $DIR/$tdir | wc -l)
27518         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27519
27520         fid1=$(lfs path2fid $DIR/$tdir/f1)
27521         fid2=$(lfs path2fid $DIR/$tdir/f2)
27522         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27523
27524         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27525         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27526
27527         cnt=$(ls -1 $DIR/$tdir | wc -l)
27528         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27529
27530         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27531         createmany -o $DIR/$tdir/f 3
27532         cnt=$(ls -1 $DIR/$tdir | wc -l)
27533         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27534
27535         fid1=$(lfs path2fid $DIR/$tdir/f1)
27536         fid2=$(lfs path2fid $DIR/$tdir/f2)
27537         echo "remove using fsname $FSNAME"
27538         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27539
27540         cnt=$(ls -1 $DIR/$tdir | wc -l)
27541         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27542 }
27543 run_test 421a "simple rm by fid"
27544
27545 test_421b() {
27546         local cnt
27547         local FID1
27548         local FID2
27549
27550         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27551                 skip "Need MDS version at least 2.12.54"
27552
27553         test_mkdir $DIR/$tdir
27554         createmany -o $DIR/$tdir/f 3
27555         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27556         MULTIPID=$!
27557
27558         FID1=$(lfs path2fid $DIR/$tdir/f1)
27559         FID2=$(lfs path2fid $DIR/$tdir/f2)
27560         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27561
27562         kill -USR1 $MULTIPID
27563         wait
27564
27565         cnt=$(ls $DIR/$tdir | wc -l)
27566         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27567 }
27568 run_test 421b "rm by fid on open file"
27569
27570 test_421c() {
27571         local cnt
27572         local FIDS
27573
27574         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27575                 skip "Need MDS version at least 2.12.54"
27576
27577         test_mkdir $DIR/$tdir
27578         createmany -o $DIR/$tdir/f 3
27579         touch $DIR/$tdir/$tfile
27580         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27581         cnt=$(ls -1 $DIR/$tdir | wc -l)
27582         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27583
27584         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27585         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27586
27587         cnt=$(ls $DIR/$tdir | wc -l)
27588         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27589 }
27590 run_test 421c "rm by fid against hardlinked files"
27591
27592 test_421d() {
27593         local cnt
27594         local FIDS
27595
27596         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27597                 skip "Need MDS version at least 2.12.54"
27598
27599         test_mkdir $DIR/$tdir
27600         createmany -o $DIR/$tdir/f 4097
27601         cnt=$(ls -1 $DIR/$tdir | wc -l)
27602         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27603
27604         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27605         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27606
27607         cnt=$(ls $DIR/$tdir | wc -l)
27608         rm -rf $DIR/$tdir
27609         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27610 }
27611 run_test 421d "rmfid en masse"
27612
27613 test_421e() {
27614         local cnt
27615         local FID
27616
27617         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27618         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27619                 skip "Need MDS version at least 2.12.54"
27620
27621         mkdir -p $DIR/$tdir
27622         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27623         createmany -o $DIR/$tdir/striped_dir/f 512
27624         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27625         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27626
27627         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27628                 sed "s/[/][^:]*://g")
27629         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27630
27631         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27632         rm -rf $DIR/$tdir
27633         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27634 }
27635 run_test 421e "rmfid in DNE"
27636
27637 test_421f() {
27638         local cnt
27639         local FID
27640
27641         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27642                 skip "Need MDS version at least 2.12.54"
27643
27644         test_mkdir $DIR/$tdir
27645         touch $DIR/$tdir/f
27646         cnt=$(ls -1 $DIR/$tdir | wc -l)
27647         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27648
27649         FID=$(lfs path2fid $DIR/$tdir/f)
27650         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27651         # rmfid should fail
27652         cnt=$(ls -1 $DIR/$tdir | wc -l)
27653         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27654
27655         chmod a+rw $DIR/$tdir
27656         ls -la $DIR/$tdir
27657         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27658         # rmfid should fail
27659         cnt=$(ls -1 $DIR/$tdir | wc -l)
27660         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27661
27662         rm -f $DIR/$tdir/f
27663         $RUNAS touch $DIR/$tdir/f
27664         FID=$(lfs path2fid $DIR/$tdir/f)
27665         echo "rmfid as root"
27666         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27667         cnt=$(ls -1 $DIR/$tdir | wc -l)
27668         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27669
27670         rm -f $DIR/$tdir/f
27671         $RUNAS touch $DIR/$tdir/f
27672         cnt=$(ls -1 $DIR/$tdir | wc -l)
27673         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27674         FID=$(lfs path2fid $DIR/$tdir/f)
27675         # rmfid w/o user_fid2path mount option should fail
27676         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27677         cnt=$(ls -1 $DIR/$tdir | wc -l)
27678         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27679
27680         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27681         stack_trap "rmdir $tmpdir"
27682         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27683                 error "failed to mount client'"
27684         stack_trap "umount_client $tmpdir"
27685
27686         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27687         # rmfid should succeed
27688         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27689         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27690
27691         # rmfid shouldn't allow to remove files due to dir's permission
27692         chmod a+rwx $tmpdir/$tdir
27693         touch $tmpdir/$tdir/f
27694         ls -la $tmpdir/$tdir
27695         FID=$(lfs path2fid $tmpdir/$tdir/f)
27696         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27697         return 0
27698 }
27699 run_test 421f "rmfid checks permissions"
27700
27701 test_421g() {
27702         local cnt
27703         local FIDS
27704
27705         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27706         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27707                 skip "Need MDS version at least 2.12.54"
27708
27709         mkdir -p $DIR/$tdir
27710         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27711         createmany -o $DIR/$tdir/striped_dir/f 512
27712         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27713         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27714
27715         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27716                 sed "s/[/][^:]*://g")
27717
27718         rm -f $DIR/$tdir/striped_dir/f1*
27719         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27720         removed=$((512 - cnt))
27721
27722         # few files have been just removed, so we expect
27723         # rmfid to fail on their fids
27724         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27725         [ $removed != $errors ] && error "$errors != $removed"
27726
27727         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27728         rm -rf $DIR/$tdir
27729         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27730 }
27731 run_test 421g "rmfid to return errors properly"
27732
27733 test_421h() {
27734         local mount_other
27735         local mount_ret
27736         local rmfid_ret
27737         local old_fid
27738         local fidA
27739         local fidB
27740         local fidC
27741         local fidD
27742
27743         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27744                 skip "Need MDS version at least 2.15.53"
27745
27746         test_mkdir $DIR/$tdir
27747         test_mkdir $DIR/$tdir/subdir
27748         touch $DIR/$tdir/subdir/file0
27749         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27750         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27751         rm -f $DIR/$tdir/subdir/file0
27752         touch $DIR/$tdir/subdir/fileA
27753         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27754         echo File $DIR/$tdir/subdir/fileA FID $fidA
27755         touch $DIR/$tdir/subdir/fileB
27756         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27757         echo File $DIR/$tdir/subdir/fileB FID $fidB
27758         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27759         touch $DIR/$tdir/subdir/fileC
27760         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27761         echo File $DIR/$tdir/subdir/fileC FID $fidC
27762         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27763         touch $DIR/$tdir/fileD
27764         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27765         echo File $DIR/$tdir/fileD FID $fidD
27766
27767         # mount another client mount point with subdirectory mount
27768         export FILESET=/$tdir/subdir
27769         mount_other=${MOUNT}_other
27770         mount_client $mount_other ${MOUNT_OPTS}
27771         mount_ret=$?
27772         export FILESET=""
27773         (( mount_ret == 0 )) || error "mount $mount_other failed"
27774
27775         echo Removing FIDs:
27776         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27777         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27778         rmfid_ret=$?
27779
27780         umount_client $mount_other || error "umount $mount_other failed"
27781
27782         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27783
27784         # fileA should have been deleted
27785         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27786
27787         # fileB should have been deleted
27788         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27789
27790         # fileC should not have been deleted, fid also exists outside of fileset
27791         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27792
27793         # fileD should not have been deleted, it exists outside of fileset
27794         stat $DIR/$tdir/fileD || error "fileD deleted"
27795 }
27796 run_test 421h "rmfid with fileset mount"
27797
27798 test_422() {
27799         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27800         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27801         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27802         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27803         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27804
27805         local amc=$(at_max_get client)
27806         local amo=$(at_max_get mds1)
27807         local timeout=`lctl get_param -n timeout`
27808
27809         at_max_set 0 client
27810         at_max_set 0 mds1
27811
27812 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27813         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27814                         fail_val=$(((2*timeout + 10)*1000))
27815         touch $DIR/$tdir/d3/file &
27816         sleep 2
27817 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27818         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27819                         fail_val=$((2*timeout + 5))
27820         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27821         local pid=$!
27822         sleep 1
27823         kill -9 $pid
27824         sleep $((2 * timeout))
27825         echo kill $pid
27826         kill -9 $pid
27827         lctl mark touch
27828         touch $DIR/$tdir/d2/file3
27829         touch $DIR/$tdir/d2/file4
27830         touch $DIR/$tdir/d2/file5
27831
27832         wait
27833         at_max_set $amc client
27834         at_max_set $amo mds1
27835
27836         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27837         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27838                 error "Watchdog is always throttled"
27839 }
27840 run_test 422 "kill a process with RPC in progress"
27841
27842 stat_test() {
27843     df -h $MOUNT &
27844     df -h $MOUNT &
27845     df -h $MOUNT &
27846     df -h $MOUNT &
27847     df -h $MOUNT &
27848     df -h $MOUNT &
27849 }
27850
27851 test_423() {
27852     local _stats
27853     # ensure statfs cache is expired
27854     sleep 2;
27855
27856     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27857     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27858
27859     return 0
27860 }
27861 run_test 423 "statfs should return a right data"
27862
27863 test_424() {
27864 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27865         $LCTL set_param fail_loc=0x80000522
27866         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27867         rm -f $DIR/$tfile
27868 }
27869 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27870
27871 test_425() {
27872         test_mkdir -c -1 $DIR/$tdir
27873         $LFS setstripe -c -1 $DIR/$tdir
27874
27875         lru_resize_disable "" 100
27876         stack_trap "lru_resize_enable" EXIT
27877
27878         sleep 5
27879
27880         for i in $(seq $((MDSCOUNT * 125))); do
27881                 local t=$DIR/$tdir/$tfile_$i
27882
27883                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27884                         error_noexit "Create file $t"
27885         done
27886         stack_trap "rm -rf $DIR/$tdir" EXIT
27887
27888         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27889                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27890                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27891
27892                 [ $lock_count -le $lru_size ] ||
27893                         error "osc lock count $lock_count > lru size $lru_size"
27894         done
27895
27896         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27897                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27898                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27899
27900                 [ $lock_count -le $lru_size ] ||
27901                         error "mdc lock count $lock_count > lru size $lru_size"
27902         done
27903 }
27904 run_test 425 "lock count should not exceed lru size"
27905
27906 test_426() {
27907         splice-test -r $DIR/$tfile
27908         splice-test -rd $DIR/$tfile
27909         splice-test $DIR/$tfile
27910         splice-test -d $DIR/$tfile
27911 }
27912 run_test 426 "splice test on Lustre"
27913
27914 test_427() {
27915         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27916         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27917                 skip "Need MDS version at least 2.12.4"
27918         local log
27919
27920         mkdir $DIR/$tdir
27921         mkdir $DIR/$tdir/1
27922         mkdir $DIR/$tdir/2
27923         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27924         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27925
27926         $LFS getdirstripe $DIR/$tdir/1/dir
27927
27928         #first setfattr for creating updatelog
27929         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27930
27931 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27932         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27933         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27934         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27935
27936         sleep 2
27937         fail mds2
27938         wait_recovery_complete mds2 $((2*TIMEOUT))
27939
27940         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27941         echo $log | grep "get update log failed" &&
27942                 error "update log corruption is detected" || true
27943 }
27944 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27945
27946 test_428() {
27947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27948         local cache_limit=$CACHE_MAX
27949
27950         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27951         $LCTL set_param -n llite.*.max_cached_mb=64
27952
27953         mkdir $DIR/$tdir
27954         $LFS setstripe -c 1 $DIR/$tdir
27955         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27956         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27957         #test write
27958         for f in $(seq 4); do
27959                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27960         done
27961         wait
27962
27963         cancel_lru_locks osc
27964         # Test read
27965         for f in $(seq 4); do
27966                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27967         done
27968         wait
27969 }
27970 run_test 428 "large block size IO should not hang"
27971
27972 test_429() { # LU-7915 / LU-10948
27973         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27974         local testfile=$DIR/$tfile
27975         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27976         local new_flag=1
27977         local first_rpc
27978         local second_rpc
27979         local third_rpc
27980
27981         $LCTL get_param $ll_opencache_threshold_count ||
27982                 skip "client does not have opencache parameter"
27983
27984         set_opencache $new_flag
27985         stack_trap "restore_opencache"
27986         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27987                 error "enable opencache failed"
27988         touch $testfile
27989         # drop MDC DLM locks
27990         cancel_lru_locks mdc
27991         # clear MDC RPC stats counters
27992         $LCTL set_param $mdc_rpcstats=clear
27993
27994         # According to the current implementation, we need to run 3 times
27995         # open & close file to verify if opencache is enabled correctly.
27996         # 1st, RPCs are sent for lookup/open and open handle is released on
27997         #      close finally.
27998         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
27999         #      so open handle won't be released thereafter.
28000         # 3rd, No RPC is sent out.
28001         $MULTIOP $testfile oc || error "multiop failed"
28002         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28003         echo "1st: $first_rpc RPCs in flight"
28004
28005         $MULTIOP $testfile oc || error "multiop failed"
28006         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28007         echo "2nd: $second_rpc RPCs in flight"
28008
28009         $MULTIOP $testfile oc || error "multiop failed"
28010         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28011         echo "3rd: $third_rpc RPCs in flight"
28012
28013         #verify no MDC RPC is sent
28014         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28015 }
28016 run_test 429 "verify if opencache flag on client side does work"
28017
28018 lseek_test_430() {
28019         local offset
28020         local file=$1
28021
28022         # data at [200K, 400K)
28023         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28024                 error "256K->512K dd fails"
28025         # data at [2M, 3M)
28026         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28027                 error "2M->3M dd fails"
28028         # data at [4M, 5M)
28029         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28030                 error "4M->5M dd fails"
28031         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28032         # start at first component hole #1
28033         printf "Seeking hole from 1000 ... "
28034         offset=$(lseek_test -l 1000 $file)
28035         echo $offset
28036         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28037         printf "Seeking data from 1000 ... "
28038         offset=$(lseek_test -d 1000 $file)
28039         echo $offset
28040         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28041
28042         # start at first component data block
28043         printf "Seeking hole from 300000 ... "
28044         offset=$(lseek_test -l 300000 $file)
28045         echo $offset
28046         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28047         printf "Seeking data from 300000 ... "
28048         offset=$(lseek_test -d 300000 $file)
28049         echo $offset
28050         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28051
28052         # start at the first component but beyond end of object size
28053         printf "Seeking hole from 1000000 ... "
28054         offset=$(lseek_test -l 1000000 $file)
28055         echo $offset
28056         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28057         printf "Seeking data from 1000000 ... "
28058         offset=$(lseek_test -d 1000000 $file)
28059         echo $offset
28060         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28061
28062         # start at second component stripe 2 (empty file)
28063         printf "Seeking hole from 1500000 ... "
28064         offset=$(lseek_test -l 1500000 $file)
28065         echo $offset
28066         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28067         printf "Seeking data from 1500000 ... "
28068         offset=$(lseek_test -d 1500000 $file)
28069         echo $offset
28070         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28071
28072         # start at second component stripe 1 (all data)
28073         printf "Seeking hole from 3000000 ... "
28074         offset=$(lseek_test -l 3000000 $file)
28075         echo $offset
28076         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28077         printf "Seeking data from 3000000 ... "
28078         offset=$(lseek_test -d 3000000 $file)
28079         echo $offset
28080         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28081
28082         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28083                 error "2nd dd fails"
28084         echo "Add data block at 640K...1280K"
28085
28086         # start at before new data block, in hole
28087         printf "Seeking hole from 600000 ... "
28088         offset=$(lseek_test -l 600000 $file)
28089         echo $offset
28090         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28091         printf "Seeking data from 600000 ... "
28092         offset=$(lseek_test -d 600000 $file)
28093         echo $offset
28094         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28095
28096         # start at the first component new data block
28097         printf "Seeking hole from 1000000 ... "
28098         offset=$(lseek_test -l 1000000 $file)
28099         echo $offset
28100         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28101         printf "Seeking data from 1000000 ... "
28102         offset=$(lseek_test -d 1000000 $file)
28103         echo $offset
28104         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28105
28106         # start at second component stripe 2, new data
28107         printf "Seeking hole from 1200000 ... "
28108         offset=$(lseek_test -l 1200000 $file)
28109         echo $offset
28110         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28111         printf "Seeking data from 1200000 ... "
28112         offset=$(lseek_test -d 1200000 $file)
28113         echo $offset
28114         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28115
28116         # start beyond file end
28117         printf "Using offset > filesize ... "
28118         lseek_test -l 4000000 $file && error "lseek should fail"
28119         printf "Using offset > filesize ... "
28120         lseek_test -d 4000000 $file && error "lseek should fail"
28121
28122         printf "Done\n\n"
28123 }
28124
28125 test_430a() {
28126         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28127                 skip "MDT does not support SEEK_HOLE"
28128
28129         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28130                 skip "OST does not support SEEK_HOLE"
28131
28132         local file=$DIR/$tdir/$tfile
28133
28134         mkdir -p $DIR/$tdir
28135
28136         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28137         # OST stripe #1 will have continuous data at [1M, 3M)
28138         # OST stripe #2 is empty
28139         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28140         lseek_test_430 $file
28141         rm $file
28142         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28143         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28144         lseek_test_430 $file
28145         rm $file
28146         $LFS setstripe -c2 -S 512K $file
28147         echo "Two stripes, stripe size 512K"
28148         lseek_test_430 $file
28149         rm $file
28150         # FLR with stale mirror
28151         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28152                        -N -c2 -S 1M $file
28153         echo "Mirrored file:"
28154         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28155         echo "Plain 2 stripes 1M"
28156         lseek_test_430 $file
28157         rm $file
28158 }
28159 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28160
28161 test_430b() {
28162         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28163                 skip "OST does not support SEEK_HOLE"
28164
28165         local offset
28166         local file=$DIR/$tdir/$tfile
28167
28168         mkdir -p $DIR/$tdir
28169         # Empty layout lseek should fail
28170         $MCREATE $file
28171         # seek from 0
28172         printf "Seeking hole from 0 ... "
28173         lseek_test -l 0 $file && error "lseek should fail"
28174         printf "Seeking data from 0 ... "
28175         lseek_test -d 0 $file && error "lseek should fail"
28176         rm $file
28177
28178         # 1M-hole file
28179         $LFS setstripe -E 1M -c2 -E eof $file
28180         $TRUNCATE $file 1048576
28181         printf "Seeking hole from 1000000 ... "
28182         offset=$(lseek_test -l 1000000 $file)
28183         echo $offset
28184         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28185         printf "Seeking data from 1000000 ... "
28186         lseek_test -d 1000000 $file && error "lseek should fail"
28187         rm $file
28188
28189         # full component followed by non-inited one
28190         $LFS setstripe -E 1M -c2 -E eof $file
28191         dd if=/dev/urandom of=$file bs=1M count=1
28192         printf "Seeking hole from 1000000 ... "
28193         offset=$(lseek_test -l 1000000 $file)
28194         echo $offset
28195         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28196         printf "Seeking hole from 1048576 ... "
28197         lseek_test -l 1048576 $file && error "lseek should fail"
28198         # init second component and truncate back
28199         echo "123" >> $file
28200         $TRUNCATE $file 1048576
28201         printf "Seeking hole from 1000000 ... "
28202         offset=$(lseek_test -l 1000000 $file)
28203         echo $offset
28204         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28205         printf "Seeking hole from 1048576 ... "
28206         lseek_test -l 1048576 $file && error "lseek should fail"
28207         # boundary checks for big values
28208         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28209         offset=$(lseek_test -d 0 $file.10g)
28210         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28211         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28212         offset=$(lseek_test -d 0 $file.100g)
28213         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28214         return 0
28215 }
28216 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28217
28218 test_430c() {
28219         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28220                 skip "OST does not support SEEK_HOLE"
28221
28222         local file=$DIR/$tdir/$tfile
28223         local start
28224
28225         mkdir -p $DIR/$tdir
28226         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
28227
28228         # cp version 8.33+ prefers lseek over fiemap
28229         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
28230                 start=$SECONDS
28231                 time cp $file /dev/null
28232                 (( SECONDS - start < 5 )) ||
28233                         error "cp: too long runtime $((SECONDS - start))"
28234
28235         fi
28236         # tar version 1.29+ supports SEEK_HOLE/DATA
28237         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
28238                 start=$SECONDS
28239                 time tar cS $file - | cat > /dev/null
28240                 (( SECONDS - start < 5 )) ||
28241                         error "tar: too long runtime $((SECONDS - start))"
28242         fi
28243 }
28244 run_test 430c "lseek: external tools check"
28245
28246 test_431() { # LU-14187
28247         local file=$DIR/$tdir/$tfile
28248
28249         mkdir -p $DIR/$tdir
28250         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28251         dd if=/dev/urandom of=$file bs=4k count=1
28252         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28253         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28254         #define OBD_FAIL_OST_RESTART_IO 0x251
28255         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28256         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28257         cp $file $file.0
28258         cancel_lru_locks
28259         sync_all_data
28260         echo 3 > /proc/sys/vm/drop_caches
28261         diff  $file $file.0 || error "data diff"
28262 }
28263 run_test 431 "Restart transaction for IO"
28264
28265 cleanup_test_432() {
28266         do_facet mgs $LCTL nodemap_activate 0
28267         wait_nm_sync active
28268 }
28269
28270 test_432() {
28271         local tmpdir=$TMP/dir432
28272
28273         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28274                 skip "Need MDS version at least 2.14.52"
28275
28276         stack_trap cleanup_test_432 EXIT
28277         mkdir $DIR/$tdir
28278         mkdir $tmpdir
28279
28280         do_facet mgs $LCTL nodemap_activate 1
28281         wait_nm_sync active
28282         do_facet mgs $LCTL nodemap_modify --name default \
28283                 --property admin --value 1
28284         do_facet mgs $LCTL nodemap_modify --name default \
28285                 --property trusted --value 1
28286         cancel_lru_locks mdc
28287         wait_nm_sync default admin_nodemap
28288         wait_nm_sync default trusted_nodemap
28289
28290         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28291                grep -ci "Operation not permitted") -ne 0 ]; then
28292                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28293         fi
28294 }
28295 run_test 432 "mv dir from outside Lustre"
28296
28297 test_433() {
28298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28299
28300         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28301                 skip "inode cache not supported"
28302
28303         $LCTL set_param llite.*.inode_cache=0
28304         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28305
28306         local count=256
28307         local before
28308         local after
28309
28310         cancel_lru_locks mdc
28311         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28312         createmany -m $DIR/$tdir/f $count
28313         createmany -d $DIR/$tdir/d $count
28314         ls -l $DIR/$tdir > /dev/null
28315         stack_trap "rm -rf $DIR/$tdir"
28316
28317         before=$(num_objects)
28318         cancel_lru_locks mdc
28319         after=$(num_objects)
28320
28321         # sometimes even @before is less than 2 * count
28322         while (( before - after < count )); do
28323                 sleep 1
28324                 after=$(num_objects)
28325                 wait=$((wait + 1))
28326                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28327                 if (( wait > 60 )); then
28328                         error "inode slab grew from $before to $after"
28329                 fi
28330         done
28331
28332         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28333 }
28334 run_test 433 "ldlm lock cancel releases dentries and inodes"
28335
28336 test_434() {
28337         local file
28338         local getxattr_count
28339         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28340         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28341
28342         [[ $(getenforce) == "Disabled" ]] ||
28343                 skip "lsm selinux module have to be disabled for this test"
28344
28345         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28346                 error "fail to create $DIR/$tdir/ on MDT0000"
28347
28348         touch $DIR/$tdir/$tfile-{001..100}
28349
28350         # disable the xattr cache
28351         save_lustre_params client "llite.*.xattr_cache" > $p
28352         lctl set_param llite.*.xattr_cache=0
28353         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28354
28355         # clear clients mdc stats
28356         clear_stats $mdc_stat_param ||
28357                 error "fail to clear stats on mdc MDT0000"
28358
28359         for file in $DIR/$tdir/$tfile-{001..100}; do
28360                 getfattr -n security.selinux $file |&
28361                         grep -q "Operation not supported" ||
28362                         error "getxattr on security.selinux should return EOPNOTSUPP"
28363         done
28364
28365         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28366         (( getxattr_count < 100 )) ||
28367                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28368 }
28369 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28370
28371 test_440() {
28372         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28373                 source $LUSTRE/scripts/bash-completion/lustre
28374         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28375                 source /usr/share/bash-completion/completions/lustre
28376         else
28377                 skip "bash completion scripts not found"
28378         fi
28379
28380         local lctl_completions
28381         local lfs_completions
28382
28383         lctl_completions=$(_lustre_cmds lctl)
28384         if [[ ! $lctl_completions =~ "get_param" ]]; then
28385                 error "lctl bash completion failed"
28386         fi
28387
28388         lfs_completions=$(_lustre_cmds lfs)
28389         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28390                 error "lfs bash completion failed"
28391         fi
28392 }
28393 run_test 440 "bash completion for lfs, lctl"
28394
28395 prep_801() {
28396         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28397         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28398                 skip "Need server version at least 2.9.55"
28399
28400         start_full_debug_logging
28401 }
28402
28403 post_801() {
28404         stop_full_debug_logging
28405 }
28406
28407 barrier_stat() {
28408         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28409                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28410                            awk '/The barrier for/ { print $7 }')
28411                 echo $st
28412         else
28413                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28414                 echo \'$st\'
28415         fi
28416 }
28417
28418 barrier_expired() {
28419         local expired
28420
28421         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28422                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28423                           awk '/will be expired/ { print $7 }')
28424         else
28425                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28426         fi
28427
28428         echo $expired
28429 }
28430
28431 test_801a() {
28432         prep_801
28433
28434         echo "Start barrier_freeze at: $(date)"
28435         #define OBD_FAIL_BARRIER_DELAY          0x2202
28436         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28437         # Do not reduce barrier time - See LU-11873
28438         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28439
28440         sleep 2
28441         local b_status=$(barrier_stat)
28442         echo "Got barrier status at: $(date)"
28443         [ "$b_status" = "'freezing_p1'" ] ||
28444                 error "(1) unexpected barrier status $b_status"
28445
28446         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28447         wait
28448         b_status=$(barrier_stat)
28449         [ "$b_status" = "'frozen'" ] ||
28450                 error "(2) unexpected barrier status $b_status"
28451
28452         local expired=$(barrier_expired)
28453         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28454         sleep $((expired + 3))
28455
28456         b_status=$(barrier_stat)
28457         [ "$b_status" = "'expired'" ] ||
28458                 error "(3) unexpected barrier status $b_status"
28459
28460         # Do not reduce barrier time - See LU-11873
28461         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28462                 error "(4) fail to freeze barrier"
28463
28464         b_status=$(barrier_stat)
28465         [ "$b_status" = "'frozen'" ] ||
28466                 error "(5) unexpected barrier status $b_status"
28467
28468         echo "Start barrier_thaw at: $(date)"
28469         #define OBD_FAIL_BARRIER_DELAY          0x2202
28470         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28471         do_facet mgs $LCTL barrier_thaw $FSNAME &
28472
28473         sleep 2
28474         b_status=$(barrier_stat)
28475         echo "Got barrier status at: $(date)"
28476         [ "$b_status" = "'thawing'" ] ||
28477                 error "(6) unexpected barrier status $b_status"
28478
28479         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28480         wait
28481         b_status=$(barrier_stat)
28482         [ "$b_status" = "'thawed'" ] ||
28483                 error "(7) unexpected barrier status $b_status"
28484
28485         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28486         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28487         do_facet mgs $LCTL barrier_freeze $FSNAME
28488
28489         b_status=$(barrier_stat)
28490         [ "$b_status" = "'failed'" ] ||
28491                 error "(8) unexpected barrier status $b_status"
28492
28493         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28494         do_facet mgs $LCTL barrier_thaw $FSNAME
28495
28496         post_801
28497 }
28498 run_test 801a "write barrier user interfaces and stat machine"
28499
28500 test_801b() {
28501         prep_801
28502
28503         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28504         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28505         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28506         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28507         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28508
28509         cancel_lru_locks mdc
28510
28511         # 180 seconds should be long enough
28512         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28513
28514         local b_status=$(barrier_stat)
28515         [ "$b_status" = "'frozen'" ] ||
28516                 error "(6) unexpected barrier status $b_status"
28517
28518         mkdir $DIR/$tdir/d0/d10 &
28519         mkdir_pid=$!
28520
28521         touch $DIR/$tdir/d1/f13 &
28522         touch_pid=$!
28523
28524         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28525         ln_pid=$!
28526
28527         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28528         mv_pid=$!
28529
28530         rm -f $DIR/$tdir/d4/f12 &
28531         rm_pid=$!
28532
28533         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28534
28535         # To guarantee taht the 'stat' is not blocked
28536         b_status=$(barrier_stat)
28537         [ "$b_status" = "'frozen'" ] ||
28538                 error "(8) unexpected barrier status $b_status"
28539
28540         # let above commands to run at background
28541         sleep 5
28542
28543         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28544         ps -p $touch_pid || error "(10) touch should be blocked"
28545         ps -p $ln_pid || error "(11) link should be blocked"
28546         ps -p $mv_pid || error "(12) rename should be blocked"
28547         ps -p $rm_pid || error "(13) unlink should be blocked"
28548
28549         b_status=$(barrier_stat)
28550         [ "$b_status" = "'frozen'" ] ||
28551                 error "(14) unexpected barrier status $b_status"
28552
28553         do_facet mgs $LCTL barrier_thaw $FSNAME
28554         b_status=$(barrier_stat)
28555         [ "$b_status" = "'thawed'" ] ||
28556                 error "(15) unexpected barrier status $b_status"
28557
28558         wait $mkdir_pid || error "(16) mkdir should succeed"
28559         wait $touch_pid || error "(17) touch should succeed"
28560         wait $ln_pid || error "(18) link should succeed"
28561         wait $mv_pid || error "(19) rename should succeed"
28562         wait $rm_pid || error "(20) unlink should succeed"
28563
28564         post_801
28565 }
28566 run_test 801b "modification will be blocked by write barrier"
28567
28568 test_801c() {
28569         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28570
28571         prep_801
28572
28573         stop mds2 || error "(1) Fail to stop mds2"
28574
28575         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28576
28577         local b_status=$(barrier_stat)
28578         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28579                 do_facet mgs $LCTL barrier_thaw $FSNAME
28580                 error "(2) unexpected barrier status $b_status"
28581         }
28582
28583         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28584                 error "(3) Fail to rescan barrier bitmap"
28585
28586         # Do not reduce barrier time - See LU-11873
28587         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28588
28589         b_status=$(barrier_stat)
28590         [ "$b_status" = "'frozen'" ] ||
28591                 error "(4) unexpected barrier status $b_status"
28592
28593         do_facet mgs $LCTL barrier_thaw $FSNAME
28594         b_status=$(barrier_stat)
28595         [ "$b_status" = "'thawed'" ] ||
28596                 error "(5) unexpected barrier status $b_status"
28597
28598         local devname=$(mdsdevname 2)
28599
28600         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28601
28602         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28603                 error "(7) Fail to rescan barrier bitmap"
28604
28605         post_801
28606 }
28607 run_test 801c "rescan barrier bitmap"
28608
28609 test_802b() {
28610         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28611         remote_mds_nodsh && skip "remote MDS with nodsh"
28612
28613         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28614                 skip "readonly option not available"
28615
28616         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28617
28618         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28619                 error "(2) Fail to copy"
28620
28621         # write back all cached data before setting MDT to readonly
28622         cancel_lru_locks
28623         sync_all_data
28624
28625         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28626         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28627
28628         echo "Modify should be refused"
28629         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28630
28631         echo "Read should be allowed"
28632         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28633                 error "(7) Read should succeed under ro mode"
28634
28635         # disable readonly
28636         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28637 }
28638 run_test 802b "be able to set MDTs to readonly"
28639
28640 test_803a() {
28641         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28642         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28643                 skip "MDS needs to be newer than 2.10.54"
28644
28645         mkdir_on_mdt0 $DIR/$tdir
28646         # Create some objects on all MDTs to trigger related logs objects
28647         for idx in $(seq $MDSCOUNT); do
28648                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28649                         $DIR/$tdir/dir${idx} ||
28650                         error "Fail to create $DIR/$tdir/dir${idx}"
28651         done
28652
28653         wait_delete_completed # ensure old test cleanups are finished
28654         sleep 3
28655         echo "before create:"
28656         $LFS df -i $MOUNT
28657         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28658
28659         for i in {1..10}; do
28660                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28661                         error "Fail to create $DIR/$tdir/foo$i"
28662         done
28663
28664         # sync ZFS-on-MDS to refresh statfs data
28665         wait_zfs_commit mds1
28666         sleep 3
28667         echo "after create:"
28668         $LFS df -i $MOUNT
28669         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28670
28671         # allow for an llog to be cleaned up during the test
28672         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28673                 error "before ($before_used) + 10 > after ($after_used)"
28674
28675         for i in {1..10}; do
28676                 rm -rf $DIR/$tdir/foo$i ||
28677                         error "Fail to remove $DIR/$tdir/foo$i"
28678         done
28679
28680         # sync ZFS-on-MDS to refresh statfs data
28681         wait_zfs_commit mds1
28682         wait_delete_completed
28683         sleep 3 # avoid MDT return cached statfs
28684         echo "after unlink:"
28685         $LFS df -i $MOUNT
28686         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28687
28688         # allow for an llog to be created during the test
28689         [ $after_used -le $((before_used + 1)) ] ||
28690                 error "after ($after_used) > before ($before_used) + 1"
28691 }
28692 run_test 803a "verify agent object for remote object"
28693
28694 test_803b() {
28695         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28696         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28697                 skip "MDS needs to be newer than 2.13.56"
28698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28699
28700         for i in $(seq 0 $((MDSCOUNT - 1))); do
28701                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28702         done
28703
28704         local before=0
28705         local after=0
28706
28707         local tmp
28708
28709         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28710         for i in $(seq 0 $((MDSCOUNT - 1))); do
28711                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28712                         awk '/getattr/ { print $2 }')
28713                 before=$((before + tmp))
28714         done
28715         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28716         for i in $(seq 0 $((MDSCOUNT - 1))); do
28717                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28718                         awk '/getattr/ { print $2 }')
28719                 after=$((after + tmp))
28720         done
28721
28722         [ $before -eq $after ] || error "getattr count $before != $after"
28723 }
28724 run_test 803b "remote object can getattr from cache"
28725
28726 test_804() {
28727         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28728         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28729                 skip "MDS needs to be newer than 2.10.54"
28730         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28731
28732         mkdir -p $DIR/$tdir
28733         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28734                 error "Fail to create $DIR/$tdir/dir0"
28735
28736         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28737         local dev=$(mdsdevname 2)
28738
28739         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28740                 grep ${fid} || error "NOT found agent entry for dir0"
28741
28742         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28743                 error "Fail to create $DIR/$tdir/dir1"
28744
28745         touch $DIR/$tdir/dir1/foo0 ||
28746                 error "Fail to create $DIR/$tdir/dir1/foo0"
28747         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28748         local rc=0
28749
28750         for idx in $(seq $MDSCOUNT); do
28751                 dev=$(mdsdevname $idx)
28752                 do_facet mds${idx} \
28753                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28754                         grep ${fid} && rc=$idx
28755         done
28756
28757         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28758                 error "Fail to rename foo0 to foo1"
28759         if [ $rc -eq 0 ]; then
28760                 for idx in $(seq $MDSCOUNT); do
28761                         dev=$(mdsdevname $idx)
28762                         do_facet mds${idx} \
28763                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28764                         grep ${fid} && rc=$idx
28765                 done
28766         fi
28767
28768         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28769                 error "Fail to rename foo1 to foo2"
28770         if [ $rc -eq 0 ]; then
28771                 for idx in $(seq $MDSCOUNT); do
28772                         dev=$(mdsdevname $idx)
28773                         do_facet mds${idx} \
28774                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28775                         grep ${fid} && rc=$idx
28776                 done
28777         fi
28778
28779         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28780
28781         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28782                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28783         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28784                 error "Fail to rename foo2 to foo0"
28785         unlink $DIR/$tdir/dir1/foo0 ||
28786                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28787         rm -rf $DIR/$tdir/dir0 ||
28788                 error "Fail to rm $DIR/$tdir/dir0"
28789
28790         for idx in $(seq $MDSCOUNT); do
28791                 rc=0
28792
28793                 stop mds${idx}
28794                 dev=$(mdsdevname $idx)
28795                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28796                         rc=$?
28797                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28798                         error "mount mds$idx failed"
28799                 df $MOUNT > /dev/null 2>&1
28800
28801                 # e2fsck should not return error
28802                 [ $rc -eq 0 ] ||
28803                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28804         done
28805 }
28806 run_test 804 "verify agent entry for remote entry"
28807
28808 cleanup_805() {
28809         do_facet $SINGLEMDS zfs set quota=$old $fsset
28810         unlinkmany $DIR/$tdir/f- 1000000
28811         trap 0
28812 }
28813
28814 test_805() {
28815         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28816         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28817         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28818                 skip "netfree not implemented before 0.7"
28819         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28820                 skip "Need MDS version at least 2.10.57"
28821
28822         local fsset
28823         local freekb
28824         local usedkb
28825         local old
28826         local quota
28827         local pref="osd-zfs.$FSNAME-MDT0000."
28828
28829         # limit available space on MDS dataset to meet nospace issue
28830         # quickly. then ZFS 0.7.2 can use reserved space if asked
28831         # properly (using netfree flag in osd_declare_destroy()
28832         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28833         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28834                 gawk '{print $3}')
28835         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28836         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28837         let "usedkb=usedkb-freekb"
28838         let "freekb=freekb/2"
28839         if let "freekb > 5000"; then
28840                 let "freekb=5000"
28841         fi
28842         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28843         trap cleanup_805 EXIT
28844         mkdir_on_mdt0 $DIR/$tdir
28845         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28846                 error "Can't set PFL layout"
28847         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28848         rm -rf $DIR/$tdir || error "not able to remove"
28849         do_facet $SINGLEMDS zfs set quota=$old $fsset
28850         trap 0
28851 }
28852 run_test 805 "ZFS can remove from full fs"
28853
28854 # Size-on-MDS test
28855 check_lsom_data()
28856 {
28857         local file=$1
28858         local expect=$(stat -c %s $file)
28859
28860         check_lsom_size $1 $expect
28861
28862         local blocks=$($LFS getsom -b $file)
28863         expect=$(stat -c %b $file)
28864         [[ $blocks == $expect ]] ||
28865                 error "$file expected blocks: $expect, got: $blocks"
28866 }
28867
28868 check_lsom_size()
28869 {
28870         local size
28871         local expect=$2
28872
28873         cancel_lru_locks mdc
28874
28875         size=$($LFS getsom -s $1)
28876         [[ $size == $expect ]] ||
28877                 error "$file expected size: $expect, got: $size"
28878 }
28879
28880 test_806() {
28881         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28882                 skip "Need MDS version at least 2.11.52"
28883
28884         local bs=1048576
28885
28886         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
28887
28888         # Disable opencache
28889         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28890         save_lustre_params client "llite.*.opencache_threshold_count" > $save
28891         lctl set_param llite.*.opencache_threshold_count=0
28892         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28893
28894         # single-threaded write
28895         echo "Test SOM for single-threaded write"
28896         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28897                 error "write $tfile failed"
28898         check_lsom_size $DIR/$tfile $bs
28899
28900         local num=32
28901         local size=$(($num * $bs))
28902         local offset=0
28903         local i
28904
28905         echo "Test SOM for single client multi-threaded($num) write"
28906         $TRUNCATE $DIR/$tfile 0
28907         for ((i = 0; i < $num; i++)); do
28908                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28909                 local pids[$i]=$!
28910                 offset=$((offset + $bs))
28911         done
28912         for (( i=0; i < $num; i++ )); do
28913                 wait ${pids[$i]}
28914         done
28915         check_lsom_size $DIR/$tfile $size
28916
28917         $TRUNCATE $DIR/$tfile 0
28918         for ((i = 0; i < $num; i++)); do
28919                 offset=$((offset - $bs))
28920                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28921                 local pids[$i]=$!
28922         done
28923         for (( i=0; i < $num; i++ )); do
28924                 wait ${pids[$i]}
28925         done
28926         check_lsom_size $DIR/$tfile $size
28927
28928         # multi-client writes
28929         num=$(get_node_count ${CLIENTS//,/ })
28930         size=$(($num * $bs))
28931         offset=0
28932         i=0
28933
28934         echo "Test SOM for multi-client ($num) writes"
28935         $TRUNCATE $DIR/$tfile 0
28936         for client in ${CLIENTS//,/ }; do
28937                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28938                 local pids[$i]=$!
28939                 i=$((i + 1))
28940                 offset=$((offset + $bs))
28941         done
28942         for (( i=0; i < $num; i++ )); do
28943                 wait ${pids[$i]}
28944         done
28945         check_lsom_size $DIR/$tfile $offset
28946
28947         i=0
28948         $TRUNCATE $DIR/$tfile 0
28949         for client in ${CLIENTS//,/ }; do
28950                 offset=$((offset - $bs))
28951                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28952                 local pids[$i]=$!
28953                 i=$((i + 1))
28954         done
28955         for (( i=0; i < $num; i++ )); do
28956                 wait ${pids[$i]}
28957         done
28958         check_lsom_size $DIR/$tfile $size
28959
28960         # verify SOM blocks count
28961         echo "Verify SOM block count"
28962         $TRUNCATE $DIR/$tfile 0
28963         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
28964                 error "failed to write file $tfile with fdatasync and fstat"
28965         check_lsom_data $DIR/$tfile
28966
28967         $TRUNCATE $DIR/$tfile 0
28968         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
28969                 error "failed to write file $tfile with fdatasync"
28970         check_lsom_data $DIR/$tfile
28971
28972         $TRUNCATE $DIR/$tfile 0
28973         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
28974                 error "failed to write file $tfile with sync IO"
28975         check_lsom_data $DIR/$tfile
28976
28977         # verify truncate
28978         echo "Test SOM for truncate"
28979         # use ftruncate to sync blocks on close request
28980         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
28981         check_lsom_size $DIR/$tfile 16384
28982         check_lsom_data $DIR/$tfile
28983
28984         $TRUNCATE $DIR/$tfile 1234
28985         check_lsom_size $DIR/$tfile 1234
28986         # sync blocks on the MDT
28987         $MULTIOP $DIR/$tfile oc
28988         check_lsom_data $DIR/$tfile
28989 }
28990 run_test 806 "Verify Lazy Size on MDS"
28991
28992 test_807() {
28993         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28994         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28995                 skip "Need MDS version at least 2.11.52"
28996
28997         # Registration step
28998         changelog_register || error "changelog_register failed"
28999         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29000         changelog_users $SINGLEMDS | grep -q $cl_user ||
29001                 error "User $cl_user not found in changelog_users"
29002
29003         rm -rf $DIR/$tdir || error "rm $tdir failed"
29004         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29005         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29006         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29007         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29008                 error "truncate $tdir/trunc failed"
29009
29010         local bs=1048576
29011         echo "Test SOM for single-threaded write with fsync"
29012         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29013                 error "write $tfile failed"
29014         sync;sync;sync
29015
29016         # multi-client wirtes
29017         local num=$(get_node_count ${CLIENTS//,/ })
29018         local offset=0
29019         local i=0
29020
29021         echo "Test SOM for multi-client ($num) writes"
29022         touch $DIR/$tfile || error "touch $tfile failed"
29023         $TRUNCATE $DIR/$tfile 0
29024         for client in ${CLIENTS//,/ }; do
29025                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29026                 local pids[$i]=$!
29027                 i=$((i + 1))
29028                 offset=$((offset + $bs))
29029         done
29030         for (( i=0; i < $num; i++ )); do
29031                 wait ${pids[$i]}
29032         done
29033
29034         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29035         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29036         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29037         check_lsom_data $DIR/$tdir/trunc
29038         check_lsom_data $DIR/$tdir/single_dd
29039         check_lsom_data $DIR/$tfile
29040
29041         rm -rf $DIR/$tdir
29042         # Deregistration step
29043         changelog_deregister || error "changelog_deregister failed"
29044 }
29045 run_test 807 "verify LSOM syncing tool"
29046
29047 check_som_nologged()
29048 {
29049         local lines=$($LFS changelog $FSNAME-MDT0000 |
29050                 grep 'x=trusted.som' | wc -l)
29051         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29052 }
29053
29054 test_808() {
29055         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29056                 skip "Need MDS version at least 2.11.55"
29057
29058         # Registration step
29059         changelog_register || error "changelog_register failed"
29060
29061         touch $DIR/$tfile || error "touch $tfile failed"
29062         check_som_nologged
29063
29064         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29065                 error "write $tfile failed"
29066         check_som_nologged
29067
29068         $TRUNCATE $DIR/$tfile 1234
29069         check_som_nologged
29070
29071         $TRUNCATE $DIR/$tfile 1048576
29072         check_som_nologged
29073
29074         # Deregistration step
29075         changelog_deregister || error "changelog_deregister failed"
29076 }
29077 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29078
29079 check_som_nodata()
29080 {
29081         $LFS getsom $1
29082         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29083 }
29084
29085 test_809() {
29086         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29087                 skip "Need MDS version at least 2.11.56"
29088
29089         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29090                 error "failed to create DoM-only file $DIR/$tfile"
29091         touch $DIR/$tfile || error "touch $tfile failed"
29092         check_som_nodata $DIR/$tfile
29093
29094         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29095                 error "write $tfile failed"
29096         check_som_nodata $DIR/$tfile
29097
29098         $TRUNCATE $DIR/$tfile 1234
29099         check_som_nodata $DIR/$tfile
29100
29101         $TRUNCATE $DIR/$tfile 4097
29102         check_som_nodata $DIR/$file
29103 }
29104 run_test 809 "Verify no SOM xattr store for DoM-only files"
29105
29106 test_810() {
29107         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29108         $GSS && skip_env "could not run with gss"
29109         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29110                 skip "OST < 2.12.58 doesn't align checksum"
29111
29112         set_checksums 1
29113         stack_trap "set_checksums $ORIG_CSUM" EXIT
29114         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29115
29116         local csum
29117         local before
29118         local after
29119         for csum in $CKSUM_TYPES; do
29120                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29121                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29122                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29123                         eval set -- $i
29124                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29125                         before=$(md5sum $DIR/$tfile)
29126                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29127                         after=$(md5sum $DIR/$tfile)
29128                         [ "$before" == "$after" ] ||
29129                                 error "$csum: $before != $after bs=$1 seek=$2"
29130                 done
29131         done
29132 }
29133 run_test 810 "partial page writes on ZFS (LU-11663)"
29134
29135 test_812a() {
29136         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29137                 skip "OST < 2.12.51 doesn't support this fail_loc"
29138
29139         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29140         # ensure ost1 is connected
29141         stat $DIR/$tfile >/dev/null || error "can't stat"
29142         wait_osc_import_state client ost1 FULL
29143         # no locks, no reqs to let the connection idle
29144         cancel_lru_locks osc
29145
29146         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29147 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29148         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29149         wait_osc_import_state client ost1 CONNECTING
29150         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29151
29152         stat $DIR/$tfile >/dev/null || error "can't stat file"
29153 }
29154 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29155
29156 test_812b() { # LU-12378
29157         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29158                 skip "OST < 2.12.51 doesn't support this fail_loc"
29159
29160         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29161         # ensure ost1 is connected
29162         stat $DIR/$tfile >/dev/null || error "can't stat"
29163         wait_osc_import_state client ost1 FULL
29164         # no locks, no reqs to let the connection idle
29165         cancel_lru_locks osc
29166
29167         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29168 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29169         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29170         wait_osc_import_state client ost1 CONNECTING
29171         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29172
29173         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29174         wait_osc_import_state client ost1 IDLE
29175 }
29176 run_test 812b "do not drop no resend request for idle connect"
29177
29178 test_812c() {
29179         local old
29180
29181         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29182
29183         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29184         $LFS getstripe $DIR/$tfile
29185         $LCTL set_param osc.*.idle_timeout=10
29186         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29187         # ensure ost1 is connected
29188         stat $DIR/$tfile >/dev/null || error "can't stat"
29189         wait_osc_import_state client ost1 FULL
29190         # no locks, no reqs to let the connection idle
29191         cancel_lru_locks osc
29192
29193 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29194         $LCTL set_param fail_loc=0x80000533
29195         sleep 15
29196         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29197 }
29198 run_test 812c "idle import vs lock enqueue race"
29199
29200 test_813() {
29201         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29202         [ -z "$file_heat_sav" ] && skip "no file heat support"
29203
29204         local readsample
29205         local writesample
29206         local readbyte
29207         local writebyte
29208         local readsample1
29209         local writesample1
29210         local readbyte1
29211         local writebyte1
29212
29213         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29214         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29215
29216         $LCTL set_param -n llite.*.file_heat=1
29217         echo "Turn on file heat"
29218         echo "Period second: $period_second, Decay percentage: $decay_pct"
29219
29220         echo "QQQQ" > $DIR/$tfile
29221         echo "QQQQ" > $DIR/$tfile
29222         echo "QQQQ" > $DIR/$tfile
29223         cat $DIR/$tfile > /dev/null
29224         cat $DIR/$tfile > /dev/null
29225         cat $DIR/$tfile > /dev/null
29226         cat $DIR/$tfile > /dev/null
29227
29228         local out=$($LFS heat_get $DIR/$tfile)
29229
29230         $LFS heat_get $DIR/$tfile
29231         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29232         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29233         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29234         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29235
29236         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29237         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29238         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29239         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29240
29241         sleep $((period_second + 3))
29242         echo "Sleep $((period_second + 3)) seconds..."
29243         # The recursion formula to calculate the heat of the file f is as
29244         # follow:
29245         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29246         # Where Hi is the heat value in the period between time points i*I and
29247         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29248         # to the weight of Ci.
29249         out=$($LFS heat_get $DIR/$tfile)
29250         $LFS heat_get $DIR/$tfile
29251         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29252         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29253         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29254         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29255
29256         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29257                 error "read sample ($readsample) is wrong"
29258         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29259                 error "write sample ($writesample) is wrong"
29260         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29261                 error "read bytes ($readbyte) is wrong"
29262         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29263                 error "write bytes ($writebyte) is wrong"
29264
29265         echo "QQQQ" > $DIR/$tfile
29266         echo "QQQQ" > $DIR/$tfile
29267         echo "QQQQ" > $DIR/$tfile
29268         cat $DIR/$tfile > /dev/null
29269         cat $DIR/$tfile > /dev/null
29270         cat $DIR/$tfile > /dev/null
29271         cat $DIR/$tfile > /dev/null
29272
29273         sleep $((period_second + 3))
29274         echo "Sleep $((period_second + 3)) seconds..."
29275
29276         out=$($LFS heat_get $DIR/$tfile)
29277         $LFS heat_get $DIR/$tfile
29278         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29279         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29280         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29281         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29282
29283         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29284                 4 * $decay_pct) / 100") -eq 1 ] ||
29285                 error "read sample ($readsample1) is wrong"
29286         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29287                 3 * $decay_pct) / 100") -eq 1 ] ||
29288                 error "write sample ($writesample1) is wrong"
29289         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29290                 20 * $decay_pct) / 100") -eq 1 ] ||
29291                 error "read bytes ($readbyte1) is wrong"
29292         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29293                 15 * $decay_pct) / 100") -eq 1 ] ||
29294                 error "write bytes ($writebyte1) is wrong"
29295
29296         echo "Turn off file heat for the file $DIR/$tfile"
29297         $LFS heat_set -o $DIR/$tfile
29298
29299         echo "QQQQ" > $DIR/$tfile
29300         echo "QQQQ" > $DIR/$tfile
29301         echo "QQQQ" > $DIR/$tfile
29302         cat $DIR/$tfile > /dev/null
29303         cat $DIR/$tfile > /dev/null
29304         cat $DIR/$tfile > /dev/null
29305         cat $DIR/$tfile > /dev/null
29306
29307         out=$($LFS heat_get $DIR/$tfile)
29308         $LFS heat_get $DIR/$tfile
29309         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29310         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29311         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29312         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29313
29314         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29315         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29316         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29317         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29318
29319         echo "Trun on file heat for the file $DIR/$tfile"
29320         $LFS heat_set -O $DIR/$tfile
29321
29322         echo "QQQQ" > $DIR/$tfile
29323         echo "QQQQ" > $DIR/$tfile
29324         echo "QQQQ" > $DIR/$tfile
29325         cat $DIR/$tfile > /dev/null
29326         cat $DIR/$tfile > /dev/null
29327         cat $DIR/$tfile > /dev/null
29328         cat $DIR/$tfile > /dev/null
29329
29330         out=$($LFS heat_get $DIR/$tfile)
29331         $LFS heat_get $DIR/$tfile
29332         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29333         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29334         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29335         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29336
29337         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29338         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29339         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29340         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29341
29342         $LFS heat_set -c $DIR/$tfile
29343         $LCTL set_param -n llite.*.file_heat=0
29344         echo "Turn off file heat support for the Lustre filesystem"
29345
29346         echo "QQQQ" > $DIR/$tfile
29347         echo "QQQQ" > $DIR/$tfile
29348         echo "QQQQ" > $DIR/$tfile
29349         cat $DIR/$tfile > /dev/null
29350         cat $DIR/$tfile > /dev/null
29351         cat $DIR/$tfile > /dev/null
29352         cat $DIR/$tfile > /dev/null
29353
29354         out=$($LFS heat_get $DIR/$tfile)
29355         $LFS heat_get $DIR/$tfile
29356         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29357         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29358         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29359         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29360
29361         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29362         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29363         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29364         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29365
29366         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29367         rm -f $DIR/$tfile
29368 }
29369 run_test 813 "File heat verfication"
29370
29371 test_814()
29372 {
29373         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29374         echo -n y >> $DIR/$tfile
29375         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29376         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29377 }
29378 run_test 814 "sparse cp works as expected (LU-12361)"
29379
29380 test_815()
29381 {
29382         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29383         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29384 }
29385 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29386
29387 test_816() {
29388         local ost1_imp=$(get_osc_import_name client ost1)
29389         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29390                          cut -d'.' -f2)
29391
29392         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29393         # ensure ost1 is connected
29394
29395         stat $DIR/$tfile >/dev/null || error "can't stat"
29396         wait_osc_import_state client ost1 FULL
29397         # no locks, no reqs to let the connection idle
29398         cancel_lru_locks osc
29399         lru_resize_disable osc
29400         local before
29401         local now
29402         before=$($LCTL get_param -n \
29403                  ldlm.namespaces.$imp_name.lru_size)
29404
29405         wait_osc_import_state client ost1 IDLE
29406         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29407         now=$($LCTL get_param -n \
29408               ldlm.namespaces.$imp_name.lru_size)
29409         [ $before == $now ] || error "lru_size changed $before != $now"
29410 }
29411 run_test 816 "do not reset lru_resize on idle reconnect"
29412
29413 cleanup_817() {
29414         umount $tmpdir
29415         exportfs -u localhost:$DIR/nfsexp
29416         rm -rf $DIR/nfsexp
29417 }
29418
29419 test_817() {
29420         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29421
29422         mkdir -p $DIR/nfsexp
29423         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29424                 error "failed to export nfs"
29425
29426         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29427         stack_trap cleanup_817 EXIT
29428
29429         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29430                 error "failed to mount nfs to $tmpdir"
29431
29432         cp /bin/true $tmpdir
29433         $DIR/nfsexp/true || error "failed to execute 'true' command"
29434 }
29435 run_test 817 "nfsd won't cache write lock for exec file"
29436
29437 test_818() {
29438         test_mkdir -i0 -c1 $DIR/$tdir
29439         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29440         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29441         stop $SINGLEMDS
29442
29443         # restore osp-syn threads
29444         stack_trap "fail $SINGLEMDS"
29445
29446         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29447         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29448         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29449                 error "start $SINGLEMDS failed"
29450         rm -rf $DIR/$tdir
29451
29452         local testid=$(echo $TESTNAME | tr '_' ' ')
29453
29454         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29455                 grep "run LFSCK" || error "run LFSCK is not suggested"
29456 }
29457 run_test 818 "unlink with failed llog"
29458
29459 test_819a() {
29460         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29461         cancel_lru_locks osc
29462         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29463         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29464         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29465         rm -f $TDIR/$tfile
29466 }
29467 run_test 819a "too big niobuf in read"
29468
29469 test_819b() {
29470         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29471         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29472         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29473         cancel_lru_locks osc
29474         sleep 1
29475         rm -f $TDIR/$tfile
29476 }
29477 run_test 819b "too big niobuf in write"
29478
29479
29480 function test_820_start_ost() {
29481         sleep 5
29482
29483         for num in $(seq $OSTCOUNT); do
29484                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29485         done
29486 }
29487
29488 test_820() {
29489         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29490
29491         mkdir $DIR/$tdir
29492         umount_client $MOUNT || error "umount failed"
29493         for num in $(seq $OSTCOUNT); do
29494                 stop ost$num
29495         done
29496
29497         # mount client with no active OSTs
29498         # so that the client can't initialize max LOV EA size
29499         # from OSC notifications
29500         mount_client $MOUNT || error "mount failed"
29501         # delay OST starting to keep this 0 max EA size for a while
29502         test_820_start_ost &
29503
29504         # create a directory on MDS2
29505         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29506                 error "Failed to create directory"
29507         # open intent should update default EA size
29508         # see mdc_update_max_ea_from_body()
29509         # notice this is the very first RPC to MDS2
29510         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29511         ret=$?
29512         echo $out
29513         # With SSK, this situation can lead to -EPERM being returned.
29514         # In that case, simply retry.
29515         if [ $ret -ne 0 ] && $SHARED_KEY; then
29516                 if echo "$out" | grep -q "not permitted"; then
29517                         cp /etc/services $DIR/$tdir/mds2
29518                         ret=$?
29519                 fi
29520         fi
29521         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29522 }
29523 run_test 820 "update max EA from open intent"
29524
29525 test_823() {
29526         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29527         local OST_MAX_PRECREATE=20000
29528
29529         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29530                 skip "Need MDS version at least 2.14.56"
29531
29532         save_lustre_params mds1 \
29533                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29534         do_facet $SINGLEMDS "$LCTL set_param -n \
29535                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29536         do_facet $SINGLEMDS "$LCTL set_param -n \
29537                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29538
29539         stack_trap "restore_lustre_params < $p; rm $p"
29540
29541         do_facet $SINGLEMDS "$LCTL set_param -n \
29542                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29543
29544         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29545                       osp.$FSNAME-OST0000*MDT0000.create_count")
29546         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29547                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29548         local expect_count=$(((($max/2)/256) * 256))
29549
29550         log "setting create_count to 100200:"
29551         log " -result- count: $count with max: $max, expecting: $expect_count"
29552
29553         [[ $count -eq expect_count ]] ||
29554                 error "Create count not set to max precreate."
29555 }
29556 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29557
29558 test_831() {
29559         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29560                 skip "Need MDS version 2.14.56"
29561
29562         local sync_changes=$(do_facet $SINGLEMDS \
29563                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29564
29565         [ "$sync_changes" -gt 100 ] &&
29566                 skip "Sync changes $sync_changes > 100 already"
29567
29568         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29569
29570         $LFS mkdir -i 0 $DIR/$tdir
29571         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29572
29573         save_lustre_params mds1 \
29574                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29575         save_lustre_params mds1 \
29576                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29577
29578         do_facet mds1 "$LCTL set_param -n \
29579                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29580                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29581         stack_trap "restore_lustre_params < $p" EXIT
29582
29583         createmany -o $DIR/$tdir/f- 1000
29584         unlinkmany $DIR/$tdir/f- 1000 &
29585         local UNLINK_PID=$!
29586
29587         while sleep 1; do
29588                 sync_changes=$(do_facet mds1 \
29589                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29590                 # the check in the code is racy, fail the test
29591                 # if the value above the limit by 10.
29592                 [ $sync_changes -gt 110 ] && {
29593                         kill -2 $UNLINK_PID
29594                         wait
29595                         error "osp changes throttling failed, $sync_changes>110"
29596                 }
29597                 kill -0 $UNLINK_PID 2> /dev/null || break
29598         done
29599         wait
29600 }
29601 run_test 831 "throttling unlink/setattr queuing on OSP"
29602
29603 test_832() {
29604         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29605         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29606                 skip "Need MDS version 2.15.52+"
29607         is_rmentry_supported || skip "rm_entry not supported"
29608
29609         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29610         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29611         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29612                 error "mkdir remote_dir failed"
29613         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29614                 error "mkdir striped_dir failed"
29615         touch $DIR/$tdir/file || error "touch file failed"
29616         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29617         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29618 }
29619 run_test 832 "lfs rm_entry"
29620
29621 #
29622 # tests that do cleanup/setup should be run at the end
29623 #
29624
29625 test_900() {
29626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29627         local ls
29628
29629         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29630         $LCTL set_param fail_loc=0x903
29631
29632         cancel_lru_locks MGC
29633
29634         FAIL_ON_ERROR=true cleanup
29635         FAIL_ON_ERROR=true setup
29636 }
29637 run_test 900 "umount should not race with any mgc requeue thread"
29638
29639 # LUS-6253/LU-11185
29640 test_901() {
29641         local old
29642         local count
29643         local oldc
29644         local newc
29645         local olds
29646         local news
29647         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29648
29649         # some get_param have a bug to handle dot in param name
29650         cancel_lru_locks MGC
29651         old=$(mount -t lustre | wc -l)
29652         # 1 config+sptlrpc
29653         # 2 params
29654         # 3 nodemap
29655         # 4 IR
29656         old=$((old * 4))
29657         oldc=0
29658         count=0
29659         while [ $old -ne $oldc ]; do
29660                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29661                 sleep 1
29662                 ((count++))
29663                 if [ $count -ge $TIMEOUT ]; then
29664                         error "too large timeout"
29665                 fi
29666         done
29667         umount_client $MOUNT || error "umount failed"
29668         mount_client $MOUNT || error "mount failed"
29669         cancel_lru_locks MGC
29670         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29671
29672         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29673
29674         return 0
29675 }
29676 run_test 901 "don't leak a mgc lock on client umount"
29677
29678 # LU-13377
29679 test_902() {
29680         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29681                 skip "client does not have LU-13377 fix"
29682         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29683         $LCTL set_param fail_loc=0x1415
29684         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29685         cancel_lru_locks osc
29686         rm -f $DIR/$tfile
29687 }
29688 run_test 902 "test short write doesn't hang lustre"
29689
29690 # LU-14711
29691 test_903() {
29692         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29693         echo "blah" > $DIR/${tfile}-2
29694         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29695         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29696         $LCTL set_param fail_loc=0x417 fail_val=20
29697
29698         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29699         sleep 1 # To start the destroy
29700         wait_destroy_complete 150 || error "Destroy taking too long"
29701         cat $DIR/$tfile > /dev/null || error "Evicted"
29702 }
29703 run_test 903 "Test long page discard does not cause evictions"
29704
29705 test_904() {
29706         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29707         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29708                 grep -q project || skip "skip project quota not supported"
29709
29710         local testfile="$DIR/$tdir/$tfile"
29711         local xattr="trusted.projid"
29712         local projid
29713         local mdts=$(comma_list $(mdts_nodes))
29714         local saved=$(do_facet mds1 $LCTL get_param -n \
29715                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29716
29717         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29718         stack_trap "do_nodes $mdts $LCTL set_param \
29719                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29720
29721         mkdir -p $DIR/$tdir
29722         touch $testfile
29723         #hide projid xattr on server
29724         $LFS project -p 1 $testfile ||
29725                 error "set $testfile project id failed"
29726         getfattr -m - $testfile | grep $xattr &&
29727                 error "do not show trusted.projid when disabled on server"
29728         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29729         #should be hidden when projid is 0
29730         $LFS project -p 0 $testfile ||
29731                 error "set $testfile project id failed"
29732         getfattr -m - $testfile | grep $xattr &&
29733                 error "do not show trusted.projid with project ID 0"
29734
29735         #still can getxattr explicitly
29736         projid=$(getfattr -n $xattr $testfile |
29737                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29738         [ $projid == "0" ] ||
29739                 error "projid expected 0 not $projid"
29740
29741         #set the projid via setxattr
29742         setfattr -n $xattr -v "1000" $testfile ||
29743                 error "setattr failed with $?"
29744         projid=($($LFS project $testfile))
29745         [ ${projid[0]} == "1000" ] ||
29746                 error "projid expected 1000 not $projid"
29747
29748         #check the new projid via getxattr
29749         $LFS project -p 1001 $testfile ||
29750                 error "set $testfile project id failed"
29751         getfattr -m - $testfile | grep $xattr ||
29752                 error "should show trusted.projid when project ID != 0"
29753         projid=$(getfattr -n $xattr $testfile |
29754                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29755         [ $projid == "1001" ] ||
29756                 error "projid expected 1001 not $projid"
29757
29758         #try to set invalid projid
29759         setfattr -n $xattr -v "4294967295" $testfile &&
29760                 error "set invalid projid should fail"
29761
29762         #remove the xattr means setting projid to 0
29763         setfattr -x $xattr $testfile ||
29764                 error "setfattr failed with $?"
29765         projid=($($LFS project $testfile))
29766         [ ${projid[0]} == "0" ] ||
29767                 error "projid expected 0 not $projid"
29768
29769         #should be hidden when parent has inherit flag and same projid
29770         $LFS project -srp 1002 $DIR/$tdir ||
29771                 error "set $tdir project id failed"
29772         getfattr -m - $testfile | grep $xattr &&
29773                 error "do not show trusted.projid with inherit flag"
29774
29775         #still can getxattr explicitly
29776         projid=$(getfattr -n $xattr $testfile |
29777                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29778         [ $projid == "1002" ] ||
29779                 error "projid expected 1002 not $projid"
29780 }
29781 run_test 904 "virtual project ID xattr"
29782
29783 # LU-8582
29784 test_905() {
29785         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29786                 skip "lustre < 2.8.54 does not support ladvise"
29787
29788         remote_ost_nodsh && skip "remote OST with nodsh"
29789         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29790
29791         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29792
29793         #define OBD_FAIL_OST_OPCODE 0x253
29794         # OST_LADVISE = 21
29795         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29796         $LFS ladvise -a willread $DIR/$tfile &&
29797                 error "unexpected success of ladvise with fault injection"
29798         $LFS ladvise -a willread $DIR/$tfile |&
29799                 grep -q "Operation not supported"
29800         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29801 }
29802 run_test 905 "bad or new opcode should not stuck client"
29803
29804 test_906() {
29805         grep -q io_uring_setup /proc/kallsyms ||
29806                 skip "Client OS does not support io_uring I/O engine"
29807         io_uring_probe || skip "kernel does not support io_uring fully"
29808         which fio || skip_env "no fio installed"
29809         fio --enghelp | grep -q io_uring ||
29810                 skip_env "fio does not support io_uring I/O engine"
29811
29812         local file=$DIR/$tfile
29813         local ioengine="io_uring"
29814         local numjobs=2
29815         local size=50M
29816
29817         fio --name=seqwrite --ioengine=$ioengine        \
29818                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29819                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29820                 error "fio seqwrite $file failed"
29821
29822         fio --name=seqread --ioengine=$ioengine \
29823                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29824                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29825                 error "fio seqread $file failed"
29826
29827         rm -f $file || error "rm -f $file failed"
29828 }
29829 run_test 906 "Simple test for io_uring I/O engine via fio"
29830
29831 complete $SECONDS
29832 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29833 check_and_cleanup_lustre
29834 if [ "$I_MOUNTED" != "yes" ]; then
29835         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29836 fi
29837 exit_status