Whamcloud - gitweb
LU-14139 statahead: add stats for batch RPC requests
[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         $LCTL set_param mdc.*.batch_stats=0
13579
13580         rm -rf $DIR/$tdir
13581         test_mkdir $DIR/$tdir
13582         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
13583         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
13584         MULT=10
13585         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
13586                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
13587
13588                 max=$(lctl get_param -n llite.*.statahead_max | head -n 1)
13589                 lctl set_param -n llite.*.statahead_max 0
13590                 lctl get_param llite.*.statahead_max
13591                 cancel_lru_locks mdc
13592                 cancel_lru_locks osc
13593                 stime=$(date +%s)
13594                 time $lsx $DIR/$tdir | wc -l
13595                 etime=$(date +%s)
13596                 delta=$((etime - stime))
13597                 log "$lsx $i files without statahead: $delta sec"
13598                 lctl set_param llite.*.statahead_max=$max
13599
13600                 swrong=$(lctl get_param -n llite.*.statahead_stats |
13601                          awk '/statahead.wrong:/ { print $NF }')
13602                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
13603                 cancel_lru_locks mdc
13604                 cancel_lru_locks osc
13605                 stime=$(date +%s)
13606                 time $lsx $DIR/$tdir | wc -l
13607                 etime=$(date +%s)
13608                 delta_sa=$((etime - stime))
13609                 log "$lsx $i files with statahead: $delta_sa sec"
13610                 lctl get_param -n llite.*.statahead_stats
13611                 ewrong=$(lctl get_param -n llite.*.statahead_stats |
13612                          awk '/statahead.wrong:/ { print $NF }')
13613
13614                 [[ $swrong -lt $ewrong ]] &&
13615                         log "statahead was stopped, maybe too many locks held!"
13616                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
13617
13618                 if (( $delta_sa*100 > $delta*105 && $delta_sa > $delta+2)); then
13619                         max=$(lctl get_param -n llite.*.statahead_max |
13620                                 head -n 1)
13621                         lctl set_param -n llite.*.statahead_max 0
13622                         lctl get_param llite.*.statahead_max
13623                         cancel_lru_locks mdc
13624                         cancel_lru_locks osc
13625                         stime=$(date +%s)
13626                         time $lsx $DIR/$tdir | wc -l
13627                         etime=$(date +%s)
13628                         delta=$((etime - stime))
13629                         log "$lsx $i files again without statahead: $delta sec"
13630                         lctl set_param llite.*.statahead_max=$max
13631                         if (( $delta_sa*100 > delta*105 && delta_sa > delta+2 )); then
13632                                 if [ $SLOWOK -eq 0 ]; then
13633                                         error "$lsx $i files is slower with statahead!"
13634                                 else
13635                                         log "$lsx $i files is slower with statahead!"
13636                                 fi
13637                                 break
13638                         fi
13639                 fi
13640
13641                 [ $delta -gt 20 ] && break
13642                 [ $delta -gt 8 ] && MULT=$((50 / delta))
13643                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
13644         done
13645         log "$lsx done"
13646
13647         stime=$(date +%s)
13648         rm -r $DIR/$tdir
13649         sync
13650         etime=$(date +%s)
13651         delta=$((etime - stime))
13652         log "rm -r $DIR/$tdir/: $delta seconds"
13653         log "rm done"
13654         lctl get_param -n llite.*.statahead_stats
13655         $LCTL get_param mdc.*.batch_stats
13656 }
13657
13658 test_123aa() {
13659         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13660
13661         test_123a_base "ls -l"
13662 }
13663 run_test 123aa "verify statahead work"
13664
13665 test_123ab() {
13666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13667
13668         statx_supported || skip_env "Test must be statx() syscall supported"
13669
13670         test_123a_base "$STATX -l"
13671 }
13672 run_test 123ab "verify statahead work by using statx"
13673
13674 test_123ac() {
13675         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13676
13677         statx_supported || skip_env "Test must be statx() syscall supported"
13678
13679         local rpcs_before
13680         local rpcs_after
13681         local agl_before
13682         local agl_after
13683
13684         cancel_lru_locks $OSC
13685         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13686         agl_before=$($LCTL get_param -n llite.*.statahead_stats |
13687                      awk '/agl.total:/ { print $NF }')
13688         test_123a_base "$STATX -c \"%n %i %A %h %u %g %W %X %Z\" -D"
13689         test_123a_base "$STATX --cached=always -D"
13690         agl_after=$($LCTL get_param -n llite.*.statahead_stats |
13691                     awk '/agl.total:/ { print $NF }')
13692         [ $agl_before -eq $agl_after ] ||
13693                 error "Should not trigger AGL thread - $agl_before:$agl_after"
13694         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
13695         [ $rpcs_after -eq $rpcs_before ] ||
13696                 error "$STATX should not send glimpse RPCs to $OSC"
13697 }
13698 run_test 123ac "verify statahead work by using statx without glimpse RPCs"
13699
13700 test_123b () { # statahead(bug 15027)
13701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13702
13703         test_mkdir $DIR/$tdir
13704         createmany -o $DIR/$tdir/$tfile-%d 1000
13705
13706         cancel_lru_locks mdc
13707         cancel_lru_locks osc
13708
13709 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
13710         lctl set_param fail_loc=0x80000803
13711         ls -lR $DIR/$tdir > /dev/null
13712         log "ls done"
13713         lctl set_param fail_loc=0x0
13714         lctl get_param -n llite.*.statahead_stats
13715         rm -r $DIR/$tdir
13716         sync
13717
13718 }
13719 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
13720
13721 test_123c() {
13722         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
13723
13724         test_mkdir -i 0 -c 1 $DIR/$tdir.0
13725         test_mkdir -i 1 -c 1 $DIR/$tdir.1
13726         touch $DIR/$tdir.1/{1..3}
13727         mv $DIR/$tdir.1/{1..3} $DIR/$tdir.0
13728
13729         remount_client $MOUNT
13730
13731         $MULTIOP $DIR/$tdir.0 Q
13732
13733         # let statahead to complete
13734         ls -l $DIR/$tdir.0 > /dev/null
13735
13736         testid=$(echo $TESTNAME | tr '_' ' ')
13737         dmesg | tac | sed "/$testid/,$ d" | grep "Can not initialize inode" &&
13738                 error "statahead warning" || true
13739 }
13740 run_test 123c "Can not initialize inode warning on DNE statahead"
13741
13742 test_123d() {
13743         local num=100
13744         local swrong
13745         local ewrong
13746
13747         test_mkdir -c -1 $DIR/$tdir || error "test_mkdir $DIR/$tdir failed"
13748         $LFS setdirstripe -D -c $MDSCOUNT $DIR/$tdir ||
13749                 error "setdirstripe $DIR/$tdir failed"
13750         createmany -d $DIR/$tdir/$tfile $num || error "createmany $num failed"
13751         remount_client $MOUNT
13752         $LCTL get_param llite.*.statahead_max
13753         $LCTL set_param llite.*.statahead_stats=0 ||
13754                 error "clear statahead_stats failed"
13755         swrong=$(lctl get_param -n llite.*.statahead_stats |
13756                  awk '/statahead.wrong:/ { print $NF }')
13757         ls -l $DIR/$tdir || error "ls -l $DIR/$tdir failed"
13758         # wait for statahead thread finished to update hit/miss stats.
13759         sleep 1
13760         $LCTL get_param -n llite.*.statahead_stats
13761         ewrong=$(lctl get_param -n llite.*.statahead_stats |
13762                  awk '/statahead.wrong:/ { print $NF }')
13763         (( $swrong == $ewrong )) ||
13764                 log "statahead was stopped, maybe too many locks held!"
13765 }
13766 run_test 123d "Statahead on striped directories works correctly"
13767
13768 test_124a() {
13769         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13770         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13771                 skip_env "no lru resize on server"
13772
13773         local NR=2000
13774
13775         test_mkdir $DIR/$tdir
13776
13777         log "create $NR files at $DIR/$tdir"
13778         createmany -o $DIR/$tdir/f $NR ||
13779                 error "failed to create $NR files in $DIR/$tdir"
13780
13781         cancel_lru_locks mdc
13782         ls -l $DIR/$tdir > /dev/null
13783
13784         local NSDIR=""
13785         local LRU_SIZE=0
13786         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
13787                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
13788                 LRU_SIZE=$($LCTL get_param -n $PARAM)
13789                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
13790                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
13791                         log "NSDIR=$NSDIR"
13792                         log "NS=$(basename $NSDIR)"
13793                         break
13794                 fi
13795         done
13796
13797         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
13798                 skip "Not enough cached locks created!"
13799         fi
13800         log "LRU=$LRU_SIZE"
13801
13802         local SLEEP=30
13803
13804         # We know that lru resize allows one client to hold $LIMIT locks
13805         # for 10h. After that locks begin to be killed by client.
13806         local MAX_HRS=10
13807         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
13808         log "LIMIT=$LIMIT"
13809         if [ $LIMIT -lt $LRU_SIZE ]; then
13810                 skip "Limit is too small $LIMIT"
13811         fi
13812
13813         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
13814         # killing locks. Some time was spent for creating locks. This means
13815         # that up to the moment of sleep finish we must have killed some of
13816         # them (10-100 locks). This depends on how fast ther were created.
13817         # Many of them were touched in almost the same moment and thus will
13818         # be killed in groups.
13819         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE * 100))
13820
13821         # Use $LRU_SIZE_B here to take into account real number of locks
13822         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
13823         local LRU_SIZE_B=$LRU_SIZE
13824         log "LVF=$LVF"
13825         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
13826         log "OLD_LVF=$OLD_LVF"
13827         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
13828
13829         # Let's make sure that we really have some margin. Client checks
13830         # cached locks every 10 sec.
13831         SLEEP=$((SLEEP+20))
13832         log "Sleep ${SLEEP} sec"
13833         local SEC=0
13834         while ((SEC<$SLEEP)); do
13835                 echo -n "..."
13836                 sleep 5
13837                 SEC=$((SEC+5))
13838                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
13839                 echo -n "$LRU_SIZE"
13840         done
13841         echo ""
13842         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
13843         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
13844
13845         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
13846                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
13847                 unlinkmany $DIR/$tdir/f $NR
13848                 return
13849         }
13850
13851         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
13852         log "unlink $NR files at $DIR/$tdir"
13853         unlinkmany $DIR/$tdir/f $NR
13854 }
13855 run_test 124a "lru resize ======================================="
13856
13857 get_max_pool_limit()
13858 {
13859         local limit=$($LCTL get_param \
13860                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
13861         local max=0
13862         for l in $limit; do
13863                 if [[ $l -gt $max ]]; then
13864                         max=$l
13865                 fi
13866         done
13867         echo $max
13868 }
13869
13870 test_124b() {
13871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13872         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13873                 skip_env "no lru resize on server"
13874
13875         LIMIT=$(get_max_pool_limit)
13876
13877         NR=$(($(default_lru_size)*20))
13878         if [[ $NR -gt $LIMIT ]]; then
13879                 log "Limit lock number by $LIMIT locks"
13880                 NR=$LIMIT
13881         fi
13882
13883         IFree=$(mdsrate_inodes_available)
13884         if [ $IFree -lt $NR ]; then
13885                 log "Limit lock number by $IFree inodes"
13886                 NR=$IFree
13887         fi
13888
13889         lru_resize_disable mdc
13890         test_mkdir -p $DIR/$tdir/disable_lru_resize
13891
13892         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
13893         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
13894         cancel_lru_locks mdc
13895         stime=`date +%s`
13896         PID=""
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         sleep 2
13903         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
13904         PID="$PID $!"
13905         wait $PID
13906         etime=`date +%s`
13907         nolruresize_delta=$((etime-stime))
13908         log "ls -la time: $nolruresize_delta seconds"
13909         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13910         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
13911
13912         lru_resize_enable mdc
13913         test_mkdir -p $DIR/$tdir/enable_lru_resize
13914
13915         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
13916         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
13917         cancel_lru_locks mdc
13918         stime=`date +%s`
13919         PID=""
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         sleep 2
13926         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
13927         PID="$PID $!"
13928         wait $PID
13929         etime=`date +%s`
13930         lruresize_delta=$((etime-stime))
13931         log "ls -la time: $lruresize_delta seconds"
13932         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
13933
13934         if [ $lruresize_delta -gt $nolruresize_delta ]; then
13935                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
13936         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
13937                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
13938         else
13939                 log "lru resize performs the same with no lru resize"
13940         fi
13941         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
13942 }
13943 run_test 124b "lru resize (performance test) ======================="
13944
13945 test_124c() {
13946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13947         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13948                 skip_env "no lru resize on server"
13949
13950         # cache ununsed locks on client
13951         local nr=100
13952         cancel_lru_locks mdc
13953         test_mkdir $DIR/$tdir
13954         createmany -o $DIR/$tdir/f $nr ||
13955                 error "failed to create $nr files in $DIR/$tdir"
13956         ls -l $DIR/$tdir > /dev/null
13957
13958         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13959         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
13960         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
13961         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
13962         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
13963
13964         # set lru_max_age to 1 sec
13965         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
13966         echo "sleep $((recalc_p * 2)) seconds..."
13967         sleep $((recalc_p * 2))
13968
13969         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
13970         # restore lru_max_age
13971         $LCTL set_param -n $nsdir.lru_max_age $max_age
13972         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
13973         unlinkmany $DIR/$tdir/f $nr
13974 }
13975 run_test 124c "LRUR cancel very aged locks"
13976
13977 test_124d() {
13978         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13979         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
13980                 skip_env "no lru resize on server"
13981
13982         # cache ununsed locks on client
13983         local nr=100
13984
13985         lru_resize_disable mdc
13986         stack_trap "lru_resize_enable mdc" EXIT
13987
13988         cancel_lru_locks mdc
13989
13990         # asynchronous object destroy at MDT could cause bl ast to client
13991         test_mkdir $DIR/$tdir
13992         createmany -o $DIR/$tdir/f $nr ||
13993                 error "failed to create $nr files in $DIR/$tdir"
13994         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
13995
13996         ls -l $DIR/$tdir > /dev/null
13997
13998         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
13999         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
14000         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
14001         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
14002
14003         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
14004
14005         # set lru_max_age to 1 sec
14006         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
14007         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
14008
14009         echo "sleep $((recalc_p * 2)) seconds..."
14010         sleep $((recalc_p * 2))
14011
14012         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
14013
14014         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
14015 }
14016 run_test 124d "cancel very aged locks if lru-resize diasbaled"
14017
14018 test_125() { # 13358
14019         $LCTL get_param -n llite.*.client_type | grep -q local ||
14020                 skip "must run as local client"
14021         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
14022                 skip_env "must have acl enabled"
14023         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
14024
14025         test_mkdir $DIR/$tdir
14026         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
14027         setfacl -R -m u:$USER0:rwx $DIR/$tdir ||
14028                 error "setfacl $DIR/$tdir failed"
14029         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
14030 }
14031 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
14032
14033 test_126() { # bug 12829/13455
14034         $GSS && skip_env "must run as gss disabled"
14035         $LCTL get_param -n llite.*.client_type | grep -q local ||
14036                 skip "must run as local client"
14037         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
14038
14039         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
14040         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
14041         rm -f $DIR/$tfile
14042         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
14043 }
14044 run_test 126 "check that the fsgid provided by the client is taken into account"
14045
14046 test_127a() { # bug 15521
14047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14048         local name count samp unit min max sum sumsq
14049         local tmpfile=$TMP/$tfile.tmp
14050
14051         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
14052         echo "stats before reset"
14053         stack_trap "rm -f $tmpfile"
14054         local now=$(date +%s)
14055
14056         $LCTL get_param osc.*.stats | tee $tmpfile
14057
14058         local snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14059         local start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14060         local elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14061         local uptime=$(awk '{ print $1 }' /proc/uptime)
14062
14063         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14064         (( ${snapshot_time%\.*} >= $now - 5 &&
14065            ${snapshot_time%\.*} <= $now + 5 )) ||
14066                 error "snapshot_time=$snapshot_time != now=$now"
14067         # elapsed _should_ be from mount, but at least less than uptime
14068         (( ${elapsed%\.*} < ${uptime%\.*} )) ||
14069                 error "elapsed=$elapsed > uptime=$uptime"
14070         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14071            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14072                 error "elapsed=$elapsed != $snapshot_time - $start_time"
14073
14074         $LCTL set_param osc.*.stats=0
14075         local reset=$(date +%s)
14076         local fsize=$((2048 * 1024))
14077
14078         dd if=/dev/zero of=$DIR/$tfile bs=$fsize count=1
14079         cancel_lru_locks osc
14080         dd if=$DIR/$tfile of=/dev/null bs=$fsize
14081
14082         now=$(date +%s)
14083         $LCTL get_param osc.*0000-osc-*.stats > $tmpfile
14084         while read name count samp unit min max sum sumsq; do
14085                 [[ "$samp" == "samples" ]] || continue
14086
14087                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14088                 [ ! $min ] && error "Missing min value for $name proc entry"
14089                 eval $name=$count || error "Wrong proc format"
14090
14091                 case $name in
14092                 read_bytes|write_bytes)
14093                         [[ "$unit" =~ "bytes" ]] ||
14094                                 error "unit is not 'bytes': $unit"
14095                         (( $min >= 4096 )) || error "min is too small: $min"
14096                         (( $min <= $fsize )) || error "min is too big: $min"
14097                         (( $max >= 4096 )) || error "max is too small: $max"
14098                         (( $max <= $fsize )) || error "max is too big: $max"
14099                         (( $sum == $fsize )) || error "sum is wrong: $sum"
14100                         (( $sumsq >= ($fsize / 4096) * (4096 * 4096) )) ||
14101                                 error "sumsquare is too small: $sumsq"
14102                         (( $sumsq <= $fsize * $fsize )) ||
14103                                 error "sumsquare is too big: $sumsq"
14104                         ;;
14105                 ost_read|ost_write)
14106                         [[ "$unit" =~ "usec" ]] ||
14107                                 error "unit is not 'usec': $unit"
14108                         ;;
14109                 *)      ;;
14110                 esac
14111         done < $tmpfile
14112
14113         #check that we actually got some stats
14114         [ "$read_bytes" ] || error "Missing read_bytes stats"
14115         [ "$write_bytes" ] || error "Missing write_bytes stats"
14116         [ "$read_bytes" != 0 ] || error "no read done"
14117         [ "$write_bytes" != 0 ] || error "no write done"
14118
14119         snapshot_time=$(awk '/snapshot_time/ { print $2; exit }' $tmpfile)
14120         start_time=$(awk '/start_time/ { print $2; exit }' $tmpfile)
14121         elapsed=$(awk '/elapsed_time/ { print $2; exit }' $tmpfile)
14122
14123         # snapshot_time should match POSIX epoch time, allow some delta for VMs
14124         (( ${snapshot_time%\.*} >= $now - 5 &&
14125            ${snapshot_time%\.*} <= $now + 5 )) ||
14126                 error "reset snapshot_time=$snapshot_time != now=$now"
14127         # elapsed should be from time of stats reset
14128         (( ${elapsed%\.*} >= $now - $reset - 2 &&
14129            ${elapsed%\.*} <= $now - $reset + 2 )) ||
14130                 error "reset elapsed=$elapsed > $now - $reset"
14131         (( ${snapshot_time%\.*} - ${start_time%\.*} >= ${elapsed%\.*} - 2 &&
14132            ${snapshot_time%\.*} - ${start_time%\.*} <= ${elapsed%\.*} + 2 )) ||
14133                 error "reset elapsed=$elapsed != $snapshot_time - $start_time"
14134 }
14135 run_test 127a "verify the client stats are sane"
14136
14137 test_127b() { # bug LU-333
14138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14139         local name count samp unit min max sum sumsq
14140
14141         echo "stats before reset"
14142         $LCTL get_param llite.*.stats
14143         $LCTL set_param llite.*.stats=0
14144
14145         # perform 2 reads and writes so MAX is different from SUM.
14146         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14147         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
14148         cancel_lru_locks osc
14149         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14150         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
14151
14152         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
14153         stack_trap "rm -f $TMP/$tfile.tmp"
14154         while read name count samp unit min max sum sumsq; do
14155                 echo "got name=$name count=$count unit=$unit min=$min max=$max"
14156                 eval $name=$count || error "Wrong proc format"
14157
14158                 case $name in
14159                 read_bytes|write_bytes)
14160                         [[ "$unit" =~ "bytes" ]] ||
14161                                 error "unit is not 'bytes': $unit"
14162                         (( $count == 2 )) || error "count is not 2: $count"
14163                         (( $min == $PAGE_SIZE )) ||
14164                                 error "min is not $PAGE_SIZE: $min"
14165                         (( $max == $PAGE_SIZE )) ||
14166                                 error "max is not $PAGE_SIZE: $max"
14167                         (( $sum == $PAGE_SIZE * 2 )) ||
14168                                 error "sum is not $((PAGE_SIZE * 2)): $sum"
14169                         ;;
14170                 read|write)
14171                         [[ "$unit" =~ "usec" ]] ||
14172                                 error "unit is not 'usec': $unit"
14173                         ;;
14174                 *)      ;;
14175                 esac
14176         done < $TMP/$tfile.tmp
14177
14178         #check that we actually got some stats
14179         [ "$read_bytes" ] || error "Missing read_bytes stats"
14180         [ "$write_bytes" ] || error "Missing write_bytes stats"
14181         [ "$read_bytes" != 0 ] || error "no read done"
14182         [ "$write_bytes" != 0 ] || error "no write done"
14183 }
14184 run_test 127b "verify the llite client stats are sane"
14185
14186 test_127c() { # LU-12394
14187         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
14188         local size
14189         local bsize
14190         local reads
14191         local writes
14192         local count
14193
14194         $LCTL set_param llite.*.extents_stats=1
14195         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
14196
14197         # Use two stripes so there is enough space in default config
14198         $LFS setstripe -c 2 $DIR/$tfile
14199
14200         # Extent stats start at 0-4K and go in power of two buckets
14201         # LL_HIST_START = 12 --> 2^12 = 4K
14202         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
14203         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
14204         # small configs
14205         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
14206                 do
14207                 # Write and read, 2x each, second time at a non-zero offset
14208                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
14209                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
14210                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
14211                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
14212                 rm -f $DIR/$tfile
14213         done
14214
14215         $LCTL get_param llite.*.extents_stats
14216
14217         count=2
14218         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
14219                 do
14220                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
14221                                 grep -m 1 $bsize)
14222                 reads=$(echo $bucket | awk '{print $5}')
14223                 writes=$(echo $bucket | awk '{print $9}')
14224                 [ "$reads" -eq $count ] ||
14225                         error "$reads reads in < $bsize bucket, expect $count"
14226                 [ "$writes" -eq $count ] ||
14227                         error "$writes writes in < $bsize bucket, expect $count"
14228         done
14229
14230         # Test mmap write and read
14231         $LCTL set_param llite.*.extents_stats=c
14232         size=512
14233         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
14234         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
14235         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
14236
14237         $LCTL get_param llite.*.extents_stats
14238
14239         count=$(((size*1024) / PAGE_SIZE))
14240
14241         bsize=$((2 * PAGE_SIZE / 1024))K
14242
14243         bucket=$($LCTL get_param -n llite.*.extents_stats |
14244                         grep -m 1 $bsize)
14245         reads=$(echo $bucket | awk '{print $5}')
14246         writes=$(echo $bucket | awk '{print $9}')
14247         # mmap writes fault in the page first, creating an additonal read
14248         [ "$reads" -eq $((2 * count)) ] ||
14249                 error "$reads reads in < $bsize bucket, expect $count"
14250         [ "$writes" -eq $count ] ||
14251                 error "$writes writes in < $bsize bucket, expect $count"
14252 }
14253 run_test 127c "test llite extent stats with regular & mmap i/o"
14254
14255 test_128() { # bug 15212
14256         touch $DIR/$tfile
14257         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
14258                 find $DIR/$tfile
14259                 find $DIR/$tfile
14260         EOF
14261
14262         result=$(grep error $TMP/$tfile.log)
14263         rm -f $DIR/$tfile $TMP/$tfile.log
14264         [ -z "$result" ] ||
14265                 error "consecutive find's under interactive lfs failed"
14266 }
14267 run_test 128 "interactive lfs for 2 consecutive find's"
14268
14269 set_dir_limits () {
14270         local mntdev
14271         local canondev
14272         local node
14273
14274         local ldproc=/proc/fs/ldiskfs
14275         local facets=$(get_facets MDS)
14276
14277         for facet in ${facets//,/ }; do
14278                 canondev=$(ldiskfs_canon \
14279                            *.$(convert_facet2label $facet).mntdev $facet)
14280                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
14281                         ldproc=/sys/fs/ldiskfs
14282                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
14283                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
14284         done
14285 }
14286
14287 check_mds_dmesg() {
14288         local facets=$(get_facets MDS)
14289         for facet in ${facets//,/ }; do
14290                 do_facet $facet "dmesg | tail -3 | grep $1" && return 0
14291         done
14292         return 1
14293 }
14294
14295 test_129() {
14296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14297         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
14298                 skip "Need MDS version with at least 2.5.56"
14299         if [ "$mds1_FSTYPE" != ldiskfs ]; then
14300                 skip_env "ldiskfs only test"
14301         fi
14302         remote_mds_nodsh && skip "remote MDS with nodsh"
14303
14304         local ENOSPC=28
14305         local has_warning=false
14306
14307         rm -rf $DIR/$tdir
14308         mkdir -p $DIR/$tdir
14309
14310         # block size of mds1
14311         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 8))
14312         set_dir_limits $maxsize $((maxsize * 6 / 8))
14313         stack_trap "set_dir_limits 0 0"
14314         stack_trap "unlinkmany $DIR/$tdir/file_base_ 2000 || true"
14315         local dirsize=$(stat -c%s "$DIR/$tdir")
14316         local nfiles=0
14317         while (( $dirsize <= $maxsize )); do
14318                 $MCREATE $DIR/$tdir/file_base_$nfiles
14319                 rc=$?
14320                 # check two errors:
14321                 # ENOSPC for ext4 max_dir_size, which has been used since
14322                 # kernel v3.6-rc1-8-gdf981d03ee, lustre v2_4_50_0-79-gaed82035c0
14323                 if (( rc == ENOSPC )); then
14324                         set_dir_limits 0 0
14325                         echo "rc=$rc returned as expected after $nfiles files"
14326
14327                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
14328                                 error "create failed w/o dir size limit"
14329
14330                         # messages may be rate limited if test is run repeatedly
14331                         check_mds_dmesg '"is approaching max"' ||
14332                                 echo "warning message should be output"
14333                         check_mds_dmesg '"has reached max"' ||
14334                                 echo "reached message should be output"
14335
14336                         dirsize=$(stat -c%s "$DIR/$tdir")
14337
14338                         [[ $dirsize -ge $maxsize ]] && return 0
14339                         error "dirsize $dirsize < $maxsize after $nfiles files"
14340                 elif (( rc != 0 )); then
14341                         break
14342                 fi
14343                 nfiles=$((nfiles + 1))
14344                 dirsize=$(stat -c%s "$DIR/$tdir")
14345         done
14346
14347         error "rc=$rc, size=$dirsize/$maxsize, mdt=$MDSCOUNT, nfiles=$nfiles"
14348 }
14349 run_test 129 "test directory size limit ========================"
14350
14351 OLDIFS="$IFS"
14352 cleanup_130() {
14353         trap 0
14354         IFS="$OLDIFS"
14355 }
14356
14357 test_130a() {
14358         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
14359         [[ -z "$filefrag_op" ]] || skip_env "filefrag does not support FIEMAP"
14360
14361         trap cleanup_130 EXIT RETURN
14362
14363         local fm_file=$DIR/$tfile
14364         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
14365         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
14366                 error "dd failed for $fm_file"
14367
14368         # LU-1795: test filefrag/FIEMAP once, even if unsupported on ZFS
14369         filefrag -ves $fm_file
14370         local rc=$?
14371         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14372                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14373         (( $rc == 0 )) || error "filefrag $fm_file failed"
14374
14375         filefrag_op=$(filefrag -ve -k $fm_file |
14376                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14377         local lun=$($LFS getstripe -i $fm_file)
14378
14379         local start_blk=$(echo $filefrag_op | cut -d: -f2 | cut -d. -f1)
14380         IFS=$'\n'
14381         local tot_len=0
14382         for line in $filefrag_op; do
14383                 local frag_lun=$(echo $line | cut -d: -f5)
14384                 local ext_len=$(echo $line | cut -d: -f4)
14385
14386                 if (( $frag_lun != $lun )); then
14387                         error "FIEMAP on 1-stripe file($fm_file) failed"
14388                         return
14389                 fi
14390                 (( tot_len += ext_len ))
14391         done
14392
14393         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
14394                 error "FIEMAP on 1-stripe file($fm_file) failed"
14395                 return
14396         fi
14397
14398         echo "FIEMAP on single striped file succeeded"
14399 }
14400 run_test 130a "FIEMAP (1-stripe file)"
14401
14402 test_130b() {
14403         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14404
14405         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14406         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14407         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14408                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14409
14410         trap cleanup_130 EXIT RETURN
14411
14412         local fm_file=$DIR/$tfile
14413         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14414                 error "setstripe on $fm_file"
14415
14416         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
14417                 error "dd failed on $fm_file"
14418
14419         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14420         filefrag_op=$(filefrag -ve -k $fm_file |
14421                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14422
14423         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14424                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14425
14426         IFS=$'\n'
14427         local tot_len=0
14428         local num_luns=1
14429
14430         for line in $filefrag_op; do
14431                 local frag_lun=$(echo $line | cut -d: -f5 |
14432                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14433                 local ext_len=$(echo $line | cut -d: -f4)
14434                 if (( $frag_lun != $last_lun )); then
14435                         if (( tot_len != 1024 )); then
14436                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14437                                 return
14438                         else
14439                                 (( num_luns += 1 ))
14440                                 tot_len=0
14441                         fi
14442                 fi
14443                 (( tot_len += ext_len ))
14444                 last_lun=$frag_lun
14445         done
14446         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
14447                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14448                 return
14449         fi
14450
14451         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
14452 }
14453 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
14454
14455 test_130c() {
14456         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14457
14458         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14459         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14460         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14461                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14462
14463         trap cleanup_130 EXIT RETURN
14464
14465         local fm_file=$DIR/$tfile
14466         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
14467
14468         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
14469                 error "dd failed on $fm_file"
14470
14471         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14472         filefrag_op=$(filefrag -ve -k $fm_file |
14473                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14474
14475         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14476                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14477
14478         IFS=$'\n'
14479         local tot_len=0
14480         local num_luns=1
14481         for line in $filefrag_op; do
14482                 local frag_lun=$(echo $line | cut -d: -f5 |
14483                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14484                 local ext_len=$(echo $line | cut -d: -f4)
14485                 if (( $frag_lun != $last_lun )); then
14486                         local logical=$(echo $line | cut -d: -f2 | cut -d. -f1)
14487                         if (( logical != 512 )); then
14488                                 error "FIEMAP on $fm_file failed; returned logical start for lun $logical instead of 512"
14489                                 return
14490                         fi
14491                         if (( tot_len != 512 )); then
14492                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14493                                 return
14494                         else
14495                                 (( num_luns += 1 ))
14496                                 tot_len=0
14497                         fi
14498                 fi
14499                 (( tot_len += ext_len ))
14500                 last_lun=$frag_lun
14501         done
14502         if (( num_luns != 2 || tot_len != 512 )); then
14503                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14504                 return
14505         fi
14506
14507         echo "FIEMAP on 2-stripe file with hole succeeded"
14508 }
14509 run_test 130c "FIEMAP (2-stripe file with hole)"
14510
14511 test_130d() {
14512         (( $OSTCOUNT >= 3 )) || skip "needs >= 3 OSTs"
14513
14514         filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14515         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14516         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14517                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14518
14519         trap cleanup_130 EXIT RETURN
14520
14521         local fm_file=$DIR/$tfile
14522         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
14523                         error "setstripe on $fm_file"
14524
14525         local actual_stripe_count=$($LFS getstripe -c $fm_file)
14526         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
14527                 error "dd failed on $fm_file"
14528
14529         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14530         filefrag_op=$(filefrag -ve -k $fm_file |
14531                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14532
14533         local last_lun=$(echo $filefrag_op | cut -d: -f5 |
14534                          sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14535
14536         IFS=$'\n'
14537         local tot_len=0
14538         local num_luns=1
14539         for line in $filefrag_op; do
14540                 local frag_lun=$(echo $line | cut -d: -f5 |
14541                                  sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
14542                 local ext_len=$(echo $line | cut -d: -f4)
14543                 if (( $frag_lun != $last_lun )); then
14544                         if (( tot_len != 1024 )); then
14545                                 error "FIEMAP on $fm_file failed; returned len $tot_len for OST $last_lun instead of 1024"
14546                                 return
14547                         else
14548                                 (( num_luns += 1 ))
14549                                 local tot_len=0
14550                         fi
14551                 fi
14552                 (( tot_len += ext_len ))
14553                 last_lun=$frag_lun
14554         done
14555         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
14556                 error "FIEMAP on $fm_file failed; returned wrong number of luns or wrong len for OST $last_lun"
14557                 return
14558         fi
14559
14560         echo "FIEMAP on N-stripe file succeeded"
14561 }
14562 run_test 130d "FIEMAP (N-stripe file)"
14563
14564 test_130e() {
14565         (( $OSTCOUNT >= 2 )) || skip "needs >= 2 OSTs"
14566
14567         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14568         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14569         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14570                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14571
14572         trap cleanup_130 EXIT RETURN
14573
14574         local fm_file=$DIR/$tfile
14575         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
14576
14577         local num_blks=512
14578         local expected_len=$(( (num_blks / 2) * 64 ))
14579         for ((i = 0; i < $num_blks; i++)); do
14580                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) \
14581                         conv=notrunc > /dev/null 2>&1
14582         done
14583
14584         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14585         filefrag_op=$(filefrag -ve -k $fm_file |
14586                       sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
14587
14588         local last_lun=$(echo $filefrag_op | cut -d: -f5)
14589
14590         IFS=$'\n'
14591         local tot_len=0
14592         local num_luns=1
14593         for line in $filefrag_op; do
14594                 local frag_lun=$(echo $line | cut -d: -f5)
14595                 local ext_len=$(echo $line | cut -d: -f4)
14596                 if (( $frag_lun != $last_lun )); then
14597                         if (( tot_len != $expected_len )); then
14598                                 error "OST$last_lun $tot_len != $expected_len"
14599                         else
14600                                 (( num_luns += 1 ))
14601                                 tot_len=0
14602                         fi
14603                 fi
14604                 (( tot_len += ext_len ))
14605                 last_lun=$frag_lun
14606         done
14607         if (( num_luns != 2 || tot_len != $expected_len )); then
14608                 error "OST$last_lun $num_luns != 2, $tot_len != $expected_len"
14609         fi
14610
14611         echo "FIEMAP with continuation calls succeeded"
14612 }
14613 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
14614
14615 test_130f() {
14616         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14617         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14618         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14619                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14620
14621         local fm_file=$DIR/$tfile
14622         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
14623                 error "multiop create with lov_delay_create on $fm_file"
14624
14625         filefrag -ves $fm_file || error "filefrag $fm_file failed"
14626         filefrag_extents=$(filefrag -vek $fm_file |
14627                            awk '/extents? found/ { print $2 }')
14628         if (( $filefrag_extents != 0 )); then
14629                 error "$fm_file: filefrag_extents=$filefrag_extents != 0"
14630         fi
14631
14632         rm -f $fm_file
14633 }
14634 run_test 130f "FIEMAP (unstriped file)"
14635
14636 test_130g() {
14637         (( $MDS1_VERSION >= $(version_code 2.12.53) )) ||
14638                 skip "Need MDS version with at least 2.12.53 for overstriping"
14639         local filefrag_op=$(filefrag -l 2>&1 | grep "invalid option")
14640         [[ -z "$filefrag_op" ]] || skip_env "filefrag missing logical ordering"
14641         [[ "$ost1_FSTYPE" != "zfs" ]] ||
14642                 skip "LU-1941: FIEMAP unimplemented on ZFS"
14643
14644         local file=$DIR/$tfile
14645         local nr=$((OSTCOUNT * 100))
14646
14647         $LFS setstripe -C $nr $file || error "failed to setstripe -C $nr $file"
14648
14649         stack_trap "rm -f $file"
14650         dd if=/dev/zero of=$file count=$nr bs=1M
14651         sync
14652         nr=$($LFS getstripe -c $file)
14653
14654         local extents=$(filefrag -v $file |
14655                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}' | wc -l)
14656
14657         echo "filefrag list $extents extents in file with stripecount $nr"
14658         if (( extents < nr )); then
14659                 $LFS getstripe $file
14660                 filefrag -v $file
14661                 error "filefrag printed $extents < $nr extents"
14662         fi
14663 }
14664 run_test 130g "FIEMAP (overstripe file)"
14665
14666 # Test for writev/readv
14667 test_131a() {
14668         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
14669                 error "writev test failed"
14670         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
14671                 error "readv failed"
14672         rm -f $DIR/$tfile
14673 }
14674 run_test 131a "test iov's crossing stripe boundary for writev/readv"
14675
14676 test_131b() {
14677         local fsize=$((524288 + 1048576 + 1572864))
14678         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
14679                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14680                         error "append writev test failed"
14681
14682         ((fsize += 1572864 + 1048576))
14683         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
14684                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
14685                         error "append writev test failed"
14686         rm -f $DIR/$tfile
14687 }
14688 run_test 131b "test append writev"
14689
14690 test_131c() {
14691         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
14692         error "NOT PASS"
14693 }
14694 run_test 131c "test read/write on file w/o objects"
14695
14696 test_131d() {
14697         rwv -f $DIR/$tfile -w -n 1 1572864
14698         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
14699         if [ "$NOB" != 1572864 ]; then
14700                 error "Short read filed: read $NOB bytes instead of 1572864"
14701         fi
14702         rm -f $DIR/$tfile
14703 }
14704 run_test 131d "test short read"
14705
14706 test_131e() {
14707         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
14708         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
14709         error "read hitting hole failed"
14710         rm -f $DIR/$tfile
14711 }
14712 run_test 131e "test read hitting hole"
14713
14714 check_stats() {
14715         local facet=$1
14716         local op=$2
14717         local want=${3:-0}
14718         local res
14719
14720         # open             11 samples [usecs] 468 4793 13658 35791898
14721         case $facet in
14722         mds*) res=($(do_facet $facet \
14723                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op"))
14724                  ;;
14725         ost*) res=($(do_facet $facet \
14726                   $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op"))
14727                  ;;
14728         *) error "Wrong facet '$facet'" ;;
14729         esac
14730         [[ -n "$res" ]] || error "counter for $op on $facet not incremented"
14731         # if $want is zero, it means any stat increment is ok.
14732         if (( $want > 0 )); then
14733                 local count=${res[1]}
14734
14735                 if (( $count != $want )); then
14736                         if [[ $facet =~ "mds" ]]; then
14737                                 do_nodes $(comma_list $(mdts_nodes)) \
14738                                         $LCTL get_param mdt.*.md_stats
14739                         else
14740                                 do_nodes $(comma_list $(osts-nodes)) \
14741                                         $LCTL get_param obdfilter.*.stats
14742                         fi
14743                         error "The $op counter on $facet is $count, not $want"
14744                 fi
14745         fi
14746 }
14747
14748 test_133a() {
14749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14750         remote_ost_nodsh && skip "remote OST with nodsh"
14751         remote_mds_nodsh && skip "remote MDS with nodsh"
14752         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14753                 skip_env "MDS doesn't support rename stats"
14754
14755         local testdir=$DIR/${tdir}/stats_testdir
14756
14757         mkdir -p $DIR/${tdir}
14758
14759         # clear stats.
14760         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14761         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14762
14763         # verify mdt stats first.
14764         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14765         check_stats $SINGLEMDS "mkdir" 1
14766
14767         # clear "open" from "lfs mkdir" above
14768         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14769         touch ${testdir}/${tfile} || error "touch failed"
14770         check_stats $SINGLEMDS "open" 1
14771         check_stats $SINGLEMDS "close" 1
14772         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
14773                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
14774                 check_stats $SINGLEMDS "mknod" 2
14775         }
14776         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
14777         check_stats $SINGLEMDS "unlink" 1
14778         rm -f ${testdir}/${tfile} || error "file remove failed"
14779         check_stats $SINGLEMDS "unlink" 2
14780
14781         # remove working dir and check mdt stats again.
14782         rmdir ${testdir} || error "rmdir failed"
14783         check_stats $SINGLEMDS "rmdir" 1
14784
14785         local testdir1=$DIR/${tdir}/stats_testdir1
14786         mkdir_on_mdt0 -p ${testdir}
14787         mkdir_on_mdt0 -p ${testdir1}
14788         touch ${testdir1}/test1
14789         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
14790         check_stats $SINGLEMDS "crossdir_rename" 1
14791
14792         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
14793         check_stats $SINGLEMDS "samedir_rename" 1
14794
14795         rm -rf $DIR/${tdir}
14796 }
14797 run_test 133a "Verifying MDT stats ========================================"
14798
14799 test_133b() {
14800         local res
14801
14802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14803         remote_ost_nodsh && skip "remote OST with nodsh"
14804         remote_mds_nodsh && skip "remote MDS with nodsh"
14805
14806         local testdir=$DIR/${tdir}/stats_testdir
14807
14808         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
14809         mkdir_on_mdt0 ${testdir} || error "mkdir_on_mdt0 failed"
14810         touch ${testdir}/${tfile} || error "touch failed"
14811         cancel_lru_locks mdc
14812
14813         # clear stats.
14814         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14815         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14816
14817         # extra mdt stats verification.
14818         chmod 444 ${testdir}/${tfile} || error "chmod failed"
14819         check_stats $SINGLEMDS "setattr" 1
14820         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14821         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
14822         then            # LU-1740
14823                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
14824                 check_stats $SINGLEMDS "getattr" 1
14825         fi
14826         rm -rf $DIR/${tdir}
14827
14828         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
14829         # so the check below is not reliable
14830         [ $MDSCOUNT -eq 1 ] || return 0
14831
14832         # Sleep to avoid a cached response.
14833         #define OBD_STATFS_CACHE_SECONDS 1
14834         sleep 2
14835         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14836         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14837         $LFS df || error "lfs failed"
14838         check_stats $SINGLEMDS "statfs" 1
14839
14840         # check aggregated statfs (LU-10018)
14841         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
14842                 return 0
14843         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
14844                 return 0
14845         sleep 2
14846         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14847         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
14848         df $DIR
14849         check_stats $SINGLEMDS "statfs" 1
14850
14851         # We want to check that the client didn't send OST_STATFS to
14852         # ost1 but the MDT also uses OST_STATFS for precreate. So some
14853         # extra care is needed here.
14854         if remote_mds; then
14855                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
14856                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
14857
14858                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
14859                 [ "$res" ] && error "OST got STATFS"
14860         fi
14861
14862         return 0
14863 }
14864 run_test 133b "Verifying extra MDT stats =================================="
14865
14866 test_133c() {
14867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14868         remote_ost_nodsh && skip "remote OST with nodsh"
14869         remote_mds_nodsh && skip "remote MDS with nodsh"
14870
14871         local testdir=$DIR/$tdir/stats_testdir
14872
14873         test_mkdir -p $testdir
14874
14875         # verify obdfilter stats.
14876         $LFS setstripe -c 1 -i 0 $testdir/$tfile
14877         sync
14878         cancel_lru_locks osc
14879         wait_delete_completed
14880
14881         # clear stats.
14882         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
14883         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
14884
14885         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
14886                 error "dd failed"
14887         sync
14888         cancel_lru_locks osc
14889         check_stats ost1 "write" 1
14890
14891         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
14892         check_stats ost1 "read" 1
14893
14894         > $testdir/$tfile || error "truncate failed"
14895         check_stats ost1 "punch" 1
14896
14897         rm -f $testdir/$tfile || error "file remove failed"
14898         wait_delete_completed
14899         check_stats ost1 "destroy" 1
14900
14901         rm -rf $DIR/$tdir
14902 }
14903 run_test 133c "Verifying OST stats ========================================"
14904
14905 order_2() {
14906         local value=$1
14907         local orig=$value
14908         local order=1
14909
14910         while [ $value -ge 2 ]; do
14911                 order=$((order*2))
14912                 value=$((value/2))
14913         done
14914
14915         if [ $orig -gt $order ]; then
14916                 order=$((order*2))
14917         fi
14918         echo $order
14919 }
14920
14921 size_in_KMGT() {
14922     local value=$1
14923     local size=('K' 'M' 'G' 'T');
14924     local i=0
14925     local size_string=$value
14926
14927     while [ $value -ge 1024 ]; do
14928         if [ $i -gt 3 ]; then
14929             #T is the biggest unit we get here, if that is bigger,
14930             #just return XXXT
14931             size_string=${value}T
14932             break
14933         fi
14934         value=$((value >> 10))
14935         if [ $value -lt 1024 ]; then
14936             size_string=${value}${size[$i]}
14937             break
14938         fi
14939         i=$((i + 1))
14940     done
14941
14942     echo $size_string
14943 }
14944
14945 get_rename_size() {
14946         local size=$1
14947         local context=${2:-.}
14948         local sample=$(do_facet $SINGLEMDS $LCTL \
14949                 get_param mdt.$FSNAME-MDT0000.rename_stats |
14950                 grep -A1 $context |
14951                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
14952         echo $sample
14953 }
14954
14955 test_133d() {
14956         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14957         remote_ost_nodsh && skip "remote OST with nodsh"
14958         remote_mds_nodsh && skip "remote MDS with nodsh"
14959         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
14960                 skip_env "MDS doesn't support rename stats"
14961
14962         local testdir1=$DIR/${tdir}/stats_testdir1
14963         local testdir2=$DIR/${tdir}/stats_testdir2
14964         mkdir -p $DIR/${tdir} || error "mkdir $tdir failed"
14965
14966         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
14967
14968         mkdir_on_mdt0 ${testdir1} || error "mkdir $testdir1 failed"
14969         mkdir_on_mdt0 ${testdir2} || error "mkdir $testdir2 failed"
14970
14971         createmany -o $testdir1/test 512 || error "createmany failed"
14972
14973         # check samedir rename size
14974         mv ${testdir1}/test0 ${testdir1}/test_0
14975
14976         local testdir1_size=$(ls -l $DIR/${tdir} |
14977                 awk '/stats_testdir1/ {print $5}')
14978         local testdir2_size=$(ls -l $DIR/${tdir} |
14979                 awk '/stats_testdir2/ {print $5}')
14980
14981         testdir1_size=$(order_2 $testdir1_size)
14982         testdir2_size=$(order_2 $testdir2_size)
14983
14984         testdir1_size=$(size_in_KMGT $testdir1_size)
14985         testdir2_size=$(size_in_KMGT $testdir2_size)
14986
14987         echo "source rename dir size: ${testdir1_size}"
14988         echo "target rename dir size: ${testdir2_size}"
14989
14990         local cmd="do_facet $SINGLEMDS $LCTL "
14991         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
14992
14993         eval $cmd || error "$cmd failed"
14994         local samedir=$($cmd | grep 'same_dir')
14995         local same_sample=$(get_rename_size $testdir1_size)
14996         [ -z "$samedir" ] && error "samedir_rename_size count error"
14997         [[ $same_sample -eq 1 ]] ||
14998                 error "samedir_rename_size error $same_sample"
14999         echo "Check same dir rename stats success"
15000
15001         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
15002
15003         # check crossdir rename size
15004         mv ${testdir1}/test_0 ${testdir2}/test_0
15005
15006         testdir1_size=$(ls -l $DIR/${tdir} |
15007                 awk '/stats_testdir1/ {print $5}')
15008         testdir2_size=$(ls -l $DIR/${tdir} |
15009                 awk '/stats_testdir2/ {print $5}')
15010
15011         testdir1_size=$(order_2 $testdir1_size)
15012         testdir2_size=$(order_2 $testdir2_size)
15013
15014         testdir1_size=$(size_in_KMGT $testdir1_size)
15015         testdir2_size=$(size_in_KMGT $testdir2_size)
15016
15017         echo "source rename dir size: ${testdir1_size}"
15018         echo "target rename dir size: ${testdir2_size}"
15019
15020         eval $cmd || error "$cmd failed"
15021         local crossdir=$($cmd | grep 'crossdir')
15022         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
15023         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
15024         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
15025         [[ $src_sample -eq 1 ]] ||
15026                 error "crossdir_rename_size error $src_sample"
15027         [[ $tgt_sample -eq 1 ]] ||
15028                 error "crossdir_rename_size error $tgt_sample"
15029         echo "Check cross dir rename stats success"
15030         rm -rf $DIR/${tdir}
15031 }
15032 run_test 133d "Verifying rename_stats ========================================"
15033
15034 test_133e() {
15035         remote_mds_nodsh && skip "remote MDS with nodsh"
15036         remote_ost_nodsh && skip "remote OST with nodsh"
15037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15038
15039         local testdir=$DIR/${tdir}/stats_testdir
15040         local ctr f0 f1 bs=32768 count=42 sum
15041
15042         mkdir -p ${testdir} || error "mkdir failed"
15043
15044         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
15045
15046         for ctr in {write,read}_bytes; do
15047                 sync
15048                 cancel_lru_locks osc
15049
15050                 do_facet ost1 $LCTL set_param -n \
15051                         "obdfilter.*.exports.clear=clear"
15052
15053                 if [ $ctr = write_bytes ]; then
15054                         f0=/dev/zero
15055                         f1=${testdir}/${tfile}
15056                 else
15057                         f0=${testdir}/${tfile}
15058                         f1=/dev/null
15059                 fi
15060
15061                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
15062                         error "dd failed"
15063                 sync
15064                 cancel_lru_locks osc
15065
15066                 sum=$(do_facet ost1 $LCTL get_param \
15067                         "obdfilter.*.exports.*.stats" |
15068                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
15069                                 $1 == ctr { sum += $7 }
15070                                 END { printf("%0.0f", sum) }')
15071
15072                 if ((sum != bs * count)); then
15073                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
15074                 fi
15075         done
15076
15077         rm -rf $DIR/${tdir}
15078 }
15079 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
15080
15081 test_133f() {
15082         [[ $(lustre_version_code $facet) -ge $(version_code 2.7.65) ]] ||
15083                 skip "too old lustre for get_param -R ($facet_ver)"
15084
15085         # verifying readability.
15086         $LCTL get_param -R '*' &> /dev/null
15087
15088         # Verifing writability with badarea_io.
15089         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15090         local skipped_params='force_lbug|changelog_mask|daemon_file'
15091         $LCTL list_param -FR '*' | grep '=' | tr -d = |
15092                 egrep -v "$skipped_params" |
15093                 xargs -n 1 find $proc_dirs -name |
15094                 xargs -n 1 badarea_io ||
15095                 error "client badarea_io failed"
15096
15097         # remount the FS in case writes/reads /proc break the FS
15098         cleanup || error "failed to unmount"
15099         setup || error "failed to setup"
15100 }
15101 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
15102
15103 test_133g() {
15104         remote_mds_nodsh && skip "remote MDS with nodsh"
15105         remote_ost_nodsh && skip "remote OST with nodsh"
15106
15107         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
15108         local skipped_params="'force_lbug|changelog_mask|daemon_file'"
15109         local facet
15110         for facet in mds1 ost1; do
15111                 local facet_ver=$(lustre_version_code $facet)
15112                 if [ $facet_ver -ge $(version_code 2.7.65) ]; then
15113                         do_facet $facet "$LCTL get_param -R '*'" &> /dev/null
15114                 else
15115                         log "$facet: too old lustre for get_param -R"
15116                 fi
15117                 if [ $facet_ver -ge $(version_code 2.5.54) ]; then
15118                         do_facet $facet "$LCTL list_param -FR '*' | grep '=' |
15119                                 tr -d = | egrep -v $skipped_params |
15120                                 xargs -n 1 find $proc_dirs -name |
15121                                 xargs -n 1 badarea_io" ||
15122                                         error "$facet badarea_io failed"
15123                 else
15124                         skip_noexit "$facet: too old lustre for get_param -R"
15125                 fi
15126         done
15127
15128         # remount the FS in case writes/reads /proc break the FS
15129         cleanup || error "failed to unmount"
15130         setup || error "failed to setup"
15131 }
15132 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
15133
15134 test_133h() {
15135         remote_mds_nodsh && skip "remote MDS with nodsh"
15136         remote_ost_nodsh && skip "remote OST with nodsh"
15137         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
15138                 skip "Need MDS version at least 2.9.54"
15139
15140         local facet
15141         for facet in client mds1 ost1; do
15142                 # Get the list of files that are missing the terminating newline
15143                 local plist=$(do_facet $facet
15144                         $LCTL list_param -FR '*' | grep '=' | tr -d =)
15145                 local ent
15146                 for ent in $plist; do
15147                         local missing=$(do_facet $facet $LCTL get_param $ent \|\
15148                                 awk -v FS='\v' -v RS='\v\v' \
15149                                 "'END { if(NR>0 && \\\$NF !~ /.*\\\n\$/) \
15150                                         print FILENAME}'" 2>/dev/null)
15151                         [ -z $missing ] || {
15152                                 do_facet $facet $LCTL get_param $ent | od -An -tx1
15153                                 error "file does not end with newline: $facet-$ent"
15154                         }
15155                 done
15156         done
15157 }
15158 run_test 133h "Proc files should end with newlines"
15159
15160 test_134a() {
15161         remote_mds_nodsh && skip "remote MDS with nodsh"
15162         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15163                 skip "Need MDS version at least 2.7.54"
15164
15165         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15166         cancel_lru_locks mdc
15167
15168         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
15169         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15170         [ $unused -eq 0 ] || error "$unused locks are not cleared"
15171
15172         local nr=1000
15173         createmany -o $DIR/$tdir/f $nr ||
15174                 error "failed to create $nr files in $DIR/$tdir"
15175         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
15176
15177         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
15178         do_facet mds1 $LCTL set_param fail_loc=0x327
15179         do_facet mds1 $LCTL set_param fail_val=500
15180         touch $DIR/$tdir/m
15181
15182         echo "sleep 10 seconds ..."
15183         sleep 10
15184         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
15185
15186         do_facet mds1 $LCTL set_param fail_loc=0
15187         do_facet mds1 $LCTL set_param fail_val=0
15188         [ $lck_cnt -lt $unused ] ||
15189                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
15190
15191         rm $DIR/$tdir/m
15192         unlinkmany $DIR/$tdir/f $nr
15193 }
15194 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
15195
15196 test_134b() {
15197         remote_mds_nodsh && skip "remote MDS with nodsh"
15198         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
15199                 skip "Need MDS version at least 2.7.54"
15200
15201         mkdir_on_mdt0 $DIR/$tdir || error "failed to create $DIR/$tdir"
15202         cancel_lru_locks mdc
15203
15204         local low_wm=$(do_facet mds1 $LCTL get_param -n \
15205                         ldlm.lock_reclaim_threshold_mb)
15206         # disable reclaim temporarily
15207         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
15208
15209         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
15210         do_facet mds1 $LCTL set_param fail_loc=0x328
15211         do_facet mds1 $LCTL set_param fail_val=500
15212
15213         $LCTL set_param debug=+trace
15214
15215         local nr=600
15216         createmany -o $DIR/$tdir/f $nr &
15217         local create_pid=$!
15218
15219         echo "Sleep $TIMEOUT seconds ..."
15220         sleep $TIMEOUT
15221         if ! ps -p $create_pid  > /dev/null 2>&1; then
15222                 do_facet mds1 $LCTL set_param fail_loc=0
15223                 do_facet mds1 $LCTL set_param fail_val=0
15224                 do_facet mds1 $LCTL set_param \
15225                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
15226                 error "createmany finished incorrectly!"
15227         fi
15228         do_facet mds1 $LCTL set_param fail_loc=0
15229         do_facet mds1 $LCTL set_param fail_val=0
15230         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
15231         wait $create_pid || return 1
15232
15233         unlinkmany $DIR/$tdir/f $nr
15234 }
15235 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
15236
15237 test_135() {
15238         remote_mds_nodsh && skip "remote MDS with nodsh"
15239         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15240                 skip "Need MDS version at least 2.13.50"
15241         local fname
15242
15243         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15244
15245 #define OBD_FAIL_PLAIN_RECORDS 0x1319
15246         #set only one record at plain llog
15247         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x1319 fail_val=1
15248
15249         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15250
15251         #fill already existed plain llog each 64767
15252         #wrapping whole catalog
15253         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15254
15255         createmany -o $DIR/$tdir/$tfile_ 64700
15256         for (( i = 0; i < 64700; i = i + 2 ))
15257         do
15258                 rm $DIR/$tdir/$tfile_$i &
15259                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15260                 local pid=$!
15261                 wait $pid
15262         done
15263
15264         #waiting osp synchronization
15265         wait_delete_completed
15266 }
15267 run_test 135 "Race catalog processing"
15268
15269 test_136() {
15270         remote_mds_nodsh && skip "remote MDS with nodsh"
15271         [[ $MDS1_VERSION -lt $(version_code 2.13.50) ]] &&
15272                 skip "Need MDS version at least 2.13.50"
15273         local fname
15274
15275         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
15276         $LFS setstripe -c 1 -i 0 $DIR/$tdir || error "failed to set striping"
15277         #set only one record at plain llog
15278 #define OBD_FAIL_CATALOG_FULL_CHECK                0x131a
15279         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x131a fail_val=1
15280
15281         ost_set_temp_seq_width_all $DATA_SEQ_MAX_WIDTH
15282
15283         #fill already existed 2 plain llogs each 64767
15284         #wrapping whole catalog
15285         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 1))
15286         createmany -o -u $DIR/$tdir/$tfile- $((64767 * 3 / 2))
15287         wait_delete_completed
15288
15289         createmany -o $DIR/$tdir/$tfile_ 10
15290         sleep 25
15291
15292         do_facet $SINGLEMDS $LCTL set_param fail_val=3
15293         for (( i = 0; i < 10; i = i + 3 ))
15294         do
15295                 rm $DIR/$tdir/$tfile_$i &
15296                 rm $DIR/$tdir/$tfile_$((i + 1)) &
15297                 local pid=$!
15298                 wait $pid
15299                 sleep 7
15300                 rm $DIR/$tdir/$tfile_$((i + 2)) &
15301         done
15302
15303         #waiting osp synchronization
15304         wait_delete_completed
15305 }
15306 run_test 136 "Race catalog processing 2"
15307
15308 test_140() { #bug-17379
15309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15310
15311         test_mkdir $DIR/$tdir
15312         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
15313         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
15314
15315         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
15316         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
15317         local i=0
15318         while i=$((i + 1)); do
15319                 test_mkdir $i
15320                 cd $i || error "Changing to $i"
15321                 ln -s ../stat stat || error "Creating stat symlink"
15322                 # Read the symlink until ELOOP present,
15323                 # not LBUGing the system is considered success,
15324                 # we didn't overrun the stack.
15325                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
15326                 if [ $ret -ne 0 ]; then
15327                         if [ $ret -eq 40 ]; then
15328                                 break  # -ELOOP
15329                         else
15330                                 error "Open stat symlink"
15331                                         return
15332                         fi
15333                 fi
15334         done
15335         i=$((i - 1))
15336         echo "The symlink depth = $i"
15337         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
15338                 error "Invalid symlink depth"
15339
15340         # Test recursive symlink
15341         ln -s symlink_self symlink_self
15342         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
15343         echo "open symlink_self returns $ret"
15344         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
15345 }
15346 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
15347
15348 test_150a() {
15349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15350
15351         local TF="$TMP/$tfile"
15352
15353         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15354         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15355         cp $TF $DIR/$tfile
15356         cancel_lru_locks $OSC
15357         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
15358         remount_client $MOUNT
15359         df -P $MOUNT
15360         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
15361
15362         $TRUNCATE $TF 6000
15363         $TRUNCATE $DIR/$tfile 6000
15364         cancel_lru_locks $OSC
15365         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
15366
15367         echo "12345" >>$TF
15368         echo "12345" >>$DIR/$tfile
15369         cancel_lru_locks $OSC
15370         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
15371
15372         echo "12345" >>$TF
15373         echo "12345" >>$DIR/$tfile
15374         cancel_lru_locks $OSC
15375         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
15376 }
15377 run_test 150a "truncate/append tests"
15378
15379 test_150b() {
15380         check_set_fallocate_or_skip
15381         local out
15382
15383         touch $DIR/$tfile
15384         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15385         out=$(check_fallocate $DIR/$tfile 2>&1) ||
15386                 skip_eopnotsupp "$out|check_fallocate failed"
15387 }
15388 run_test 150b "Verify fallocate (prealloc) functionality"
15389
15390 test_150bb() {
15391         check_set_fallocate_or_skip
15392
15393         touch $DIR/$tfile
15394         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15395         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=20 || error "dd failed"
15396         > $DIR/$tfile
15397         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15398         # precomputed md5sum for 20MB of zeroes
15399         local expect="8f4e33f3dc3e414ff94e5fb6905cba8c"
15400         local sum=($(md5sum $DIR/$tfile))
15401
15402         [[ "${sum[0]}" == "$expect" ]] || error "fallocate unwritten is not zero"
15403
15404         check_set_fallocate 1
15405
15406         > $DIR/$tfile
15407         fallocate -l $((1048576 * 20)) $DIR/$tfile || error "fallocate failed"
15408         sum=($(md5sum $DIR/$tfile))
15409
15410         [[ "${sum[0]}" == "$expect" ]] || error "fallocate zero is not zero"
15411 }
15412 run_test 150bb "Verify fallocate modes both zero space"
15413
15414 test_150c() {
15415         check_set_fallocate_or_skip
15416         local striping="-c2"
15417
15418         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15419         $LFS setstripe -c $OSTCOUNT -S1M $DIR/$tfile || error "setstripe failed"
15420         fallocate -l ${OSTCOUNT}m $DIR/$tfile || error "fallocate failed"
15421         local bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15422         local want=$((OSTCOUNT * 1048576))
15423
15424         # Must allocate all requested space, not more than 5% extra
15425         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15426                 error "bytes $bytes is not $want"
15427
15428         rm -f $DIR/$tfile
15429
15430         echo "verify fallocate on PFL file"
15431
15432         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15433
15434         $LFS setstripe -E1M $striping -E16M -c3 -Eeof -c 4 $DIR/$tfile ||
15435                 error "Create $DIR/$tfile failed"
15436         fallocate -l $((1048576 * 512)) $DIR/$tfile || error "fallocate failed"
15437         bytes=$(($(stat -c '%b * %B' $DIR/$tfile)))
15438         want=$((512 * 1048576))
15439
15440         # Must allocate all requested space, not more than 5% extra
15441         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15442                 error "bytes $bytes is not $want"
15443 }
15444 run_test 150c "Verify fallocate Size and Blocks"
15445
15446 test_150d() {
15447         check_set_fallocate_or_skip
15448         local striping="-c2"
15449
15450         [[ "x$DOM" == "xyes" ]] && striping="-L mdt"
15451
15452         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15453         $LFS setstripe -E1M $striping -E eof -c $OSTCOUNT -S1M $DIR/$tdir ||
15454                 error "setstripe failed"
15455         fallocate -o 1G -l ${OSTCOUNT}m $DIR/$tdir || error "fallocate failed"
15456         local bytes=$(($(stat -c '%b * %B' $DIR/$tdir)))
15457         local want=$((OSTCOUNT * 1048576))
15458
15459         # Must allocate all requested space, not more than 5% extra
15460         (( $bytes >= $want && $bytes < $want * 105 / 100 )) ||
15461                 error "bytes $bytes is not $want"
15462 }
15463 run_test 150d "Verify fallocate Size and Blocks - Non zero start"
15464
15465 test_150e() {
15466         check_set_fallocate_or_skip
15467
15468         echo "df before:"
15469         $LFS df
15470         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15471         $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15472                 error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15473
15474         # Find OST with Minimum Size
15475         min_size_ost=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15476                        sort -un | head -1)
15477
15478         # Get 100MB per OST of the available space to reduce run time
15479         # else 60% of the available space if we are running SLOW tests
15480         if [ $SLOW == "no" ]; then
15481                 local space=$((1024 * 100 * OSTCOUNT))
15482         else
15483                 local space=$(((min_size_ost * 60)/100 * OSTCOUNT))
15484         fi
15485
15486         fallocate -l${space}k $DIR/$tfile ||
15487                 error "fallocate ${space}k $DIR/$tfile failed"
15488         echo "'fallocate -l ${space}k $DIR/$tfile' succeeded"
15489
15490         # get size immediately after fallocate. This should be correctly
15491         # updated
15492         local size=$(stat -c '%s' $DIR/$tfile)
15493         local used=$(( $(stat -c '%b * %B' $DIR/$tfile) / 1024))
15494
15495         # Sleep for a while for statfs to get updated. And not pull from cache.
15496         sleep 2
15497
15498         echo "df after fallocate:"
15499         $LFS df
15500
15501         (( size / 1024 == space )) || error "size $size != requested $space"
15502         [ "$ost1_FSTYPE" != ldiskfs ] || (( used >= space )) ||
15503                 error "used $used < space $space"
15504
15505         rm $DIR/$tfile || error "rm failed"
15506         sync
15507         wait_delete_completed
15508
15509         echo "df after unlink:"
15510         $LFS df
15511 }
15512 run_test 150e "Verify 60% of available OST space consumed by fallocate"
15513
15514 test_150f() {
15515         local size
15516         local blocks
15517         local want_size_before=20480 # in bytes
15518         local want_blocks_before=40 # 512 sized blocks
15519         local want_blocks_after=24  # 512 sized blocks
15520         local length=$(((want_blocks_before - want_blocks_after) * 512))
15521
15522         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15523                 skip "need at least 2.14.0 for fallocate punch"
15524
15525         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15526                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15527         fi
15528
15529         check_set_fallocate_or_skip
15530         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15531
15532         [[ "x$DOM" == "xyes" ]] &&
15533                 $LFS setstripe -E1M -L mdt -E eof $DIR/$tfile
15534
15535         echo "Verify fallocate punch: Range within the file range"
15536         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15537                 error "dd failed for bs 4096 and count 5"
15538
15539         # Call fallocate with punch range which is within the file range
15540         out=$(fallocate -p --offset 4096 -l $length $DIR/$tfile 2>&1) ||
15541                 skip_eopnotsupp "$out|fallocate: offset 4096 and length $length"
15542         # client must see changes immediately after fallocate
15543         size=$(stat -c '%s' $DIR/$tfile)
15544         blocks=$(stat -c '%b' $DIR/$tfile)
15545
15546         # Verify punch worked.
15547         (( blocks == want_blocks_after )) ||
15548                 error "punch failed: blocks $blocks != $want_blocks_after"
15549
15550         (( size == want_size_before )) ||
15551                 error "punch failed: size $size != $want_size_before"
15552
15553         # Verify there is hole in file
15554         local data_off=$(lseek_test -d 4096 $DIR/$tfile)
15555         # precomputed md5sum
15556         local expect="4a9a834a2db02452929c0a348273b4aa"
15557
15558         cksum=($(md5sum $DIR/$tfile))
15559         [[ "${cksum[0]}" == "$expect" ]] ||
15560                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15561
15562         # Start second sub-case for fallocate punch.
15563         echo "Verify fallocate punch: Range overlapping and less than blocksize"
15564         yes 'A' | dd of=$DIR/$tfile bs=4096 count=5 ||
15565                 error "dd failed for bs 4096 and count 5"
15566
15567         # Punch range less than block size will have no change in block count
15568         want_blocks_after=40  # 512 sized blocks
15569
15570         # Punch overlaps two blocks and less than blocksize
15571         out=$(fallocate -p --offset 4000 -l 3000 $DIR/$tfile 2>&1) ||
15572                 skip_eopnotsupp "$out|fallocate: offset 4000 length 3000"
15573         size=$(stat -c '%s' $DIR/$tfile)
15574         blocks=$(stat -c '%b' $DIR/$tfile)
15575
15576         # Verify punch worked.
15577         (( blocks == want_blocks_after )) ||
15578                 error "punch failed: blocks $blocks != $want_blocks_after"
15579
15580         (( size == want_size_before )) ||
15581                 error "punch failed: size $size != $want_size_before"
15582
15583         # Verify if range is really zero'ed out. We expect Zeros.
15584         # precomputed md5sum
15585         expect="c57ec5d769c3dbe3426edc3f7d7e11d3"
15586         cksum=($(md5sum $DIR/$tfile))
15587         [[ "${cksum[0]}" == "$expect" ]] ||
15588                 error "unexpected MD5SUM after punch: ${cksum[0]}"
15589 }
15590 run_test 150f "Verify fallocate punch functionality"
15591
15592 test_150g() {
15593         local space
15594         local size
15595         local blocks
15596         local blocks_after
15597         local size_after
15598         local BS=4096 # Block size in bytes
15599
15600         [[ $OST1_VERSION -ge $(version_code 2.14.0) ]] ||
15601                 skip "need at least 2.14.0 for fallocate punch"
15602
15603         if [ "$ost1_FSTYPE" = "zfs" ] || [ "$mds1_FSTYPE" = "zfs" ]; then
15604                 skip "LU-14160: punch mode is not implemented on OSD ZFS"
15605         fi
15606
15607         check_set_fallocate_or_skip
15608         stack_trap "rm -f $DIR/$tfile; wait_delete_completed"
15609
15610         if [[ "x$DOM" == "xyes" ]]; then
15611                 $LFS setstripe -E2M -L mdt -E eof -c${OSTCOUNT} $DIR/$tfile ||
15612                         error "$LFS setstripe DoM + ${OSTCOUNT} OST failed"
15613         else
15614                 $LFS setstripe -c${OSTCOUNT} $DIR/$tfile ||
15615                         error "$LFS setstripe -c${OSTCOUNT} $DIR/$tfile failed"
15616         fi
15617
15618         # Get 100MB per OST of the available space to reduce run time
15619         # else 60% of the available space if we are running SLOW tests
15620         if [ $SLOW == "no" ]; then
15621                 space=$((1024 * 100 * OSTCOUNT))
15622         else
15623                 # Find OST with Minimum Size
15624                 space=$($LFS df | awk "/$FSNAME-OST/ { print \$4 }" |
15625                         sort -un | head -1)
15626                 echo "min size OST: $space"
15627                 space=$(((space * 60)/100 * OSTCOUNT))
15628         fi
15629         # space in 1k units, round to 4k blocks
15630         local blkcount=$((space * 1024 / $BS))
15631
15632         echo "Verify fallocate punch: Very large Range"
15633         fallocate -l${space}k $DIR/$tfile ||
15634                 error "fallocate ${space}k $DIR/$tfile failed"
15635         # write 1M at the end, start and in the middle
15636         yes 'A' | dd of=$DIR/$tfile bs=$BS count=256 ||
15637                 error "dd failed: bs $BS count 256"
15638         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount - 256)) count=256 ||
15639                 error "dd failed: bs $BS count 256 seek $((blkcount - 256))"
15640         yes 'A' | dd of=$DIR/$tfile bs=$BS seek=$((blkcount / 2)) count=1024 ||
15641                 error "dd failed: bs $BS count 256 seek $((blkcount / 2))"
15642
15643         # Gather stats.
15644         size=$(stat -c '%s' $DIR/$tfile)
15645
15646         # gather punch length.
15647         local punch_size=$((size - (BS * 2)))
15648
15649         echo "punch_size = $punch_size"
15650         echo "size - punch_size: $((size - punch_size))"
15651         echo "size - punch_size in blocks: $(((size - punch_size)/BS))"
15652
15653         # Call fallocate to punch all except 2 blocks. We leave the
15654         # first and the last block
15655         echo "fallocate -p --offset $BS -l $punch_size $DIR/$tfile"
15656         out=$(fallocate -p --offset $BS -l $punch_size $DIR/$tfile 2>&1) ||
15657                 skip_eopnotsupp "$out|fallocate: offset $BS length $punch_size"
15658
15659         size_after=$(stat -c '%s' $DIR/$tfile)
15660         blocks_after=$(stat -c '%b' $DIR/$tfile)
15661
15662         # Verify punch worked.
15663         # Size should be kept
15664         (( size == size_after )) ||
15665                 error "punch failed: size $size != $size_after"
15666
15667         # two 4k data blocks to remain plus possible 1 extra extent block
15668         (( blocks_after <= ((BS / 512) * 3) )) ||
15669                 error "too many blocks remains: $blocks_after"
15670
15671         # Verify that file has hole between the first and the last blocks
15672         local hole_start=$(lseek_test -l 0 $DIR/$tfile)
15673         local hole_end=$(lseek_test -d $BS $DIR/$tfile)
15674
15675         echo "Hole at [$hole_start, $hole_end)"
15676         (( hole_start == BS )) ||
15677                 error "no hole at offset $BS after punch"
15678
15679         (( hole_end == BS + punch_size )) ||
15680                 error "data at offset $hole_end < $((BS + punch_size))"
15681 }
15682 run_test 150g "Verify fallocate punch on large range"
15683
15684 test_150h() {
15685         local file=$DIR/$tfile
15686         local size
15687
15688         check_set_fallocate_or_skip
15689         statx_supported || skip_env "Test must be statx() syscall supported"
15690
15691         # fallocate() does not update the size information on the MDT
15692         fallocate -l 16K $file || error "failed to fallocate $file"
15693         cancel_lru_locks $OSC
15694         # STATX with cached-always mode will not send glimpse RPCs to OST,
15695         # it uses the caching attrs on the client side as much as possible.
15696         size=$($STATX --cached=always -c %s $file)
15697         [ $size == 16384 ] ||
15698                 error "size after fallocate() is $size, expected 16384"
15699 }
15700 run_test 150h "Verify extend fallocate updates the file size"
15701
15702 #LU-2902 roc_hit was not able to read all values from lproc
15703 function roc_hit_init() {
15704         local list=$(comma_list $(osts_nodes))
15705         local dir=$DIR/$tdir-check
15706         local file=$dir/$tfile
15707         local BEFORE
15708         local AFTER
15709         local idx
15710
15711         test_mkdir $dir
15712         #use setstripe to do a write to every ost
15713         for i in $(seq 0 $((OSTCOUNT-1))); do
15714                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
15715                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
15716                 idx=$(printf %04x $i)
15717                 BEFORE=$(get_osd_param $list *OST*$idx stats |
15718                         awk '$1 == "cache_access" {sum += $7}
15719                                 END { printf("%0.0f", sum) }')
15720
15721                 cancel_lru_locks osc
15722                 cat $file >/dev/null
15723
15724                 AFTER=$(get_osd_param $list *OST*$idx stats |
15725                         awk '$1 == "cache_access" {sum += $7}
15726                                 END { printf("%0.0f", sum) }')
15727
15728                 echo BEFORE:$BEFORE AFTER:$AFTER
15729                 if ! let "AFTER - BEFORE == 4"; then
15730                         rm -rf $dir
15731                         error "roc_hit is not safe to use"
15732                 fi
15733                 rm $file
15734         done
15735
15736         rm -rf $dir
15737 }
15738
15739 function roc_hit() {
15740         local list=$(comma_list $(osts_nodes))
15741         echo $(get_osd_param $list '' stats |
15742                 awk '$1 == "cache_hit" {sum += $7}
15743                         END { printf("%0.0f", sum) }')
15744 }
15745
15746 function set_cache() {
15747         local on=1
15748
15749         if [ "$2" == "off" ]; then
15750                 on=0;
15751         fi
15752         local list=$(comma_list $(osts_nodes))
15753         set_osd_param $list '' $1_cache_enable $on
15754
15755         cancel_lru_locks osc
15756 }
15757
15758 test_151() {
15759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15760         remote_ost_nodsh && skip "remote OST with nodsh"
15761
15762         local CPAGES=3
15763         local list=$(comma_list $(osts_nodes))
15764
15765         # check whether obdfilter is cache capable at all
15766         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
15767                 skip "not cache-capable obdfilter"
15768         fi
15769
15770         # check cache is enabled on all obdfilters
15771         if get_osd_param $list '' read_cache_enable | grep 0; then
15772                 skip "oss cache is disabled"
15773         fi
15774
15775         set_osd_param $list '' writethrough_cache_enable 1
15776
15777         # check write cache is enabled on all obdfilters
15778         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
15779                 skip "oss write cache is NOT enabled"
15780         fi
15781
15782         roc_hit_init
15783
15784         #define OBD_FAIL_OBD_NO_LRU  0x609
15785         do_nodes $list $LCTL set_param fail_loc=0x609
15786
15787         # pages should be in the case right after write
15788         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
15789                 error "dd failed"
15790
15791         local BEFORE=$(roc_hit)
15792         cancel_lru_locks osc
15793         cat $DIR/$tfile >/dev/null
15794         local AFTER=$(roc_hit)
15795
15796         do_nodes $list $LCTL set_param fail_loc=0
15797
15798         if ! let "AFTER - BEFORE == CPAGES"; then
15799                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
15800         fi
15801
15802         cancel_lru_locks osc
15803         # invalidates OST cache
15804         do_nodes $list "echo 1 > /proc/sys/vm/drop_caches"
15805         set_osd_param $list '' read_cache_enable 0
15806         cat $DIR/$tfile >/dev/null
15807
15808         # now data shouldn't be found in the cache
15809         BEFORE=$(roc_hit)
15810         cancel_lru_locks osc
15811         cat $DIR/$tfile >/dev/null
15812         AFTER=$(roc_hit)
15813         if let "AFTER - BEFORE != 0"; then
15814                 error "IN CACHE: before: $BEFORE, after: $AFTER"
15815         fi
15816
15817         set_osd_param $list '' read_cache_enable 1
15818         rm -f $DIR/$tfile
15819 }
15820 run_test 151 "test cache on oss and controls ==============================="
15821
15822 test_152() {
15823         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15824
15825         local TF="$TMP/$tfile"
15826
15827         # simulate ENOMEM during write
15828 #define OBD_FAIL_OST_NOMEM      0x226
15829         lctl set_param fail_loc=0x80000226
15830         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
15831         cp $TF $DIR/$tfile
15832         sync || error "sync failed"
15833         lctl set_param fail_loc=0
15834
15835         # discard client's cache
15836         cancel_lru_locks osc
15837
15838         # simulate ENOMEM during read
15839         lctl set_param fail_loc=0x80000226
15840         cmp $TF $DIR/$tfile || error "cmp failed"
15841         lctl set_param fail_loc=0
15842
15843         rm -f $TF
15844 }
15845 run_test 152 "test read/write with enomem ============================"
15846
15847 test_153() {
15848         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
15849 }
15850 run_test 153 "test if fdatasync does not crash ======================="
15851
15852 dot_lustre_fid_permission_check() {
15853         local fid=$1
15854         local ffid=$MOUNT/.lustre/fid/$fid
15855         local test_dir=$2
15856
15857         echo "stat fid $fid"
15858         stat $ffid || error "stat $ffid failed."
15859         echo "touch fid $fid"
15860         touch $ffid || error "touch $ffid failed."
15861         echo "write to fid $fid"
15862         cat /etc/hosts > $ffid || error "write $ffid failed."
15863         echo "read fid $fid"
15864         diff /etc/hosts $ffid || error "read $ffid failed."
15865         echo "append write to fid $fid"
15866         cat /etc/hosts >> $ffid || error "append write $ffid failed."
15867         echo "rename fid $fid"
15868         mv $ffid $test_dir/$tfile.1 &&
15869                 error "rename $ffid to $tfile.1 should fail."
15870         touch $test_dir/$tfile.1
15871         mv $test_dir/$tfile.1 $ffid &&
15872                 error "rename $tfile.1 to $ffid should fail."
15873         rm -f $test_dir/$tfile.1
15874         echo "truncate fid $fid"
15875         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
15876         echo "link fid $fid"
15877         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
15878         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
15879                 echo "setfacl fid $fid"
15880                 setfacl -R -m u:$USER0:rwx $ffid ||
15881                         error "setfacl $ffid failed"
15882                 echo "getfacl fid $fid"
15883                 getfacl $ffid || error "getfacl $ffid failed."
15884         fi
15885         echo "unlink fid $fid"
15886         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
15887         echo "mknod fid $fid"
15888         mknod $ffid c 1 3 && error "mknod $ffid should fail."
15889
15890         fid=[0xf00000400:0x1:0x0]
15891         ffid=$MOUNT/.lustre/fid/$fid
15892
15893         echo "stat non-exist fid $fid"
15894         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
15895         echo "write to non-exist fid $fid"
15896         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
15897         echo "link new fid $fid"
15898         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
15899
15900         mkdir -p $test_dir/$tdir
15901         touch $test_dir/$tdir/$tfile
15902         fid=$($LFS path2fid $test_dir/$tdir)
15903         rc=$?
15904         [ $rc -ne 0 ] &&
15905                 error "error: could not get fid for $test_dir/$dir/$tfile."
15906
15907         ffid=$MOUNT/.lustre/fid/$fid
15908
15909         echo "ls $fid"
15910         ls $ffid || error "ls $ffid failed."
15911         echo "touch $fid/$tfile.1"
15912         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
15913
15914         echo "touch $MOUNT/.lustre/fid/$tfile"
15915         touch $MOUNT/.lustre/fid/$tfile && \
15916                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
15917
15918         echo "setxattr to $MOUNT/.lustre/fid"
15919         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
15920
15921         echo "listxattr for $MOUNT/.lustre/fid"
15922         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
15923
15924         echo "delxattr from $MOUNT/.lustre/fid"
15925         setfattr -x trusted.name1 $MOUNT/.lustre/fid
15926
15927         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
15928         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
15929                 error "touch invalid fid should fail."
15930
15931         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
15932         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
15933                 error "touch non-normal fid should fail."
15934
15935         echo "rename $tdir to $MOUNT/.lustre/fid"
15936         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
15937                 error "rename to $MOUNT/.lustre/fid should fail."
15938
15939         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
15940         then            # LU-3547
15941                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
15942                 local new_obf_mode=777
15943
15944                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
15945                 chmod $new_obf_mode $DIR/.lustre/fid ||
15946                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
15947
15948                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
15949                 [ $obf_mode -eq $new_obf_mode ] ||
15950                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
15951
15952                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
15953                 chmod $old_obf_mode $DIR/.lustre/fid ||
15954                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
15955         fi
15956
15957         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
15958         fid=$($LFS path2fid $test_dir/$tfile-2)
15959
15960         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
15961         then # LU-5424
15962                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
15963                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
15964                         error "create lov data thru .lustre failed"
15965         fi
15966         echo "cp /etc/passwd $test_dir/$tfile-2"
15967         cp /etc/passwd $test_dir/$tfile-2 ||
15968                 error "copy to $test_dir/$tfile-2 failed."
15969         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
15970         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
15971                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
15972
15973         rm -rf $test_dir/tfile.lnk
15974         rm -rf $test_dir/$tfile-2
15975 }
15976
15977 test_154A() {
15978         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
15979                 skip "Need MDS version at least 2.4.1"
15980
15981         local tf=$DIR/$tfile
15982         touch $tf
15983
15984         local fid=$($LFS path2fid $tf)
15985         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
15986
15987         # check that we get the same pathname back
15988         local rootpath
15989         local found
15990         for rootpath in "$MOUNT" "$MOUNT///" "$MOUNT/$tfile"; do
15991                 echo "$rootpath $fid"
15992                 found=$($LFS fid2path $rootpath "$fid")
15993                 [ -z "$found" ] && error "fid2path unable to get '$fid' path"
15994                 [ "$found" == "$tf" ] || error "fid2path $found != $tf"
15995         done
15996
15997         # check wrong root path format
15998         rootpath=$MOUNT"_wrong"
15999         found=$($LFS fid2path $rootpath "$fid")
16000         [ -z "$found" ] || error "should fail ($rootpath != $MOUNT)"
16001 }
16002 run_test 154A "lfs path2fid and fid2path basic checks"
16003
16004 test_154B() {
16005         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16006                 skip "Need MDS version at least 2.4.1"
16007
16008         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
16009         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
16010         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
16011         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
16012
16013         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
16014         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
16015
16016         # check that we get the same pathname
16017         echo "PFID: $PFID, name: $name"
16018         local FOUND=$($LFS fid2path $MOUNT "$PFID")
16019         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
16020         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
16021                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
16022
16023         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
16024 }
16025 run_test 154B "verify the ll_decode_linkea tool"
16026
16027 test_154a() {
16028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16029         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16030         (( $MDS1_VERSION >= $(version_code 2.2.51) )) ||
16031                 skip "Need MDS version at least 2.2.51"
16032         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
16033
16034         cp /etc/hosts $DIR/$tfile
16035
16036         fid=$($LFS path2fid $DIR/$tfile)
16037         rc=$?
16038         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
16039
16040         dot_lustre_fid_permission_check "$fid" $DIR ||
16041                 error "dot lustre permission check $fid failed"
16042
16043         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
16044
16045         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
16046
16047         touch $MOUNT/.lustre/file &&
16048                 error "creation is not allowed under .lustre"
16049
16050         mkdir $MOUNT/.lustre/dir &&
16051                 error "mkdir is not allowed under .lustre"
16052
16053         rm -rf $DIR/$tfile
16054 }
16055 run_test 154a "Open-by-FID"
16056
16057 test_154b() {
16058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16059         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16060         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16061         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
16062                 skip "Need MDS version at least 2.2.51"
16063
16064         local remote_dir=$DIR/$tdir/remote_dir
16065         local MDTIDX=1
16066         local rc=0
16067
16068         mkdir -p $DIR/$tdir
16069         $LFS mkdir -i $MDTIDX $remote_dir ||
16070                 error "create remote directory failed"
16071
16072         cp /etc/hosts $remote_dir/$tfile
16073
16074         fid=$($LFS path2fid $remote_dir/$tfile)
16075         rc=$?
16076         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
16077
16078         dot_lustre_fid_permission_check "$fid" $remote_dir ||
16079                 error "dot lustre permission check $fid failed"
16080         rm -rf $DIR/$tdir
16081 }
16082 run_test 154b "Open-by-FID for remote directory"
16083
16084 test_154c() {
16085         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
16086                 skip "Need MDS version at least 2.4.1"
16087
16088         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
16089         local FID1=$($LFS path2fid $DIR/$tfile.1)
16090         local FID2=$($LFS path2fid $DIR/$tfile.2)
16091         local FID3=$($LFS path2fid $DIR/$tfile.3)
16092
16093         local N=1
16094         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
16095                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
16096                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
16097                 local want=FID$N
16098                 [ "$FID" = "${!want}" ] ||
16099                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
16100                 N=$((N + 1))
16101         done
16102
16103         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
16104         do
16105                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
16106                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
16107                 N=$((N + 1))
16108         done
16109 }
16110 run_test 154c "lfs path2fid and fid2path multiple arguments"
16111
16112 test_154d() {
16113         remote_mds_nodsh && skip "remote MDS with nodsh"
16114         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
16115                 skip "Need MDS version at least 2.5.53"
16116
16117         if remote_mds; then
16118                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
16119         else
16120                 nid="0@lo"
16121         fi
16122         local proc_ofile="mdt.*.exports.'$nid'.open_files"
16123         local fd
16124         local cmd
16125
16126         rm -f $DIR/$tfile
16127         touch $DIR/$tfile
16128
16129         local fid=$($LFS path2fid $DIR/$tfile)
16130         # Open the file
16131         fd=$(free_fd)
16132         cmd="exec $fd<$DIR/$tfile"
16133         eval $cmd
16134         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
16135         echo "$fid_list" | grep "$fid"
16136         rc=$?
16137
16138         cmd="exec $fd>/dev/null"
16139         eval $cmd
16140         if [ $rc -ne 0 ]; then
16141                 error "FID $fid not found in open files list $fid_list"
16142         fi
16143 }
16144 run_test 154d "Verify open file fid"
16145
16146 test_154e()
16147 {
16148         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
16149                 skip "Need MDS version at least 2.6.50"
16150
16151         if ls -a $MOUNT | grep -q '^\.lustre$'; then
16152                 error ".lustre returned by readdir"
16153         fi
16154 }
16155 run_test 154e ".lustre is not returned by readdir"
16156
16157 test_154f() {
16158         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
16159
16160         # create parent directory on a single MDT to avoid cross-MDT hardlinks
16161         mkdir_on_mdt0 $DIR/$tdir
16162         # test dirs inherit from its stripe
16163         mkdir -p $DIR/$tdir/foo1 || error "mkdir error"
16164         mkdir -p $DIR/$tdir/foo2 || error "mkdir error"
16165         cp /etc/hosts $DIR/$tdir/foo1/$tfile
16166         ln $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/link
16167         touch $DIR/f
16168
16169         # get fid of parents
16170         local FID0=$($LFS path2fid $DIR/$tdir)
16171         local FID1=$($LFS path2fid $DIR/$tdir/foo1)
16172         local FID2=$($LFS path2fid $DIR/$tdir/foo2)
16173         local FID3=$($LFS path2fid $DIR)
16174
16175         # check that path2fid --parents returns expected <parent_fid>/name
16176         # 1) test for a directory (single parent)
16177         local parent=$($LFS path2fid --parents $DIR/$tdir/foo1)
16178         [ "$parent" == "$FID0/foo1" ] ||
16179                 error "expected parent: $FID0/foo1, got: $parent"
16180
16181         # 2) test for a file with nlink > 1 (multiple parents)
16182         parent=$($LFS path2fid --parents $DIR/$tdir/foo1/$tfile)
16183         echo "$parent" | grep -F "$FID1/$tfile" ||
16184                 error "$FID1/$tfile not returned in parent list"
16185         echo "$parent" | grep -F "$FID2/link" ||
16186                 error "$FID2/link not returned in parent list"
16187
16188         # 3) get parent by fid
16189         local file_fid=$($LFS path2fid $DIR/$tdir/foo1/$tfile)
16190         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16191         echo "$parent" | grep -F "$FID1/$tfile" ||
16192                 error "$FID1/$tfile not returned in parent list (by fid)"
16193         echo "$parent" | grep -F "$FID2/link" ||
16194                 error "$FID2/link not returned in parent list (by fid)"
16195
16196         # 4) test for entry in root directory
16197         parent=$($LFS path2fid --parents $DIR/f)
16198         echo "$parent" | grep -F "$FID3/f" ||
16199                 error "$FID3/f not returned in parent list"
16200
16201         # 5) test it on root directory
16202         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
16203                 error "$MOUNT should not have parents"
16204
16205         # enable xattr caching and check that linkea is correctly updated
16206         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
16207         save_lustre_params client "llite.*.xattr_cache" > $save
16208         lctl set_param llite.*.xattr_cache 1
16209
16210         # 6.1) linkea update on rename
16211         mv $DIR/$tdir/foo1/$tfile $DIR/$tdir/foo2/$tfile.moved
16212
16213         # get parents by fid
16214         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16215         # foo1 should no longer be returned in parent list
16216         echo "$parent" | grep -F "$FID1" &&
16217                 error "$FID1 should no longer be in parent list"
16218         # the new path should appear
16219         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
16220                 error "$FID2/$tfile.moved is not in parent list"
16221
16222         # 6.2) linkea update on unlink
16223         rm -f $DIR/$tdir/foo2/link
16224         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
16225         # foo2/link should no longer be returned in parent list
16226         echo "$parent" | grep -F "$FID2/link" &&
16227                 error "$FID2/link should no longer be in parent list"
16228         true
16229
16230         rm -f $DIR/f
16231         restore_lustre_params < $save
16232         rm -f $save
16233 }
16234 run_test 154f "get parent fids by reading link ea"
16235
16236 test_154g()
16237 {
16238         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
16239            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
16240                 skip "Need MDS version at least 2.6.92"
16241
16242         mkdir_on_mdt0 $DIR/$tdir
16243         llapi_fid_test -d $DIR/$tdir
16244 }
16245 run_test 154g "various llapi FID tests"
16246
16247 test_155_small_load() {
16248     local temp=$TMP/$tfile
16249     local file=$DIR/$tfile
16250
16251     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
16252         error "dd of=$temp bs=6096 count=1 failed"
16253     cp $temp $file
16254     cancel_lru_locks $OSC
16255     cmp $temp $file || error "$temp $file differ"
16256
16257     $TRUNCATE $temp 6000
16258     $TRUNCATE $file 6000
16259     cmp $temp $file || error "$temp $file differ (truncate1)"
16260
16261     echo "12345" >>$temp
16262     echo "12345" >>$file
16263     cmp $temp $file || error "$temp $file differ (append1)"
16264
16265     echo "12345" >>$temp
16266     echo "12345" >>$file
16267     cmp $temp $file || error "$temp $file differ (append2)"
16268
16269     rm -f $temp $file
16270     true
16271 }
16272
16273 test_155_big_load() {
16274         remote_ost_nodsh && skip "remote OST with nodsh"
16275
16276         local temp=$TMP/$tfile
16277         local file=$DIR/$tfile
16278
16279         free_min_max
16280         local cache_size=$(do_facet ost$((MAXI+1)) \
16281                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
16282
16283         # LU-16042: can not get the cache size on Arm64 VM here, fallback to a
16284         # pre-set value
16285         if [ -z "$cache_size" ]; then
16286                 cache_size=256
16287         fi
16288         local large_file_size=$((cache_size * 2))
16289
16290         echo "OSS cache size: $cache_size KB"
16291         echo "Large file size: $large_file_size KB"
16292
16293         [ $MAXV -le $large_file_size ] &&
16294                 skip_env "max available OST size needs > $large_file_size KB"
16295
16296         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
16297
16298         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
16299                 error "dd of=$temp bs=$large_file_size count=1k failed"
16300         cp $temp $file
16301         ls -lh $temp $file
16302         cancel_lru_locks osc
16303         cmp $temp $file || error "$temp $file differ"
16304
16305         rm -f $temp $file
16306         true
16307 }
16308
16309 save_writethrough() {
16310         local facets=$(get_facets OST)
16311
16312         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
16313 }
16314
16315 test_155a() {
16316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16317
16318         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16319
16320         save_writethrough $p
16321
16322         set_cache read on
16323         set_cache writethrough on
16324         test_155_small_load
16325         restore_lustre_params < $p
16326         rm -f $p
16327 }
16328 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
16329
16330 test_155b() {
16331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16332
16333         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16334
16335         save_writethrough $p
16336
16337         set_cache read on
16338         set_cache writethrough off
16339         test_155_small_load
16340         restore_lustre_params < $p
16341         rm -f $p
16342 }
16343 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
16344
16345 test_155c() {
16346         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16347
16348         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16349
16350         save_writethrough $p
16351
16352         set_cache read off
16353         set_cache writethrough on
16354         test_155_small_load
16355         restore_lustre_params < $p
16356         rm -f $p
16357 }
16358 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
16359
16360 test_155d() {
16361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16362
16363         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16364
16365         save_writethrough $p
16366
16367         set_cache read off
16368         set_cache writethrough off
16369         test_155_small_load
16370         restore_lustre_params < $p
16371         rm -f $p
16372 }
16373 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
16374
16375 test_155e() {
16376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16377
16378         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16379
16380         save_writethrough $p
16381
16382         set_cache read on
16383         set_cache writethrough on
16384         test_155_big_load
16385         restore_lustre_params < $p
16386         rm -f $p
16387 }
16388 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
16389
16390 test_155f() {
16391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16392
16393         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16394
16395         save_writethrough $p
16396
16397         set_cache read on
16398         set_cache writethrough off
16399         test_155_big_load
16400         restore_lustre_params < $p
16401         rm -f $p
16402 }
16403 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
16404
16405 test_155g() {
16406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16407
16408         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16409
16410         save_writethrough $p
16411
16412         set_cache read off
16413         set_cache writethrough on
16414         test_155_big_load
16415         restore_lustre_params < $p
16416         rm -f $p
16417 }
16418 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
16419
16420 test_155h() {
16421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16422
16423         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16424
16425         save_writethrough $p
16426
16427         set_cache read off
16428         set_cache writethrough off
16429         test_155_big_load
16430         restore_lustre_params < $p
16431         rm -f $p
16432 }
16433 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
16434
16435 test_156() {
16436         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16437         remote_ost_nodsh && skip "remote OST with nodsh"
16438         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
16439                 skip "stats not implemented on old servers"
16440         [ "$ost1_FSTYPE" = "zfs" ] &&
16441                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
16442
16443         local CPAGES=3
16444         local BEFORE
16445         local AFTER
16446         local file="$DIR/$tfile"
16447         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
16448
16449         save_writethrough $p
16450         roc_hit_init
16451
16452         log "Turn on read and write cache"
16453         set_cache read on
16454         set_cache writethrough on
16455
16456         log "Write data and read it back."
16457         log "Read should be satisfied from the cache."
16458         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16459         BEFORE=$(roc_hit)
16460         cancel_lru_locks osc
16461         cat $file >/dev/null
16462         AFTER=$(roc_hit)
16463         if ! let "AFTER - BEFORE == CPAGES"; then
16464                 error "NOT IN CACHE (2): before: $BEFORE, after: $AFTER"
16465         else
16466                 log "cache hits: before: $BEFORE, after: $AFTER"
16467         fi
16468
16469         log "Read again; it should be satisfied from the cache."
16470         BEFORE=$AFTER
16471         cancel_lru_locks osc
16472         cat $file >/dev/null
16473         AFTER=$(roc_hit)
16474         if ! let "AFTER - BEFORE == CPAGES"; then
16475                 error "NOT IN CACHE (3): before: $BEFORE, after: $AFTER"
16476         else
16477                 log "cache hits:: before: $BEFORE, after: $AFTER"
16478         fi
16479
16480         log "Turn off the read cache and turn on the write cache"
16481         set_cache read off
16482         set_cache writethrough on
16483
16484         log "Read again; it should be satisfied from the cache."
16485         BEFORE=$(roc_hit)
16486         cancel_lru_locks osc
16487         cat $file >/dev/null
16488         AFTER=$(roc_hit)
16489         if ! let "AFTER - BEFORE == CPAGES"; then
16490                 error "NOT IN CACHE (4): before: $BEFORE, after: $AFTER"
16491         else
16492                 log "cache hits:: before: $BEFORE, after: $AFTER"
16493         fi
16494
16495         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16496                 # > 2.12.56 uses pagecache if cached
16497                 log "Read again; it should not be satisfied from the cache."
16498                 BEFORE=$AFTER
16499                 cancel_lru_locks osc
16500                 cat $file >/dev/null
16501                 AFTER=$(roc_hit)
16502                 if ! let "AFTER - BEFORE == 0"; then
16503                         error "IN CACHE (5): before: $BEFORE, after: $AFTER"
16504                 else
16505                         log "cache hits:: before: $BEFORE, after: $AFTER"
16506                 fi
16507         fi
16508
16509         log "Write data and read it back."
16510         log "Read should be satisfied from the cache."
16511         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16512         BEFORE=$(roc_hit)
16513         cancel_lru_locks osc
16514         cat $file >/dev/null
16515         AFTER=$(roc_hit)
16516         if ! let "AFTER - BEFORE == CPAGES"; then
16517                 error "NOT IN CACHE (6): before: $BEFORE, after: $AFTER"
16518         else
16519                 log "cache hits:: before: $BEFORE, after: $AFTER"
16520         fi
16521
16522         if [ $OST1_VERSION -lt $(version_code 2.12.55) ]; then
16523                 # > 2.12.56 uses pagecache if cached
16524                 log "Read again; it should not be satisfied from the cache."
16525                 BEFORE=$AFTER
16526                 cancel_lru_locks osc
16527                 cat $file >/dev/null
16528                 AFTER=$(roc_hit)
16529                 if ! let "AFTER - BEFORE == 0"; then
16530                         error "IN CACHE (7): before: $BEFORE, after: $AFTER"
16531                 else
16532                         log "cache hits:: before: $BEFORE, after: $AFTER"
16533                 fi
16534         fi
16535
16536         log "Turn off read and write cache"
16537         set_cache read off
16538         set_cache writethrough off
16539
16540         log "Write data and read it back"
16541         log "It should not be satisfied from the cache."
16542         rm -f $file
16543         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16544         cancel_lru_locks osc
16545         BEFORE=$(roc_hit)
16546         cat $file >/dev/null
16547         AFTER=$(roc_hit)
16548         if ! let "AFTER - BEFORE == 0"; then
16549                 error_ignore bz20762 "IN CACHE (8):before:$BEFORE,after:$AFTER"
16550         else
16551                 log "cache hits:: before: $BEFORE, after: $AFTER"
16552         fi
16553
16554         log "Turn on the read cache and turn off the write cache"
16555         set_cache read on
16556         set_cache writethrough off
16557
16558         log "Write data and read it back"
16559         log "It should not be satisfied from the cache."
16560         rm -f $file
16561         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
16562         BEFORE=$(roc_hit)
16563         cancel_lru_locks osc
16564         cat $file >/dev/null
16565         AFTER=$(roc_hit)
16566         if ! let "AFTER - BEFORE == 0"; then
16567                 error_ignore bz20762 "IN CACHE (9):before:$BEFORE,after:$AFTER"
16568         else
16569                 log "cache hits:: before: $BEFORE, after: $AFTER"
16570         fi
16571
16572         log "Read again; it should be satisfied from the cache."
16573         BEFORE=$(roc_hit)
16574         cancel_lru_locks osc
16575         cat $file >/dev/null
16576         AFTER=$(roc_hit)
16577         if ! let "AFTER - BEFORE == CPAGES"; then
16578                 error "NOT IN CACHE (1): before: $BEFORE, after: $AFTER"
16579         else
16580                 log "cache hits:: before: $BEFORE, after: $AFTER"
16581         fi
16582
16583         restore_lustre_params < $p
16584         rm -f $p $file
16585 }
16586 run_test 156 "Verification of tunables"
16587
16588 test_160a() {
16589         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16590         remote_mds_nodsh && skip "remote MDS with nodsh"
16591         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16592                 skip "Need MDS version at least 2.2.0"
16593
16594         changelog_register || error "changelog_register failed"
16595         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16596         changelog_users $SINGLEMDS | grep -q $cl_user ||
16597                 error "User $cl_user not found in changelog_users"
16598
16599         mkdir_on_mdt0 $DIR/$tdir
16600
16601         # change something
16602         test_mkdir -p $DIR/$tdir/pics/2008/zachy
16603         changelog_clear 0 || error "changelog_clear failed"
16604         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
16605         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
16606         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16607         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16608         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16609         rm $DIR/$tdir/pics/desktop.jpg
16610
16611         echo "verifying changelog mask"
16612         changelog_chmask "-MKDIR"
16613         changelog_chmask "-CLOSE"
16614
16615         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
16616         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
16617
16618         changelog_chmask "+MKDIR"
16619         changelog_chmask "+CLOSE"
16620
16621         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
16622         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
16623
16624         MKDIRS=$(changelog_dump | grep -c "MKDIR")
16625         CLOSES=$(changelog_dump | grep -c "CLOSE")
16626         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
16627         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
16628
16629         # verify contents
16630         echo "verifying target fid"
16631         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
16632         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
16633         [ "$fidc" == "$fidf" ] ||
16634                 error "changelog '$tfile' fid $fidc != file fid $fidf"
16635         echo "verifying parent fid"
16636         # The FID returned from the Changelog may be the directory shard on
16637         # a different MDT, and not the FID returned by path2fid on the parent.
16638         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
16639         # since this is what will matter when recreating this file in the tree.
16640         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
16641         local pathp=$($LFS fid2path $MOUNT "$fidp")
16642         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
16643                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
16644
16645         echo "getting records for $cl_user"
16646         changelog_users $SINGLEMDS
16647         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
16648         local nclr=3
16649         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
16650                 error "changelog_clear failed"
16651         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
16652         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
16653         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
16654                 error "user index expect $user_rec1 + $nclr != $user_rec2"
16655
16656         local min0_rec=$(changelog_users $SINGLEMDS |
16657                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
16658         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
16659                           awk '{ print $1; exit; }')
16660
16661         changelog_dump | tail -n 5
16662         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
16663         [ $first_rec == $((min0_rec + 1)) ] ||
16664                 error "first index should be $min0_rec + 1 not $first_rec"
16665
16666         # LU-3446 changelog index reset on MDT restart
16667         local cur_rec1=$(changelog_users $SINGLEMDS |
16668                          awk '/^current.index:/ { print $NF }')
16669         changelog_clear 0 ||
16670                 error "clear all changelog records for $cl_user failed"
16671         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
16672         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
16673                 error "Fail to start $SINGLEMDS"
16674         local cur_rec2=$(changelog_users $SINGLEMDS |
16675                          awk '/^current.index:/ { print $NF }')
16676         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
16677         [ $cur_rec1 == $cur_rec2 ] ||
16678                 error "current index should be $cur_rec1 not $cur_rec2"
16679
16680         echo "verifying users from this test are deregistered"
16681         changelog_deregister || error "changelog_deregister failed"
16682         changelog_users $SINGLEMDS | grep -q $cl_user &&
16683                 error "User '$cl_user' still in changelog_users"
16684
16685         # lctl get_param -n mdd.*.changelog_users
16686         # current_index: 144
16687         # ID    index (idle seconds)
16688         # cl3   144   (2) mask=<list>
16689         if [ -z "$(changelog_users $SINGLEMDS | grep -v current.index)" ]; then
16690                 # this is the normal case where all users were deregistered
16691                 # make sure no new records are added when no users are present
16692                 local last_rec1=$(changelog_users $SINGLEMDS |
16693                                   awk '/^current.index:/ { print $NF }')
16694                 touch $DIR/$tdir/chloe
16695                 local last_rec2=$(changelog_users $SINGLEMDS |
16696                                   awk '/^current.index:/ { print $NF }')
16697                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
16698                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
16699         else
16700                 # any changelog users must be leftovers from a previous test
16701                 changelog_users $SINGLEMDS
16702                 echo "other changelog users; can't verify off"
16703         fi
16704 }
16705 run_test 160a "changelog sanity"
16706
16707 test_160b() { # LU-3587
16708         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16709         remote_mds_nodsh && skip "remote MDS with nodsh"
16710         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
16711                 skip "Need MDS version at least 2.2.0"
16712
16713         changelog_register || error "changelog_register failed"
16714         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
16715         changelog_users $SINGLEMDS | grep -q $cl_user ||
16716                 error "User '$cl_user' not found in changelog_users"
16717
16718         local longname1=$(str_repeat a 255)
16719         local longname2=$(str_repeat b 255)
16720
16721         cd $DIR
16722         echo "creating very long named file"
16723         touch $longname1 || error "create of '$longname1' failed"
16724         echo "renaming very long named file"
16725         mv $longname1 $longname2
16726
16727         changelog_dump | grep RENME | tail -n 5
16728         rm -f $longname2
16729 }
16730 run_test 160b "Verify that very long rename doesn't crash in changelog"
16731
16732 test_160c() {
16733         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16734         remote_mds_nodsh && skip "remote MDS with nodsh"
16735
16736         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16737                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16738                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16739                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16740
16741         local rc=0
16742
16743         # Registration step
16744         changelog_register || error "changelog_register failed"
16745
16746         rm -rf $DIR/$tdir
16747         mkdir -p $DIR/$tdir
16748         $MCREATE $DIR/$tdir/foo_160c
16749         changelog_chmask "-TRUNC"
16750         $TRUNCATE $DIR/$tdir/foo_160c 200
16751         changelog_chmask "+TRUNC"
16752         $TRUNCATE $DIR/$tdir/foo_160c 199
16753         changelog_dump | tail -n 5
16754         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
16755         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
16756 }
16757 run_test 160c "verify that changelog log catch the truncate event"
16758
16759 test_160d() {
16760         remote_mds_nodsh && skip "remote MDS with nodsh"
16761         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16763         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
16764                 skip "Need MDS version at least 2.7.60"
16765
16766         # Registration step
16767         changelog_register || error "changelog_register failed"
16768
16769         mkdir -p $DIR/$tdir/migrate_dir
16770         changelog_clear 0 || error "changelog_clear failed"
16771
16772         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
16773         changelog_dump | tail -n 5
16774         local migrates=$(changelog_dump | grep -c "MIGRT")
16775         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
16776 }
16777 run_test 160d "verify that changelog log catch the migrate event"
16778
16779 test_160e() {
16780         remote_mds_nodsh && skip "remote MDS with nodsh"
16781
16782         # Create a user
16783         changelog_register || error "changelog_register failed"
16784
16785         local MDT0=$(facet_svc $SINGLEMDS)
16786         local rc
16787
16788         # No user (expect fail)
16789         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister
16790         rc=$?
16791         if [ $rc -eq 0 ]; then
16792                 error "Should fail without user"
16793         elif [ $rc -ne 4 ]; then
16794                 error "changelog_deregister failed with $rc, expect 4(CMD_HELP)"
16795         fi
16796
16797         # Delete a future user (expect fail)
16798         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
16799         rc=$?
16800         if [ $rc -eq 0 ]; then
16801                 error "Deleted non-existant user cl77"
16802         elif [ $rc -ne 2 ]; then
16803                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
16804         fi
16805
16806         # Clear to a bad index (1 billion should be safe)
16807         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
16808         rc=$?
16809
16810         if [ $rc -eq 0 ]; then
16811                 error "Successfully cleared to invalid CL index"
16812         elif [ $rc -ne 22 ]; then
16813                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
16814         fi
16815 }
16816 run_test 160e "changelog negative testing (should return errors)"
16817
16818 test_160f() {
16819         remote_mds_nodsh && skip "remote MDS with nodsh" && return
16820         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
16821                 skip "Need MDS version at least 2.10.56"
16822
16823         local mdts=$(comma_list $(mdts_nodes))
16824
16825         # Create a user
16826         changelog_register || error "first changelog_register failed"
16827         changelog_register || error "second changelog_register failed"
16828         local cl_users
16829         declare -A cl_user1
16830         declare -A cl_user2
16831         local user_rec1
16832         local user_rec2
16833         local i
16834
16835         # generate some changelog records to accumulate on each MDT
16836         # use all_char because created files should be evenly distributed
16837         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16838                 error "test_mkdir $tdir failed"
16839         log "$(date +%s): creating first files"
16840         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16841                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT)) ||
16842                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT)) failed"
16843         done
16844
16845         # check changelogs have been generated
16846         local start=$SECONDS
16847         local idle_time=$((MDSCOUNT * 5 + 5))
16848         local nbcl=$(changelog_dump | wc -l)
16849         [[ $nbcl -eq 0 ]] && error "no changelogs found"
16850
16851         for param in "changelog_max_idle_time=$idle_time" \
16852                      "changelog_gc=1" \
16853                      "changelog_min_gc_interval=2" \
16854                      "changelog_min_free_cat_entries=3"; do
16855                 local MDT0=$(facet_svc $SINGLEMDS)
16856                 local var="${param%=*}"
16857                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16858
16859                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16860                 do_nodes $mdts $LCTL set_param mdd.*.$param
16861         done
16862
16863         # force cl_user2 to be idle (1st part), but also cancel the
16864         # cl_user1 records so that it is not evicted later in the test.
16865         local sleep1=$((idle_time / 2))
16866         echo "$(date +%s): sleep1 $sleep1/${idle_time}s"
16867         sleep $sleep1
16868
16869         # simulate changelog catalog almost full
16870         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
16871         do_nodes $mdts "$LCTL set_param fail_loc=0x1313 fail_val=3"
16872
16873         for i in $(seq $MDSCOUNT); do
16874                 cl_users=(${CL_USERS[mds$i]})
16875                 cl_user1[mds$i]="${cl_users[0]}"
16876                 cl_user2[mds$i]="${cl_users[1]}"
16877
16878                 [ -n "${cl_user1[mds$i]}" ] ||
16879                         error "mds$i: no user registered"
16880                 [ -n "${cl_user2[mds$i]}" ] ||
16881                         error "mds$i: only ${cl_user2[mds$i]} is registered"
16882
16883                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16884                 [ -n "$user_rec1" ] ||
16885                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16886                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
16887                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16888                 [ -n "$user_rec2" ] ||
16889                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16890                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
16891                      "$user_rec1 + 2 == $user_rec2"
16892                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
16893                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
16894                               "$user_rec1 + 2, but is $user_rec2"
16895                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
16896                 [ -n "$user_rec2" ] ||
16897                         error "mds$i: User ${cl_user2[mds$i]} not registered"
16898                 [ $user_rec1 == $user_rec2 ] ||
16899                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
16900                               "$user_rec1, but is $user_rec2"
16901         done
16902
16903         # force cl_user2 idle (2nd part) to just exceed changelog_max_idle_time
16904         local sleep2=$((idle_time - (SECONDS - start) + 1))
16905         echo "$(date +%s): sleep2 $sleep2/${idle_time}s"
16906         sleep $sleep2
16907
16908         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
16909         # cl_user1 should be OK because it recently processed records.
16910         echo "$(date +%s): creating $((MDSCOUNT * 2)) files"
16911         for ((i = 0; i < MDSCOUNT * 2; i++)); do
16912                 $LFS mkdir -i $((i%MDSCOUNT)) $DIR/$tdir/d$i.$((i/MDSCOUNT+2))||
16913                         error "create $DIR/$tdir/d$i.$((i/MDSCOUNT+2)) failed"
16914         done
16915
16916         # ensure gc thread is done
16917         for i in $(mdts_nodes); do
16918                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
16919                         error "$i: GC-thread not done"
16920         done
16921
16922         local first_rec
16923         for (( i = 1; i <= MDSCOUNT; i++ )); do
16924                 # check cl_user1 still registered
16925                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
16926                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16927                 # check cl_user2 unregistered
16928                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
16929                         error "mds$i: User ${cl_user2[mds$i]} still registered"
16930
16931                 # check changelogs are present and starting at $user_rec1 + 1
16932                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
16933                 [ -n "$user_rec1" ] ||
16934                         error "mds$i: User ${cl_user1[mds$i]} not registered"
16935                 first_rec=$($LFS changelog $(facet_svc mds$i) |
16936                             awk '{ print $1; exit; }')
16937
16938                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
16939                 [ $((user_rec1 + 1)) == $first_rec ] ||
16940                         error "mds$i: rec $first_rec != $user_rec1 + 1"
16941         done
16942 }
16943 run_test 160f "changelog garbage collect (timestamped users)"
16944
16945 test_160g() {
16946         remote_mds_nodsh && skip "remote MDS with nodsh"
16947         [[ $MDS1_VERSION -ge $(version_code 2.14.55) ]] ||
16948                 skip "Need MDS version at least 2.14.55"
16949
16950         local mdts=$(comma_list $(mdts_nodes))
16951
16952         # Create a user
16953         changelog_register || error "first changelog_register failed"
16954         changelog_register || error "second changelog_register failed"
16955         local cl_users
16956         declare -A cl_user1
16957         declare -A cl_user2
16958         local user_rec1
16959         local user_rec2
16960         local i
16961
16962         # generate some changelog records to accumulate on each MDT
16963         # use all_char because created files should be evenly distributed
16964         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
16965                 error "test_mkdir $tdir failed"
16966         for ((i = 0; i < MDSCOUNT; i++)); do
16967                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
16968                         error "create $DIR/$tdir/d$i.1 failed"
16969         done
16970
16971         # check changelogs have been generated
16972         local nbcl=$(changelog_dump | wc -l)
16973         (( $nbcl > 0 )) || error "no changelogs found"
16974
16975         # reduce the max_idle_indexes value to make sure we exceed it
16976         for param in "changelog_max_idle_indexes=2" \
16977                      "changelog_gc=1" \
16978                      "changelog_min_gc_interval=2"; do
16979                 local MDT0=$(facet_svc $SINGLEMDS)
16980                 local var="${param%=*}"
16981                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
16982
16983                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
16984                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
16985                         error "unable to set mdd.*.$param"
16986         done
16987
16988         local start=$SECONDS
16989         for i in $(seq $MDSCOUNT); do
16990                 cl_users=(${CL_USERS[mds$i]})
16991                 cl_user1[mds$i]="${cl_users[0]}"
16992                 cl_user2[mds$i]="${cl_users[1]}"
16993
16994                 [ -n "${cl_user1[mds$i]}" ] ||
16995                         error "mds$i: user1 is not registered"
16996                 [ -n "${cl_user2[mds$i]}" ] ||
16997                         error "mds$i: only ${cl_user1[mds$i]} is registered"
16998
16999                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17000                 [ -n "$user_rec1" ] ||
17001                         error "mds$i: user1 ${cl_user1[mds$i]} not found"
17002                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17003                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17004                 [ -n "$user_rec2" ] ||
17005                         error "mds$i: user1 ${cl_user1[mds$i]} not found (2)"
17006                 echo "mds$i: verifying user1 ${cl_user1[mds$i]} clear: " \
17007                      "$user_rec1 + 2 == $user_rec2"
17008                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17009                         error "mds$i: user1 ${cl_user1[mds$i]} index " \
17010                               "expected $user_rec1 + 2, but is $user_rec2"
17011                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17012                 [ -n "$user_rec2" ] ||
17013                         error "mds$i: user2 ${cl_user2[mds$i]} not found"
17014                 [ $user_rec1 == $user_rec2 ] ||
17015                         error "mds$i: user2 ${cl_user2[mds$i]} index " \
17016                               "expected $user_rec1, but is $user_rec2"
17017         done
17018
17019         # ensure we are past the previous changelog_min_gc_interval set above
17020         local sleep2=$((start + 2 - SECONDS))
17021         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17022         # Generate one more changelog to trigger GC at fail_loc for cl_user2.
17023         # cl_user1 should be OK because it recently processed records.
17024         for ((i = 0; i < MDSCOUNT; i++)); do
17025                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 ||
17026                         error "create $DIR/$tdir/d$i.3 failed"
17027         done
17028
17029         # ensure gc thread is done
17030         for i in $(mdts_nodes); do
17031                 wait_update $i "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
17032                         error "$i: GC-thread not done"
17033         done
17034
17035         local first_rec
17036         for (( i = 1; i <= MDSCOUNT; i++ )); do
17037                 # check cl_user1 still registered
17038                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17039                         error "mds$i: user1 ${cl_user1[mds$i]} not found (3)"
17040                 # check cl_user2 unregistered
17041                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17042                         error "mds$i: user2 ${cl_user2[mds$i]} is registered"
17043
17044                 # check changelogs are present and starting at $user_rec1 + 1
17045                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17046                 [ -n "$user_rec1" ] ||
17047                         error "mds$i: user1 ${cl_user1[mds$i]} not found (4)"
17048                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17049                             awk '{ print $1; exit; }')
17050
17051                 echo "mds$i: $(date +%s) verify rec $user_rec1+1 == $first_rec"
17052                 [ $((user_rec1 + 1)) == $first_rec ] ||
17053                         error "mds$i: rec $first_rec != $user_rec1 + 1"
17054         done
17055 }
17056 run_test 160g "changelog garbage collect on idle records"
17057
17058 test_160h() {
17059         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17060         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
17061                 skip "Need MDS version at least 2.10.56"
17062
17063         local mdts=$(comma_list $(mdts_nodes))
17064
17065         # Create a user
17066         changelog_register || error "first changelog_register failed"
17067         changelog_register || error "second changelog_register failed"
17068         local cl_users
17069         declare -A cl_user1
17070         declare -A cl_user2
17071         local user_rec1
17072         local user_rec2
17073         local i
17074
17075         # generate some changelog records to accumulate on each MDT
17076         # use all_char because created files should be evenly distributed
17077         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17078                 error "test_mkdir $tdir failed"
17079         for ((i = 0; i < MDSCOUNT; i++)); do
17080                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17081                         error "create $DIR/$tdir/d$i.1 failed"
17082         done
17083
17084         # check changelogs have been generated
17085         local nbcl=$(changelog_dump | wc -l)
17086         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17087
17088         for param in "changelog_max_idle_time=10" \
17089                      "changelog_gc=1" \
17090                      "changelog_min_gc_interval=2"; do
17091                 local MDT0=$(facet_svc $SINGLEMDS)
17092                 local var="${param%=*}"
17093                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17094
17095                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17096                 do_nodes $mdts $LCTL set_param mdd.*.$param
17097         done
17098
17099         # force cl_user2 to be idle (1st part)
17100         sleep 9
17101
17102         for i in $(seq $MDSCOUNT); do
17103                 cl_users=(${CL_USERS[mds$i]})
17104                 cl_user1[mds$i]="${cl_users[0]}"
17105                 cl_user2[mds$i]="${cl_users[1]}"
17106
17107                 [ -n "${cl_user1[mds$i]}" ] ||
17108                         error "mds$i: no user registered"
17109                 [ -n "${cl_user2[mds$i]}" ] ||
17110                         error "mds$i: only ${cl_user2[mds$i]} is registered"
17111
17112                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17113                 [ -n "$user_rec1" ] ||
17114                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17115                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
17116                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17117                 [ -n "$user_rec2" ] ||
17118                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17119                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
17120                      "$user_rec1 + 2 == $user_rec2"
17121                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
17122                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
17123                               "$user_rec1 + 2, but is $user_rec2"
17124                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
17125                 [ -n "$user_rec2" ] ||
17126                         error "mds$i: User ${cl_user2[mds$i]} not registered"
17127                 [ $user_rec1 == $user_rec2 ] ||
17128                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
17129                               "$user_rec1, but is $user_rec2"
17130         done
17131
17132         # force cl_user2 to be idle (2nd part) and to reach
17133         # changelog_max_idle_time
17134         sleep 2
17135
17136         # force each GC-thread start and block then
17137         # one per MDT/MDD, set fail_val accordingly
17138         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
17139         do_nodes $mdts $LCTL set_param fail_loc=0x1316
17140
17141         # generate more changelogs to trigger fail_loc
17142         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17143                 error "create $DIR/$tdir/${tfile}bis failed"
17144
17145         # stop MDT to stop GC-thread, should be done in back-ground as it will
17146         # block waiting for the thread to be released and exit
17147         declare -A stop_pids
17148         for i in $(seq $MDSCOUNT); do
17149                 stop mds$i &
17150                 stop_pids[mds$i]=$!
17151         done
17152
17153         for i in $(mdts_nodes); do
17154                 local facet
17155                 local nb=0
17156                 local facets=$(facets_up_on_host $i)
17157
17158                 for facet in ${facets//,/ }; do
17159                         if [[ $facet == mds* ]]; then
17160                                 nb=$((nb + 1))
17161                         fi
17162                 done
17163                 # ensure each MDS's gc threads are still present and all in "R"
17164                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
17165                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
17166                         error "$i: expected $nb GC-thread"
17167                 wait_update $i \
17168                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
17169                         "R" 20 ||
17170                         error "$i: GC-thread not found in R-state"
17171                 # check umounts of each MDT on MDS have reached kthread_stop()
17172                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
17173                         error "$i: expected $nb umount"
17174                 wait_update $i \
17175                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
17176                         error "$i: umount not found in D-state"
17177         done
17178
17179         # release all GC-threads
17180         do_nodes $mdts $LCTL set_param fail_loc=0
17181
17182         # wait for MDT stop to complete
17183         for i in $(seq $MDSCOUNT); do
17184                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
17185         done
17186
17187         # XXX
17188         # may try to check if any orphan changelog records are present
17189         # via ldiskfs/zfs and llog_reader...
17190
17191         # re-start/mount MDTs
17192         for i in $(seq $MDSCOUNT); do
17193                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
17194                         error "Fail to start mds$i"
17195         done
17196
17197         local first_rec
17198         for i in $(seq $MDSCOUNT); do
17199                 # check cl_user1 still registered
17200                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
17201                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17202                 # check cl_user2 unregistered
17203                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
17204                         error "mds$i: User ${cl_user2[mds$i]} still registered"
17205
17206                 # check changelogs are present and starting at $user_rec1 + 1
17207                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
17208                 [ -n "$user_rec1" ] ||
17209                         error "mds$i: User ${cl_user1[mds$i]} not registered"
17210                 first_rec=$($LFS changelog $(facet_svc mds$i) |
17211                             awk '{ print $1; exit; }')
17212
17213                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
17214                 [ $((user_rec1 + 1)) == $first_rec ] ||
17215                         error "mds$i: first index should be $user_rec1 + 1, " \
17216                               "but is $first_rec"
17217         done
17218 }
17219 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
17220               "during mount"
17221
17222 test_160i() {
17223
17224         local mdts=$(comma_list $(mdts_nodes))
17225
17226         changelog_register || error "first changelog_register failed"
17227
17228         # generate some changelog records to accumulate on each MDT
17229         # use all_char because created files should be evenly distributed
17230         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17231                 error "test_mkdir $tdir failed"
17232         for ((i = 0; i < MDSCOUNT; i++)); do
17233                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17234                         error "create $DIR/$tdir/d$i.1 failed"
17235         done
17236
17237         # check changelogs have been generated
17238         local nbcl=$(changelog_dump | wc -l)
17239         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17240
17241         # simulate race between register and unregister
17242         # XXX as fail_loc is set per-MDS, with DNE configs the race
17243         # simulation will only occur for one MDT per MDS and for the
17244         # others the normal race scenario will take place
17245         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
17246         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
17247         do_nodes $mdts $LCTL set_param fail_val=1
17248
17249         # unregister 1st user
17250         changelog_deregister &
17251         local pid1=$!
17252         # wait some time for deregister work to reach race rdv
17253         sleep 2
17254         # register 2nd user
17255         changelog_register || error "2nd user register failed"
17256
17257         wait $pid1 || error "1st user deregister failed"
17258
17259         local i
17260         local last_rec
17261         declare -A LAST_REC
17262         for i in $(seq $MDSCOUNT); do
17263                 if changelog_users mds$i | grep "^cl"; then
17264                         # make sure new records are added with one user present
17265                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
17266                                           awk '/^current.index:/ { print $NF }')
17267                 else
17268                         error "mds$i has no user registered"
17269                 fi
17270         done
17271
17272         # generate more changelog records to accumulate on each MDT
17273         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
17274                 error "create $DIR/$tdir/${tfile}bis failed"
17275
17276         for i in $(seq $MDSCOUNT); do
17277                 last_rec=$(changelog_users $SINGLEMDS |
17278                            awk '/^current.index:/ { print $NF }')
17279                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
17280                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
17281                         error "changelogs are off on mds$i"
17282         done
17283 }
17284 run_test 160i "changelog user register/unregister race"
17285
17286 test_160j() {
17287         remote_mds_nodsh && skip "remote MDS with nodsh"
17288         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
17289                 skip "Need MDS version at least 2.12.56"
17290
17291         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
17292         stack_trap "umount $MOUNT2" EXIT
17293
17294         changelog_register || error "first changelog_register failed"
17295         stack_trap "changelog_deregister" EXIT
17296
17297         # generate some changelog
17298         # use all_char because created files should be evenly distributed
17299         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17300                 error "mkdir $tdir failed"
17301         for ((i = 0; i < MDSCOUNT; i++)); do
17302                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17303                         error "create $DIR/$tdir/d$i.1 failed"
17304         done
17305
17306         # open the changelog device
17307         exec 3>/dev/changelog-$FSNAME-MDT0000
17308         stack_trap "exec 3>&-" EXIT
17309         exec 4</dev/changelog-$FSNAME-MDT0000
17310         stack_trap "exec 4<&-" EXIT
17311
17312         # umount the first lustre mount
17313         umount $MOUNT
17314         stack_trap "mount_client $MOUNT" EXIT
17315
17316         # read changelog, which may or may not fail, but should not crash
17317         cat <&4 >/dev/null
17318
17319         # clear changelog
17320         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17321         changelog_users $SINGLEMDS | grep -q $cl_user ||
17322                 error "User $cl_user not found in changelog_users"
17323
17324         printf 'clear:'$cl_user':0' >&3
17325 }
17326 run_test 160j "client can be umounted while its chanangelog is being used"
17327
17328 test_160k() {
17329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17330         remote_mds_nodsh && skip "remote MDS with nodsh"
17331
17332         mkdir -p $DIR/$tdir/1/1
17333
17334         changelog_register || error "changelog_register failed"
17335         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17336
17337         changelog_users $SINGLEMDS | grep -q $cl_user ||
17338                 error "User '$cl_user' not found in changelog_users"
17339 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
17340         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
17341         rmdir $DIR/$tdir/1/1 & sleep 1
17342         mkdir $DIR/$tdir/2
17343         touch $DIR/$tdir/2/2
17344         rm -rf $DIR/$tdir/2
17345
17346         wait
17347         sleep 4
17348
17349         changelog_dump | grep rmdir || error "rmdir not recorded"
17350 }
17351 run_test 160k "Verify that changelog records are not lost"
17352
17353 # Verifies that a file passed as a parameter has recently had an operation
17354 # performed on it that has generated an MTIME changelog which contains the
17355 # correct parent FID. As files might reside on a different MDT from the
17356 # parent directory in DNE configurations, the FIDs are translated to paths
17357 # before being compared, which should be identical
17358 compare_mtime_changelog() {
17359         local file="${1}"
17360         local mdtidx
17361         local mtime
17362         local cl_fid
17363         local pdir
17364         local dir
17365
17366         mdtidx=$($LFS getstripe --mdt-index $file)
17367         mdtidx=$(printf "%04x" $mdtidx)
17368
17369         # Obtain the parent FID from the MTIME changelog
17370         mtime=$($LFS changelog $FSNAME-MDT$mdtidx | tail -n 1 | grep MTIME)
17371         [ -z "$mtime" ] && error "MTIME changelog not recorded"
17372
17373         cl_fid=$(sed -e 's/.* p=//' -e 's/ .*//' <<<$mtime)
17374         [ -z "$cl_fid" ] && error "parent FID not present"
17375
17376         # Verify that the path for the parent FID is the same as the path for
17377         # the test directory
17378         pdir=$($LFS fid2path $MOUNT "$cl_fid")
17379
17380         dir=$(dirname $1)
17381
17382         [[ "${pdir%/}" == "$dir" ]] ||
17383                 error "MTIME changelog parent FID is wrong, expected $dir, got $pdir"
17384 }
17385
17386 test_160l() {
17387         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17388
17389         remote_mds_nodsh && skip "remote MDS with nodsh"
17390         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
17391                 skip "Need MDS version at least 2.13.55"
17392
17393         local cl_user
17394
17395         changelog_register || error "changelog_register failed"
17396         cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17397
17398         changelog_users $SINGLEMDS | grep -q $cl_user ||
17399                 error "User '$cl_user' not found in changelog_users"
17400
17401         # Clear some types so that MTIME changelogs are generated
17402         changelog_chmask "-CREAT"
17403         changelog_chmask "-CLOSE"
17404
17405         test_mkdir $DIR/$tdir || error "failed to mkdir $DIR/$tdir"
17406
17407         # Test CL_MTIME during setattr
17408         touch $DIR/$tdir/$tfile
17409         compare_mtime_changelog $DIR/$tdir/$tfile
17410
17411         # Test CL_MTIME during close
17412         $MULTIOP $DIR/$tdir/${tfile}_2 O_2w4096c || error "multiop failed"
17413         compare_mtime_changelog $DIR/$tdir/${tfile}_2
17414 }
17415 run_test 160l "Verify that MTIME changelog records contain the parent FID"
17416
17417 test_160m() {
17418         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17419         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17420                 skip "Need MDS version at least 2.14.51"
17421         local cl_users
17422         local cl_user1
17423         local cl_user2
17424         local pid1
17425
17426         # Create a user
17427         changelog_register || error "first changelog_register failed"
17428         changelog_register || error "second changelog_register failed"
17429
17430         cl_users=(${CL_USERS[mds1]})
17431         cl_user1="${cl_users[0]}"
17432         cl_user2="${cl_users[1]}"
17433         # generate some changelog records to accumulate on MDT0
17434         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17435         createmany -m $DIR/$tdir/$tfile 50 ||
17436                 error "create $DIR/$tdir/$tfile failed"
17437         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17438         rm -f $DIR/$tdir
17439
17440         # check changelogs have been generated
17441         local nbcl=$(changelog_dump | wc -l)
17442         [[ $nbcl -eq 0 ]] && error "no changelogs found"
17443
17444 #define OBD_FAIL_MDS_CHANGELOG_RACE      0x15f
17445         do_facet mds1 $LCTL set_param fail_loc=0x8000015f fail_val=0
17446
17447         __changelog_clear mds1 $cl_user1 +10
17448         __changelog_clear mds1 $cl_user2 0 &
17449         pid1=$!
17450         sleep 2
17451         __changelog_clear mds1 $cl_user1 0 ||
17452                 error "fail to cancel record for $cl_user1"
17453         wait $pid1
17454         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17455 }
17456 run_test 160m "Changelog clear race"
17457
17458 test_160n() {
17459         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17460         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17461                 skip "Need MDS version at least 2.14.51"
17462         local cl_users
17463         local cl_user1
17464         local cl_user2
17465         local pid1
17466         local first_rec
17467         local last_rec=0
17468
17469         # Create a user
17470         changelog_register || error "first changelog_register failed"
17471
17472         cl_users=(${CL_USERS[mds1]})
17473         cl_user1="${cl_users[0]}"
17474
17475         # generate some changelog records to accumulate on MDT0
17476         test_mkdir -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17477         first_rec=$(changelog_users $SINGLEMDS |
17478                         awk '/^current.index:/ { print $NF }')
17479         while (( last_rec < (( first_rec + 65000)) )); do
17480                 createmany -m $DIR/$tdir/$tfile 10000 ||
17481                         error "create $DIR/$tdir/$tfile failed"
17482
17483                 for i in $(seq 0 10000); do
17484                         mrename $DIR/$tdir/$tfile$i $DIR/$tdir/$tfile-new$i \
17485                                 > /dev/null
17486                 done
17487
17488                 unlinkmany $DIR/$tdir/$tfile-new 10000 ||
17489                         error "unlinkmany failed unlink"
17490                 last_rec=$(changelog_users $SINGLEMDS |
17491                         awk '/^current.index:/ { print $NF }')
17492                 echo last record $last_rec
17493                 (( last_rec == 0 )) && error "no changelog found"
17494         done
17495
17496 #define OBD_FAIL_MDS_CHANGELOG_DEL       0x16c
17497         do_facet mds1 $LCTL set_param fail_loc=0x8000016c fail_val=0
17498
17499         __changelog_clear mds1 $cl_user1 0 &
17500         pid1=$!
17501         sleep 2
17502         __changelog_clear mds1 $cl_user1 0 ||
17503                 error "fail to cancel record for $cl_user1"
17504         wait $pid1
17505         [[ $? -eq 0 ]] || error "fail to cancel record for $cl_user2"
17506 }
17507 run_test 160n "Changelog destroy race"
17508
17509 test_160o() {
17510         local mdt="$(facet_svc $SINGLEMDS)"
17511
17512         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17513         remote_mds_nodsh && skip "remote MDS with nodsh"
17514         [ $MDS1_VERSION -ge $(version_code 2.14.52) ] ||
17515                 skip "Need MDS version at least 2.14.52"
17516
17517         changelog_register --user test_160o -m unlnk+close+open ||
17518                 error "changelog_register failed"
17519
17520         do_facet $SINGLEMDS $LCTL --device $mdt \
17521                                 changelog_register -u "Tt3_-#" &&
17522                 error "bad symbols in name should fail"
17523
17524         do_facet $SINGLEMDS $LCTL --device $mdt \
17525                                 changelog_register -u test_160o &&
17526                 error "the same name registration should fail"
17527
17528         do_facet $SINGLEMDS $LCTL --device $mdt \
17529                         changelog_register -u test_160toolongname &&
17530                 error "too long name registration should fail"
17531
17532         changelog_chmask "MARK+HSM"
17533         lctl get_param mdd.*.changelog*mask
17534         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
17535         changelog_users $SINGLEMDS | grep -q $cl_user ||
17536                 error "User $cl_user not found in changelog_users"
17537         #verify username
17538         echo $cl_user | grep -q test_160o ||
17539                 error "User $cl_user has no specific name 'test160o'"
17540
17541         # change something
17542         changelog_clear 0 || error "changelog_clear failed"
17543         # generate some changelog records to accumulate on MDT0
17544         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17545         touch $DIR/$tdir/$tfile                 # open 1
17546
17547         OPENS=$(changelog_dump | grep -c "OPEN")
17548         [[ $OPENS -eq 1 ]] || error "OPEN changelog mask count $OPENS != 1"
17549
17550         # must be no MKDIR it wasn't set as user mask
17551         MKDIR=$(changelog_dump | grep -c "MKDIR")
17552         [[ $MKDIR -eq 0 ]] || error "MKDIR changelog mask found $MKDIR > 0"
17553
17554         oldmask=$(do_facet $SINGLEMDS $LCTL get_param \
17555                                 mdd.$mdt.changelog_current_mask -n)
17556         # register maskless user
17557         changelog_register || error "changelog_register failed"
17558         # effective mask should be not changed because it is not minimal
17559         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17560                                 mdd.$mdt.changelog_current_mask -n)
17561         [[ $mask == $oldmask ]] || error "mask was changed: $mask vs $oldmask"
17562         # set server mask to minimal value
17563         changelog_chmask "MARK"
17564         # check effective mask again, should be treated as DEFMASK now
17565         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17566                                 mdd.$mdt.changelog_current_mask -n)
17567         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17568
17569         if (( $MDS1_VERSION >= $(version_code 2.15.52) )) ; then
17570                 # set server mask back to some value
17571                 changelog_chmask "CLOSE,UNLNK"
17572                 # check effective mask again, should not remain as DEFMASK
17573                 mask=$(do_facet $SINGLEMDS $LCTL get_param \
17574                                 mdd.$mdt.changelog_current_mask -n)
17575                 [[ $mask != *"HLINK"* ]] || error "mask is still DEFMASK"
17576         fi
17577
17578         do_facet $SINGLEMDS $LCTL --device $mdt \
17579                                 changelog_deregister -u test_160o ||
17580                 error "cannot deregister by name"
17581 }
17582 run_test 160o "changelog user name and mask"
17583
17584 test_160p() {
17585         remote_mds_nodsh && skip "remote MDS with nodsh" && return
17586         [[ $MDS1_VERSION -ge $(version_code 2.14.51) ]] ||
17587                 skip "Need MDS version at least 2.14.51"
17588         [[ "$mds1_FSTYPE" == "ldiskfs" ]] || skip "ldiskfs only test"
17589         local cl_users
17590         local cl_user1
17591         local entry_count
17592
17593         # Create a user
17594         changelog_register || error "first changelog_register failed"
17595
17596         cl_users=(${CL_USERS[mds1]})
17597         cl_user1="${cl_users[0]}"
17598
17599         test_mkdir -p -i0 -c1 $DIR/$tdir || error "test_mkdir $tdir failed"
17600         createmany -m $DIR/$tdir/$tfile 50 ||
17601                 error "create $DIR/$tdir/$tfile failed"
17602         unlinkmany $DIR/$tdir/$tfile 50 || error "unlinkmany failed"
17603         rm -rf $DIR/$tdir
17604
17605         # check changelogs have been generated
17606         entry_count=$(changelog_dump | wc -l)
17607         ((entry_count != 0)) || error "no changelog entries found"
17608
17609         # remove changelog_users and check that orphan entries are removed
17610         stop mds1
17611         local dev=$(mdsdevname 1)
17612         do_facet mds1 "$DEBUGFS -w -R 'rm changelog_users' $dev"
17613         start mds1 $dev $MDS_MOUNT_OPTS || error "cannot start mds1"
17614         entry_count=$(changelog_dump | wc -l)
17615         ((entry_count == 0)) ||
17616                 error "found $entry_count changelog entries, expected none"
17617 }
17618 run_test 160p "Changelog orphan cleanup with no users"
17619
17620 test_160q() {
17621         local mdt="$(facet_svc $SINGLEMDS)"
17622         local clu
17623
17624         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
17625         remote_mds_nodsh && skip "remote MDS with nodsh"
17626         [ $MDS1_VERSION -ge $(version_code 2.14.54) ] ||
17627                 skip "Need MDS version at least 2.14.54"
17628
17629         # set server mask to minimal value like server init does
17630         changelog_chmask "MARK"
17631         clu=$(do_facet $SINGLEMDS $LCTL --device $mdt changelog_register -n) ||
17632                 error "changelog_register failed"
17633         # check effective mask again, should be treated as DEFMASK now
17634         mask=$(do_facet $SINGLEMDS $LCTL get_param \
17635                                 mdd.$mdt.changelog_current_mask -n)
17636         do_facet $SINGLEMDS $LCTL --device $mdt changelog_deregister $clu ||
17637                 error "changelog_deregister failed"
17638         [[ $mask == *"HLINK"* ]] || error "mask is not DEFMASK as expected"
17639 }
17640 run_test 160q "changelog effective mask is DEFMASK if not set"
17641
17642 test_160s() {
17643         remote_mds_nodsh && skip "remote MDS with nodsh"
17644         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
17645                 skip "Need MDS version at least 2.14.55"
17646
17647         local mdts=$(comma_list $(mdts_nodes))
17648
17649         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
17650         do_nodes $mdts $LCTL set_param fail_loc=0x1314 \
17651                                        fail_val=$((24 * 3600 * 10))
17652
17653         # Create a user which is 10 days old
17654         changelog_register || error "first changelog_register failed"
17655         local cl_users
17656         declare -A cl_user1
17657         local i
17658
17659         # generate some changelog records to accumulate on each MDT
17660         # use all_char because created files should be evenly distributed
17661         test_mkdir -c $MDSCOUNT -H all_char $DIR/$tdir ||
17662                 error "test_mkdir $tdir failed"
17663         for ((i = 0; i < MDSCOUNT; i++)); do
17664                 $LFS mkdir -i $i $DIR/$tdir/d$i.1 $DIR/$tdir/d$i.2 ||
17665                         error "create $DIR/$tdir/d$i.1 failed"
17666         done
17667
17668         # check changelogs have been generated
17669         local nbcl=$(changelog_dump | wc -l)
17670         (( nbcl > 0 )) || error "no changelogs found"
17671
17672         # reduce the max_idle_indexes value to make sure we exceed it
17673         for param in "changelog_max_idle_indexes=2097446912" \
17674                      "changelog_max_idle_time=2592000" \
17675                      "changelog_gc=1" \
17676                      "changelog_min_gc_interval=2"; do
17677                 local MDT0=$(facet_svc $SINGLEMDS)
17678                 local var="${param%=*}"
17679                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17680
17681                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
17682                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
17683                         error "unable to set mdd.*.$param"
17684         done
17685
17686         local start=$SECONDS
17687         for i in $(seq $MDSCOUNT); do
17688                 cl_users=(${CL_USERS[mds$i]})
17689                 cl_user1[mds$i]="${cl_users[0]}"
17690
17691                 [[ -n "${cl_user1[mds$i]}" ]] ||
17692                         error "mds$i: no user registered"
17693         done
17694
17695         #define OBD_FAIL_MDS_CHANGELOG_IDX_PUMP   0x16d
17696         do_nodes $mdts $LCTL set_param fail_loc=0x16d fail_val=500000000
17697
17698         # ensure we are past the previous changelog_min_gc_interval set above
17699         local sleep2=$((start + 2 - SECONDS))
17700         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17701
17702         # Generate one more changelog to trigger GC
17703         for ((i = 0; i < MDSCOUNT; i++)); do
17704                 $LFS mkdir -i $i $DIR/$tdir/d$i.3 $DIR/$tdir/d$i.4 ||
17705                         error "create $DIR/$tdir/d$i.3 failed"
17706         done
17707
17708         # ensure gc thread is done
17709         for node in $(mdts_nodes); do
17710                 wait_update $node "pgrep chlg_gc_thread" "" 20 ||
17711                         error "$node: GC-thread not done"
17712         done
17713
17714         do_nodes $mdts $LCTL set_param fail_loc=0
17715
17716         for (( i = 1; i <= MDSCOUNT; i++ )); do
17717                 # check cl_user1 is purged
17718                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" &&
17719                         error "mds$i: User ${cl_user1[mds$i]} is registered"
17720         done
17721         return 0
17722 }
17723 run_test 160s "changelog garbage collect on idle records * time"
17724
17725 test_160t() {
17726         remote_mds_nodsh && skip "remote MDS with nodsh"
17727         (( $MDS1_VERSION >= $(version_code 2.15.50) )) ||
17728                 skip "Need MDS version at least 2.15.50"
17729
17730         local MDT0=$(facet_svc $SINGLEMDS)
17731         local cl_users
17732         local cl_user1
17733         local cl_user2
17734         local start
17735
17736         changelog_register --user user1 -m all ||
17737                 error "user1 failed to register"
17738
17739         mkdir_on_mdt0 $DIR/$tdir
17740         # create default overstripe to maximize changelog size
17741         $LFS setstripe  -C 8 $DIR/$tdir || error "setstripe failed"
17742         createmany -o $DIR/$tdir/u1_ 2000 || error "createmany for user1 failed"
17743         llog_size1=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17744
17745         # user2 consumes less records so less space
17746         changelog_register --user user2 || error "user2 failed to register"
17747         createmany -o $DIR/$tdir/u2_ 500 || error "createmany for user2 failed"
17748         llog_size2=$(do_facet mds1 $LCTL get_param -n mdd.$MDT0.changelog_size)
17749
17750         # check changelogs have been generated
17751         local nbcl=$(changelog_dump | wc -l)
17752         (( nbcl > 0 )) || error "no changelogs found"
17753
17754         # reduce the changelog_min_gc_interval to force check
17755         for param in "changelog_gc=1" "changelog_min_gc_interval=2"; do
17756                 local var="${param%=*}"
17757                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
17758
17759                 stack_trap "do_facet mds1 $LCTL set_param mdd.$MDT0.$var=$old"
17760                 do_facet mds1 $LCTL set_param mdd.$MDT0.$param ||
17761                         error "unable to set mdd.*.$param"
17762         done
17763
17764         start=$SECONDS
17765         cl_users=(${CL_USERS[mds1]})
17766         cl_user1="${cl_users[0]}"
17767         cl_user2="${cl_users[1]}"
17768
17769         [[ -n $cl_user1 ]] ||
17770                 error "mds1: user #1 isn't registered"
17771         [[ -n $cl_user2 ]] ||
17772                 error "mds1: user #2 isn't registered"
17773
17774         # ensure we are past the previous changelog_min_gc_interval set above
17775         local sleep2=$((start + 2 - SECONDS))
17776         (( sleep2 > 0 )) && echo "sleep $sleep2 for interval" && sleep $sleep2
17777
17778         #define OBD_FAIL_MDS_CHANGELOG_ENOSPC 0x018c
17779         do_facet mds1 $LCTL set_param fail_loc=0x018c \
17780                         fail_val=$(((llog_size1 + llog_size2) / 2))
17781
17782         # Generate more changelog to trigger GC
17783         createmany -o $DIR/$tdir/u3_ 4 ||
17784                 error "create failed for more files"
17785
17786         # ensure gc thread is done
17787         wait_update_facet mds1 "pgrep chlg_gc_thread" "" 20 ||
17788                 error "mds1: GC-thread not done"
17789
17790         do_facet mds1 $LCTL set_param fail_loc=0
17791
17792         # check cl_user1 is purged
17793         changelog_users mds1 | grep -q "$cl_user1" &&
17794                 error "User $cl_user1 is registered"
17795         # check cl_user2 is not purged
17796         changelog_users mds1 | grep -q "$cl_user2" ||
17797                 error "User $cl_user2 is not registered"
17798 }
17799 run_test 160t "changelog garbage collect on lack of space"
17800
17801 test_161a() {
17802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17803
17804         test_mkdir -c1 $DIR/$tdir
17805         cp /etc/hosts $DIR/$tdir/$tfile
17806         test_mkdir -c1 $DIR/$tdir/foo1
17807         test_mkdir -c1 $DIR/$tdir/foo2
17808         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
17809         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
17810         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
17811         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
17812         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
17813         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17814                 $LFS fid2path $DIR $FID
17815                 error "bad link ea"
17816         fi
17817         # middle
17818         rm $DIR/$tdir/foo2/zachary
17819         # last
17820         rm $DIR/$tdir/foo2/thor
17821         # first
17822         rm $DIR/$tdir/$tfile
17823         # rename
17824         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
17825         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
17826                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
17827         rm $DIR/$tdir/foo2/maggie
17828
17829         # overflow the EA
17830         local longname=$tfile.avg_len_is_thirty_two_
17831         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
17832                 error_noexit 'failed to unlink many hardlinks'" EXIT
17833         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
17834                 error "failed to hardlink many files"
17835         links=$($LFS fid2path $DIR $FID | wc -l)
17836         echo -n "${links}/1000 links in link EA"
17837         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
17838 }
17839 run_test 161a "link ea sanity"
17840
17841 test_161b() {
17842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17843         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
17844
17845         local MDTIDX=1
17846         local remote_dir=$DIR/$tdir/remote_dir
17847
17848         mkdir -p $DIR/$tdir
17849         $LFS mkdir -i $MDTIDX $remote_dir ||
17850                 error "create remote directory failed"
17851
17852         cp /etc/hosts $remote_dir/$tfile
17853         mkdir -p $remote_dir/foo1
17854         mkdir -p $remote_dir/foo2
17855         ln $remote_dir/$tfile $remote_dir/foo1/sofia
17856         ln $remote_dir/$tfile $remote_dir/foo2/zachary
17857         ln $remote_dir/$tfile $remote_dir/foo1/luna
17858         ln $remote_dir/$tfile $remote_dir/foo2/thor
17859
17860         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
17861                      tr -d ']')
17862         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
17863                 $LFS fid2path $DIR $FID
17864                 error "bad link ea"
17865         fi
17866         # middle
17867         rm $remote_dir/foo2/zachary
17868         # last
17869         rm $remote_dir/foo2/thor
17870         # first
17871         rm $remote_dir/$tfile
17872         # rename
17873         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
17874         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
17875         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
17876                 $LFS fid2path $DIR $FID
17877                 error "bad link rename"
17878         fi
17879         rm $remote_dir/foo2/maggie
17880
17881         # overflow the EA
17882         local longname=filename_avg_len_is_thirty_two_
17883         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
17884                 error "failed to hardlink many files"
17885         links=$($LFS fid2path $DIR $FID | wc -l)
17886         echo -n "${links}/1000 links in link EA"
17887         [[ ${links} -gt 60 ]] ||
17888                 error "expected at least 60 links in link EA"
17889         unlinkmany $remote_dir/foo2/$longname 1000 ||
17890         error "failed to unlink many hardlinks"
17891 }
17892 run_test 161b "link ea sanity under remote directory"
17893
17894 test_161c() {
17895         remote_mds_nodsh && skip "remote MDS with nodsh"
17896         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17897         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
17898                 skip "Need MDS version at least 2.1.5"
17899
17900         # define CLF_RENAME_LAST 0x0001
17901         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
17902         changelog_register || error "changelog_register failed"
17903
17904         rm -rf $DIR/$tdir
17905         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
17906         touch $DIR/$tdir/foo_161c
17907         touch $DIR/$tdir/bar_161c
17908         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17909         changelog_dump | grep RENME | tail -n 5
17910         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17911         changelog_clear 0 || error "changelog_clear failed"
17912         if [ x$flags != "x0x1" ]; then
17913                 error "flag $flags is not 0x1"
17914         fi
17915
17916         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
17917         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
17918         touch $DIR/$tdir/foo_161c
17919         touch $DIR/$tdir/bar_161c
17920         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17921         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
17922         changelog_dump | grep RENME | tail -n 5
17923         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
17924         changelog_clear 0 || error "changelog_clear failed"
17925         if [ x$flags != "x0x0" ]; then
17926                 error "flag $flags is not 0x0"
17927         fi
17928         echo "rename overwrite a target having nlink > 1," \
17929                 "changelog record has flags of $flags"
17930
17931         # rename doesn't overwrite a target (changelog flag 0x0)
17932         touch $DIR/$tdir/foo_161c
17933         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
17934         changelog_dump | grep RENME | tail -n 5
17935         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
17936         changelog_clear 0 || error "changelog_clear failed"
17937         if [ x$flags != "x0x0" ]; then
17938                 error "flag $flags is not 0x0"
17939         fi
17940         echo "rename doesn't overwrite a target," \
17941                 "changelog record has flags of $flags"
17942
17943         # define CLF_UNLINK_LAST 0x0001
17944         # unlink a file having nlink = 1 (changelog flag 0x1)
17945         rm -f $DIR/$tdir/foo2_161c
17946         changelog_dump | grep UNLNK | tail -n 5
17947         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17948         changelog_clear 0 || error "changelog_clear failed"
17949         if [ x$flags != "x0x1" ]; then
17950                 error "flag $flags is not 0x1"
17951         fi
17952         echo "unlink a file having nlink = 1," \
17953                 "changelog record has flags of $flags"
17954
17955         # unlink a file having nlink > 1 (changelog flag 0x0)
17956         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
17957         rm -f $DIR/$tdir/foobar_161c
17958         changelog_dump | grep UNLNK | tail -n 5
17959         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
17960         changelog_clear 0 || error "changelog_clear failed"
17961         if [ x$flags != "x0x0" ]; then
17962                 error "flag $flags is not 0x0"
17963         fi
17964         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
17965 }
17966 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
17967
17968 test_161d() {
17969         remote_mds_nodsh && skip "remote MDS with nodsh"
17970         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
17971
17972         local pid
17973         local fid
17974
17975         changelog_register || error "changelog_register failed"
17976
17977         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
17978         # interfer with $MOUNT/.lustre/fid/ access
17979         mkdir $DIR/$tdir
17980         [[ $? -eq 0 ]] || error "mkdir failed"
17981
17982         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
17983         $LCTL set_param fail_loc=0x8000140c
17984         # 5s pause
17985         $LCTL set_param fail_val=5
17986
17987         # create file
17988         echo foofoo > $DIR/$tdir/$tfile &
17989         pid=$!
17990
17991         # wait for create to be delayed
17992         sleep 2
17993
17994         ps -p $pid
17995         [[ $? -eq 0 ]] || error "create should be blocked"
17996
17997         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
17998         stack_trap "rm -f $tempfile"
17999         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
18000         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
18001         # some delay may occur during ChangeLog publishing and file read just
18002         # above, that could allow file write to happen finally
18003         [[ -s $tempfile ]] && echo "file should be empty"
18004
18005         $LCTL set_param fail_loc=0
18006
18007         wait $pid
18008         [[ $? -eq 0 ]] || error "create failed"
18009 }
18010 run_test 161d "create with concurrent .lustre/fid access"
18011
18012 check_path() {
18013         local expected="$1"
18014         shift
18015         local fid="$2"
18016
18017         local path
18018         path=$($LFS fid2path "$@")
18019         local rc=$?
18020
18021         if [ $rc -ne 0 ]; then
18022                 error "path looked up of '$expected' failed: rc=$rc"
18023         elif [ "$path" != "$expected" ]; then
18024                 error "path looked up '$path' instead of '$expected'"
18025         else
18026                 echo "FID '$fid' resolves to path '$path' as expected"
18027         fi
18028 }
18029
18030 test_162a() { # was test_162
18031         test_mkdir -p -c1 $DIR/$tdir/d2
18032         touch $DIR/$tdir/d2/$tfile
18033         touch $DIR/$tdir/d2/x1
18034         touch $DIR/$tdir/d2/x2
18035         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
18036         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
18037         # regular file
18038         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
18039         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
18040
18041         # softlink
18042         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
18043         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
18044         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
18045
18046         # softlink to wrong file
18047         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
18048         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
18049         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
18050
18051         # hardlink
18052         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
18053         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
18054         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
18055         # fid2path dir/fsname should both work
18056         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
18057         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
18058
18059         # hardlink count: check that there are 2 links
18060         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
18061         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
18062
18063         # hardlink indexing: remove the first link
18064         rm $DIR/$tdir/d2/p/q/r/hlink
18065         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
18066 }
18067 run_test 162a "path lookup sanity"
18068
18069 test_162b() {
18070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18071         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18072
18073         mkdir $DIR/$tdir
18074         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18075                                 error "create striped dir failed"
18076
18077         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18078                                         tail -n 1 | awk '{print $2}')
18079         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
18080
18081         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
18082         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
18083
18084         # regular file
18085         for ((i=0;i<5;i++)); do
18086                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
18087                         error "get fid for f$i failed"
18088                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
18089
18090                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
18091                         error "get fid for d$i failed"
18092                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
18093         done
18094
18095         return 0
18096 }
18097 run_test 162b "striped directory path lookup sanity"
18098
18099 # LU-4239: Verify fid2path works with paths 100 or more directories deep
18100 test_162c() {
18101         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
18102                 skip "Need MDS version at least 2.7.51"
18103
18104         local lpath=$tdir.local
18105         local rpath=$tdir.remote
18106
18107         test_mkdir $DIR/$lpath
18108         test_mkdir $DIR/$rpath
18109
18110         for ((i = 0; i <= 101; i++)); do
18111                 lpath="$lpath/$i"
18112                 mkdir $DIR/$lpath
18113                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
18114                         error "get fid for local directory $DIR/$lpath failed"
18115                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
18116
18117                 rpath="$rpath/$i"
18118                 test_mkdir $DIR/$rpath
18119                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
18120                         error "get fid for remote directory $DIR/$rpath failed"
18121                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
18122         done
18123
18124         return 0
18125 }
18126 run_test 162c "fid2path works with paths 100 or more directories deep"
18127
18128 oalr_event_count() {
18129         local event="${1}"
18130         local trace="${2}"
18131
18132         awk -v name="${FSNAME}-OST0000" \
18133             -v event="${event}" \
18134             '$1 == "TRACE" && $2 == event && $3 == name' \
18135             "${trace}" |
18136         wc -l
18137 }
18138
18139 oalr_expect_event_count() {
18140         local event="${1}"
18141         local trace="${2}"
18142         local expect="${3}"
18143         local count
18144
18145         count=$(oalr_event_count "${event}" "${trace}")
18146         if ((count == expect)); then
18147                 return 0
18148         fi
18149
18150         error_noexit "${event} event count was '${count}', expected ${expect}"
18151         cat "${trace}" >&2
18152         exit 1
18153 }
18154
18155 cleanup_165() {
18156         do_facet ost1 killall --quiet -KILL ofd_access_log_reader || true
18157         stop ost1
18158         start ost1 "$(ostdevname 1)" $OST_MOUNT_OPTS
18159 }
18160
18161 setup_165() {
18162         sync # Flush previous IOs so we can count log entries.
18163         do_facet ost1 $LCTL set_param "obdfilter.${FSNAME}-OST0000.access_log_size=4096"
18164         stack_trap cleanup_165 EXIT
18165 }
18166
18167 test_165a() {
18168         local trace="/tmp/${tfile}.trace"
18169         local rc
18170         local count
18171
18172         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18173                 skip "OFD access log unsupported"
18174
18175         setup_165
18176         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18177         sleep 5
18178
18179         do_facet ost1 ofd_access_log_reader --list
18180         stop ost1
18181
18182         do_facet ost1 killall -TERM ofd_access_log_reader
18183         wait
18184         rc=$?
18185
18186         if ((rc != 0)); then
18187                 error "ofd_access_log_reader exited with rc = '${rc}'"
18188         fi
18189
18190         # Parse trace file for discovery events:
18191         oalr_expect_event_count alr_log_add "${trace}" 1
18192         oalr_expect_event_count alr_log_eof "${trace}" 1
18193         oalr_expect_event_count alr_log_free "${trace}" 1
18194 }
18195 run_test 165a "ofd access log discovery"
18196
18197 test_165b() {
18198         local trace="/tmp/${tfile}.trace"
18199         local file="${DIR}/${tfile}"
18200         local pfid1
18201         local pfid2
18202         local -a entry
18203         local rc
18204         local count
18205         local size
18206         local flags
18207
18208         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18209                 skip "OFD access log unsupported"
18210
18211         setup_165
18212         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18213         sleep 5
18214
18215         do_facet ost1 ofd_access_log_reader --list
18216
18217         lfs setstripe -c 1 -i 0 "${file}"
18218         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18219                 error "cannot create '${file}'"
18220
18221         sleep 5
18222         do_facet ost1 killall -TERM ofd_access_log_reader
18223         wait
18224         rc=$?
18225
18226         if ((rc != 0)); then
18227                 error "ofd_access_log_reader exited with rc = '${rc}'"
18228         fi
18229
18230         oalr_expect_event_count alr_log_entry "${trace}" 1
18231
18232         pfid1=$($LFS path2fid "${file}")
18233
18234         # 1     2             3   4    5     6   7    8    9     10
18235         # TRACE alr_log_entry OST PFID BEGIN END TIME SIZE COUNT FLAGS
18236         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18237
18238         echo "entry = '${entry[*]}'" >&2
18239
18240         pfid2=${entry[4]}
18241         if [[ "${pfid1}" != "${pfid2}" ]]; then
18242                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18243         fi
18244
18245         size=${entry[8]}
18246         if ((size != 1048576)); then
18247                 error "entry '${entry[*]}' has invalid io size '${size}', expected 1048576"
18248         fi
18249
18250         flags=${entry[10]}
18251         if [[ "${flags}" != "w" ]]; then
18252                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'w'"
18253         fi
18254
18255         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18256         sleep 5
18257
18258         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r524288c ||
18259                 error "cannot read '${file}'"
18260         sleep 5
18261
18262         do_facet ost1 killall -TERM ofd_access_log_reader
18263         wait
18264         rc=$?
18265
18266         if ((rc != 0)); then
18267                 error "ofd_access_log_reader exited with rc = '${rc}'"
18268         fi
18269
18270         oalr_expect_event_count alr_log_entry "${trace}" 1
18271
18272         entry=( - $(awk -v pfid="${pfid}" '$1 == "TRACE" && $2 == "alr_log_entry"' "${trace}" ) )
18273         echo "entry = '${entry[*]}'" >&2
18274
18275         pfid2=${entry[4]}
18276         if [[ "${pfid1}" != "${pfid2}" ]]; then
18277                 error "entry '${entry[*]}' has invalid PFID '${pfid2}', expected ${pfid1}"
18278         fi
18279
18280         size=${entry[8]}
18281         if ((size != 524288)); then
18282                 error "entry '${entry[*]}' has invalid io size '${size}', 524288"
18283         fi
18284
18285         flags=${entry[10]}
18286         if [[ "${flags}" != "r" ]]; then
18287                 error "entry '${entry[*]}' has invalid io flags '${flags}', expected 'r'"
18288         fi
18289 }
18290 run_test 165b "ofd access log entries are produced and consumed"
18291
18292 test_165c() {
18293         local trace="/tmp/${tfile}.trace"
18294         local file="${DIR}/${tdir}/${tfile}"
18295
18296         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18297                 skip "OFD access log unsupported"
18298
18299         test_mkdir "${DIR}/${tdir}"
18300
18301         setup_165
18302         do_facet ost1 ofd_access_log_reader --debug=- --trace=- > "${trace}" &
18303         sleep 5
18304
18305         lfs setstripe -c 1 -i 0 "${DIR}/${tdir}"
18306
18307         # 4096 / 64 = 64. Create twice as many entries.
18308         for ((i = 0; i < 128; i++)); do
18309                 $MULTIOP "${file}-${i}" oO_CREAT:O_WRONLY:w512c ||
18310                         error "cannot create file"
18311         done
18312
18313         sync
18314
18315         do_facet ost1 killall -TERM ofd_access_log_reader
18316         wait
18317         rc=$?
18318         if ((rc != 0)); then
18319                 error "ofd_access_log_reader exited with rc = '${rc}'"
18320         fi
18321
18322         unlinkmany  "${file}-%d" 128
18323 }
18324 run_test 165c "full ofd access logs do not block IOs"
18325
18326 oal_get_read_count() {
18327         local stats="$1"
18328
18329         # STATS lustre-OST0001 alr_read_count 1
18330
18331         do_facet ost1 cat "${stats}" |
18332         awk '$1 == "STATS" && $3 == "alr_read_count" { count = $4; }
18333              END { print count; }'
18334 }
18335
18336 oal_expect_read_count() {
18337         local stats="$1"
18338         local count
18339         local expect="$2"
18340
18341         # Ask ofd_access_log_reader to write stats.
18342         do_facet ost1 killall -USR1 ofd_access_log_reader
18343
18344         # Allow some time for things to happen.
18345         sleep 1
18346
18347         count=$(oal_get_read_count "${stats}")
18348         if ((count == expect)); then
18349                 return 0
18350         fi
18351
18352         error_noexit "bad read count, got ${count}, expected ${expect}"
18353         do_facet ost1 cat "${stats}" >&2
18354         exit 1
18355 }
18356
18357 test_165d() {
18358         local stats="/tmp/${tfile}.stats"
18359         local file="${DIR}/${tdir}/${tfile}"
18360         local param="obdfilter.${FSNAME}-OST0000.access_log_mask"
18361
18362         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18363                 skip "OFD access log unsupported"
18364
18365         test_mkdir "${DIR}/${tdir}"
18366
18367         setup_165
18368         do_facet ost1 ofd_access_log_reader --stats="${stats}" &
18369         sleep 5
18370
18371         lfs setstripe -c 1 -i 0 "${file}"
18372
18373         do_facet ost1 lctl set_param "${param}=rw"
18374         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18375                 error "cannot create '${file}'"
18376         oal_expect_read_count "${stats}" 1
18377
18378         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18379                 error "cannot read '${file}'"
18380         oal_expect_read_count "${stats}" 2
18381
18382         do_facet ost1 lctl set_param "${param}=r"
18383         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18384                 error "cannot create '${file}'"
18385         oal_expect_read_count "${stats}" 2
18386
18387         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18388                 error "cannot read '${file}'"
18389         oal_expect_read_count "${stats}" 3
18390
18391         do_facet ost1 lctl set_param "${param}=w"
18392         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18393                 error "cannot create '${file}'"
18394         oal_expect_read_count "${stats}" 4
18395
18396         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18397                 error "cannot read '${file}'"
18398         oal_expect_read_count "${stats}" 4
18399
18400         do_facet ost1 lctl set_param "${param}=0"
18401         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_WRONLY:w1048576c ||
18402                 error "cannot create '${file}'"
18403         oal_expect_read_count "${stats}" 4
18404
18405         $MULTIOP "${file}" oO_CREAT:O_DIRECT:O_RDONLY:r1048576c ||
18406                 error "cannot read '${file}'"
18407         oal_expect_read_count "${stats}" 4
18408
18409         do_facet ost1 killall -TERM ofd_access_log_reader
18410         wait
18411         rc=$?
18412         if ((rc != 0)); then
18413                 error "ofd_access_log_reader exited with rc = '${rc}'"
18414         fi
18415 }
18416 run_test 165d "ofd_access_log mask works"
18417
18418 test_165e() {
18419         local stats="/tmp/${tfile}.stats"
18420         local file0="${DIR}/${tdir}-0/${tfile}"
18421         local file1="${DIR}/${tdir}-1/${tfile}"
18422
18423         (( $OST1_VERSION >= $(version_code 2.13.54) )) ||
18424                 skip "OFD access log unsupported"
18425
18426         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
18427
18428         test_mkdir -c 1 -i 0 "${DIR}/${tdir}-0"
18429         test_mkdir -c 1 -i 1 "${DIR}/${tdir}-1"
18430
18431         lfs setstripe -c 1 -i 0 "${file0}"
18432         lfs setstripe -c 1 -i 0 "${file1}"
18433
18434         setup_165
18435         do_facet ost1 ofd_access_log_reader -I 1 --stats="${stats}" &
18436         sleep 5
18437
18438         $MULTIOP "${file0}" oO_CREAT:O_WRONLY:w512c ||
18439                 error "cannot create '${file0}'"
18440         sync
18441         oal_expect_read_count "${stats}" 0
18442
18443         $MULTIOP "${file1}" oO_CREAT:O_WRONLY:w512c ||
18444                 error "cannot create '${file1}'"
18445         sync
18446         oal_expect_read_count "${stats}" 1
18447
18448         do_facet ost1 killall -TERM ofd_access_log_reader
18449         wait
18450         rc=$?
18451         if ((rc != 0)); then
18452                 error "ofd_access_log_reader exited with rc = '${rc}'"
18453         fi
18454 }
18455 run_test 165e "ofd_access_log MDT index filter works"
18456
18457 test_165f() {
18458         local trace="/tmp/${tfile}.trace"
18459         local rc
18460         local count
18461
18462         setup_165
18463         do_facet ost1 timeout 60 ofd_access_log_reader \
18464                 --exit-on-close --debug=- --trace=- > "${trace}" &
18465         sleep 5
18466         stop ost1
18467
18468         wait
18469         rc=$?
18470
18471         if ((rc != 0)); then
18472                 error_noexit "ofd_access_log_reader exited with rc = '${rc}'"
18473                 cat "${trace}"
18474                 exit 1
18475         fi
18476 }
18477 run_test 165f "ofd_access_log_reader --exit-on-close works"
18478
18479 test_169() {
18480         # do directio so as not to populate the page cache
18481         log "creating a 10 Mb file"
18482         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c ||
18483                 error "multiop failed while creating a file"
18484         log "starting reads"
18485         dd if=$DIR/$tfile of=/dev/null bs=4096 &
18486         log "truncating the file"
18487         $MULTIOP $DIR/$tfile oO_TRUNC:c ||
18488                 error "multiop failed while truncating the file"
18489         log "killing dd"
18490         kill %+ || true # reads might have finished
18491         echo "wait until dd is finished"
18492         wait
18493         log "removing the temporary file"
18494         rm -rf $DIR/$tfile || error "tmp file removal failed"
18495 }
18496 run_test 169 "parallel read and truncate should not deadlock"
18497
18498 test_170() {
18499         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18500
18501         $LCTL clear     # bug 18514
18502         $LCTL debug_daemon start $TMP/${tfile}_log_good
18503         touch $DIR/$tfile
18504         $LCTL debug_daemon stop
18505         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
18506                 error "sed failed to read log_good"
18507
18508         $LCTL debug_daemon start $TMP/${tfile}_log_good
18509         rm -rf $DIR/$tfile
18510         $LCTL debug_daemon stop
18511
18512         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
18513                error "lctl df log_bad failed"
18514
18515         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18516         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18517
18518         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
18519         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
18520
18521         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
18522                 error "bad_line good_line1 good_line2 are empty"
18523
18524         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18525         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
18526         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
18527
18528         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
18529         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
18530         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
18531
18532         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
18533                 error "bad_line_new good_line_new are empty"
18534
18535         local expected_good=$((good_line1 + good_line2*2))
18536
18537         rm -f $TMP/${tfile}*
18538         # LU-231, short malformed line may not be counted into bad lines
18539         if [ $bad_line -ne $bad_line_new ] &&
18540                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
18541                 error "expected $bad_line bad lines, but got $bad_line_new"
18542                 return 1
18543         fi
18544
18545         if [ $expected_good -ne $good_line_new ]; then
18546                 error "expected $expected_good good lines, but got $good_line_new"
18547                 return 2
18548         fi
18549         true
18550 }
18551 run_test 170 "test lctl df to handle corrupted log ====================="
18552
18553 test_171() { # bug20592
18554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18555
18556         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
18557         $LCTL set_param fail_loc=0x50e
18558         $LCTL set_param fail_val=3000
18559         multiop_bg_pause $DIR/$tfile O_s || true
18560         local MULTIPID=$!
18561         kill -USR1 $MULTIPID
18562         # cause log dump
18563         sleep 3
18564         wait $MULTIPID
18565         if dmesg | grep "recursive fault"; then
18566                 error "caught a recursive fault"
18567         fi
18568         $LCTL set_param fail_loc=0
18569         true
18570 }
18571 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
18572
18573 test_172() {
18574
18575         #define OBD_FAIL_OBD_CLEANUP  0x60e
18576         $LCTL set_param fail_loc=0x60e
18577         umount $MOUNT || error "umount $MOUNT failed"
18578         stack_trap "mount_client $MOUNT"
18579
18580         (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )) ||
18581                 error "no client OBDs are remained"
18582
18583         $LCTL dl | while read devno state type name foo; do
18584                 case $type in
18585                 lov|osc|lmv|mdc)
18586                         $LCTL --device $name cleanup
18587                         $LCTL --device $name detach
18588                         ;;
18589                 *)
18590                         # skip server devices
18591                         ;;
18592                 esac
18593         done
18594
18595         if (( $($LCTL dl | egrep -c " osc | lov | lmv | mdc ") > 0 )); then
18596                 $LCTL dl | egrep " osc | lov | lmv | mdc "
18597                 error "some client OBDs are still remained"
18598         fi
18599
18600 }
18601 run_test 172 "manual device removal with lctl cleanup/detach ======"
18602
18603 # it would be good to share it with obdfilter-survey/iokit-libecho code
18604 setup_obdecho_osc () {
18605         local rc=0
18606         local ost_nid=$1
18607         local obdfilter_name=$2
18608         echo "Creating new osc for $obdfilter_name on $ost_nid"
18609         # make sure we can find loopback nid
18610         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
18611
18612         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
18613                            ${obdfilter_name}_osc_UUID || rc=2; }
18614         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
18615                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
18616         return $rc
18617 }
18618
18619 cleanup_obdecho_osc () {
18620         local obdfilter_name=$1
18621         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
18622         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
18623         return 0
18624 }
18625
18626 obdecho_test() {
18627         local OBD=$1
18628         local node=$2
18629         local pages=${3:-64}
18630         local rc=0
18631         local id
18632
18633         local count=10
18634         local obd_size=$(get_obd_size $node $OBD)
18635         local page_size=$(get_page_size $node)
18636         if [[ -n "$obd_size" ]]; then
18637                 local new_count=$((obd_size / (pages * page_size / 1024)))
18638                 [[ $new_count -ge $count ]] || count=$new_count
18639         fi
18640
18641         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
18642         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
18643                            rc=2; }
18644         if [ $rc -eq 0 ]; then
18645             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
18646             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
18647         fi
18648         echo "New object id is $id"
18649         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
18650                            rc=4; }
18651         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
18652                            "test_brw $count w v $pages $id" || rc=4; }
18653         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
18654                            rc=4; }
18655         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
18656                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
18657         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
18658                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
18659         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
18660         return $rc
18661 }
18662
18663 test_180a() {
18664         skip "obdecho on osc is no longer supported"
18665 }
18666 run_test 180a "test obdecho on osc"
18667
18668 test_180b() {
18669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18670         remote_ost_nodsh && skip "remote OST with nodsh"
18671
18672         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18673                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18674                 error "failed to load module obdecho"
18675
18676         local target=$(do_facet ost1 $LCTL dl |
18677                        awk '/obdfilter/ { print $4; exit; }')
18678
18679         if [ -n "$target" ]; then
18680                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
18681         else
18682                 do_facet ost1 $LCTL dl
18683                 error "there is no obdfilter target on ost1"
18684         fi
18685 }
18686 run_test 180b "test obdecho directly on obdfilter"
18687
18688 test_180c() { # LU-2598
18689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18690         remote_ost_nodsh && skip "remote OST with nodsh"
18691         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
18692                 skip "Need MDS version at least 2.4.0"
18693
18694         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
18695                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
18696                 error "failed to load module obdecho"
18697
18698         local target=$(do_facet ost1 $LCTL dl |
18699                        awk '/obdfilter/ { print $4; exit; }')
18700
18701         if [ -n "$target" ]; then
18702                 local pages=16384 # 64MB bulk I/O RPC size
18703
18704                 obdecho_test "$target" ost1 "$pages" ||
18705                         error "obdecho_test with pages=$pages failed with $?"
18706         else
18707                 do_facet ost1 $LCTL dl
18708                 error "there is no obdfilter target on ost1"
18709         fi
18710 }
18711 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
18712
18713 test_181() { # bug 22177
18714         test_mkdir $DIR/$tdir
18715         # create enough files to index the directory
18716         createmany -o $DIR/$tdir/foobar 4000
18717         # print attributes for debug purpose
18718         lsattr -d .
18719         # open dir
18720         multiop_bg_pause $DIR/$tdir D_Sc || return 1
18721         MULTIPID=$!
18722         # remove the files & current working dir
18723         unlinkmany $DIR/$tdir/foobar 4000
18724         rmdir $DIR/$tdir
18725         kill -USR1 $MULTIPID
18726         wait $MULTIPID
18727         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
18728         return 0
18729 }
18730 run_test 181 "Test open-unlinked dir ========================"
18731
18732 test_182a() {
18733         local fcount=1000
18734         local tcount=10
18735
18736         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
18737
18738         $LCTL set_param mdc.*.rpc_stats=clear
18739
18740         for (( i = 0; i < $tcount; i++ )) ; do
18741                 mkdir $DIR/$tdir/$i
18742         done
18743
18744         for (( i = 0; i < $tcount; i++ )) ; do
18745                 createmany -o $DIR/$tdir/$i/f- $fcount &
18746         done
18747         wait
18748
18749         for (( i = 0; i < $tcount; i++ )) ; do
18750                 unlinkmany $DIR/$tdir/$i/f- $fcount &
18751         done
18752         wait
18753
18754         $LCTL get_param mdc.*.rpc_stats
18755
18756         rm -rf $DIR/$tdir
18757 }
18758 run_test 182a "Test parallel modify metadata operations from mdc"
18759
18760 test_182b() {
18761         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18762         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18763         local dcount=1000
18764         local tcount=10
18765         local stime
18766         local etime
18767         local delta
18768
18769         do_facet mds1 $LCTL list_param \
18770                 osp.$FSNAME-MDT*-osp-MDT*.rpc_stats ||
18771                 skip "MDS lacks parallel RPC handling"
18772
18773         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18774
18775         rpc_count=$(do_facet mds1 $LCTL get_param -n \
18776                     osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight)
18777
18778         stime=$(date +%s)
18779         createmany -i 0 -d $DIR/$tdir/t- $tcount
18780
18781         for (( i = 0; i < $tcount; i++ )) ; do
18782                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18783         done
18784         wait
18785         etime=$(date +%s)
18786         delta=$((etime - stime))
18787         echo "Time for file creation $delta sec for $rpc_count parallel RPCs"
18788
18789         stime=$(date +%s)
18790         for (( i = 0; i < $tcount; i++ )) ; do
18791                 unlinkmany -d $DIR/$tdir/$i/d- $dcount &
18792         done
18793         wait
18794         etime=$(date +%s)
18795         delta=$((etime - stime))
18796         echo "Time for file removal $delta sec for $rpc_count parallel RPCs"
18797
18798         rm -rf $DIR/$tdir
18799
18800         $LFS mkdir -i 0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18801
18802         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=1
18803
18804         stime=$(date +%s)
18805         createmany -i 0 -d $DIR/$tdir/t- $tcount
18806
18807         for (( i = 0; i < $tcount; i++ )) ; do
18808                 createmany -i 0 -d $DIR/$tdir/t-$i/d- 0 $dcount &
18809         done
18810         wait
18811         etime=$(date +%s)
18812         delta=$((etime - stime))
18813         echo "Time for file creation $delta sec for 1 RPC sent at a time"
18814
18815         stime=$(date +%s)
18816         for (( i = 0; i < $tcount; i++ )) ; do
18817                 unlinkmany -d $DIR/$tdir/t-$i/d- $dcount &
18818         done
18819         wait
18820         etime=$(date +%s)
18821         delta=$((etime - stime))
18822         echo "Time for file removal $delta sec for 1 RPC sent at a time"
18823
18824         do_facet mds1 $LCTL set_param osp.$FSNAME-MDT0001-osp-MDT0000.max_mod_rpcs_in_flight=$rpc_count
18825 }
18826 run_test 182b "Test parallel modify metadata operations from osp"
18827
18828 test_183() { # LU-2275
18829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18830         remote_mds_nodsh && skip "remote MDS with nodsh"
18831         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
18832                 skip "Need MDS version at least 2.3.56"
18833
18834         mkdir_on_mdt0 $DIR/$tdir || error "creating dir $DIR/$tdir"
18835         echo aaa > $DIR/$tdir/$tfile
18836
18837 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
18838         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
18839
18840         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
18841         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
18842
18843         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
18844
18845         # Flush negative dentry cache
18846         touch $DIR/$tdir/$tfile
18847
18848         # We are not checking for any leaked references here, they'll
18849         # become evident next time we do cleanup with module unload.
18850         rm -rf $DIR/$tdir
18851 }
18852 run_test 183 "No crash or request leak in case of strange dispositions ========"
18853
18854 # test suite 184 is for LU-2016, LU-2017
18855 test_184a() {
18856         check_swap_layouts_support
18857
18858         dir0=$DIR/$tdir/$testnum
18859         test_mkdir -p -c1 $dir0
18860         ref1=/etc/passwd
18861         ref2=/etc/group
18862         file1=$dir0/f1
18863         file2=$dir0/f2
18864         $LFS setstripe -c1 $file1
18865         cp $ref1 $file1
18866         $LFS setstripe -c2 $file2
18867         cp $ref2 $file2
18868         gen1=$($LFS getstripe -g $file1)
18869         gen2=$($LFS getstripe -g $file2)
18870
18871         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
18872         gen=$($LFS getstripe -g $file1)
18873         [[ $gen1 != $gen ]] ||
18874                 error "Layout generation on $file1 does not change"
18875         gen=$($LFS getstripe -g $file2)
18876         [[ $gen2 != $gen ]] ||
18877                 error "Layout generation on $file2 does not change"
18878
18879         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
18880         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
18881
18882         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
18883 }
18884 run_test 184a "Basic layout swap"
18885
18886 test_184b() {
18887         check_swap_layouts_support
18888
18889         dir0=$DIR/$tdir/$testnum
18890         mkdir -p $dir0 || error "creating dir $dir0"
18891         file1=$dir0/f1
18892         file2=$dir0/f2
18893         file3=$dir0/f3
18894         dir1=$dir0/d1
18895         dir2=$dir0/d2
18896         mkdir $dir1 $dir2
18897         $LFS setstripe -c1 $file1
18898         $LFS setstripe -c2 $file2
18899         $LFS setstripe -c1 $file3
18900         chown $RUNAS_ID $file3
18901         gen1=$($LFS getstripe -g $file1)
18902         gen2=$($LFS getstripe -g $file2)
18903
18904         $LFS swap_layouts $dir1 $dir2 &&
18905                 error "swap of directories layouts should fail"
18906         $LFS swap_layouts $dir1 $file1 &&
18907                 error "swap of directory and file layouts should fail"
18908         $RUNAS $LFS swap_layouts $file1 $file2 &&
18909                 error "swap of file we cannot write should fail"
18910         $LFS swap_layouts $file1 $file3 &&
18911                 error "swap of file with different owner should fail"
18912         /bin/true # to clear error code
18913 }
18914 run_test 184b "Forbidden layout swap (will generate errors)"
18915
18916 test_184c() {
18917         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
18918         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
18919         check_swap_layouts_support
18920         check_swap_layout_no_dom $DIR
18921
18922         local dir0=$DIR/$tdir/$testnum
18923         mkdir -p $dir0 || error "creating dir $dir0"
18924
18925         local ref1=$dir0/ref1
18926         local ref2=$dir0/ref2
18927         local file1=$dir0/file1
18928         local file2=$dir0/file2
18929         # create a file large enough for the concurrent test
18930         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
18931         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
18932         echo "ref file size: ref1($(stat -c %s $ref1))," \
18933              "ref2($(stat -c %s $ref2))"
18934
18935         cp $ref2 $file2
18936         dd if=$ref1 of=$file1 bs=16k &
18937         local DD_PID=$!
18938
18939         # Make sure dd starts to copy file, but wait at most 5 seconds
18940         local loops=0
18941         while [ ! -s $file1 -a $((loops++)) -lt 50 ]; do sleep 0.1; done
18942
18943         $LFS swap_layouts $file1 $file2
18944         local rc=$?
18945         wait $DD_PID
18946         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
18947         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
18948
18949         # how many bytes copied before swapping layout
18950         local copied=$(stat -c %s $file2)
18951         local remaining=$(stat -c %s $ref1)
18952         remaining=$((remaining - copied))
18953         echo "Copied $copied bytes before swapping layout..."
18954
18955         cmp -n $copied $file1 $ref2 | grep differ &&
18956                 error "Content mismatch [0, $copied) of ref2 and file1"
18957         cmp -n $copied $file2 $ref1 ||
18958                 error "Content mismatch [0, $copied) of ref1 and file2"
18959         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
18960                 error "Content mismatch [$copied, EOF) of ref1 and file1"
18961
18962         # clean up
18963         rm -f $ref1 $ref2 $file1 $file2
18964 }
18965 run_test 184c "Concurrent write and layout swap"
18966
18967 test_184d() {
18968         check_swap_layouts_support
18969         check_swap_layout_no_dom $DIR
18970         [ -z "$(which getfattr 2>/dev/null)" ] &&
18971                 skip_env "no getfattr command"
18972
18973         local file1=$DIR/$tdir/$tfile-1
18974         local file2=$DIR/$tdir/$tfile-2
18975         local file3=$DIR/$tdir/$tfile-3
18976         local lovea1
18977         local lovea2
18978
18979         mkdir -p $DIR/$tdir
18980         touch $file1 || error "create $file1 failed"
18981         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
18982                 error "create $file2 failed"
18983         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
18984                 error "create $file3 failed"
18985         lovea1=$(get_layout_param $file1)
18986
18987         $LFS swap_layouts $file2 $file3 ||
18988                 error "swap $file2 $file3 layouts failed"
18989         $LFS swap_layouts $file1 $file2 ||
18990                 error "swap $file1 $file2 layouts failed"
18991
18992         lovea2=$(get_layout_param $file2)
18993         echo "$lovea1"
18994         echo "$lovea2"
18995         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
18996
18997         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
18998         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
18999 }
19000 run_test 184d "allow stripeless layouts swap"
19001
19002 test_184e() {
19003         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
19004                 skip "Need MDS version at least 2.6.94"
19005         check_swap_layouts_support
19006         check_swap_layout_no_dom $DIR
19007         [ -z "$(which getfattr 2>/dev/null)" ] &&
19008                 skip_env "no getfattr command"
19009
19010         local file1=$DIR/$tdir/$tfile-1
19011         local file2=$DIR/$tdir/$tfile-2
19012         local file3=$DIR/$tdir/$tfile-3
19013         local lovea
19014
19015         mkdir -p $DIR/$tdir
19016         touch $file1 || error "create $file1 failed"
19017         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
19018                 error "create $file2 failed"
19019         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
19020                 error "create $file3 failed"
19021
19022         $LFS swap_layouts $file1 $file2 ||
19023                 error "swap $file1 $file2 layouts failed"
19024
19025         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
19026         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
19027
19028         echo 123 > $file1 || error "Should be able to write into $file1"
19029
19030         $LFS swap_layouts $file1 $file3 ||
19031                 error "swap $file1 $file3 layouts failed"
19032
19033         echo 123 > $file1 || error "Should be able to write into $file1"
19034
19035         rm -rf $file1 $file2 $file3
19036 }
19037 run_test 184e "Recreate layout after stripeless layout swaps"
19038
19039 test_184f() {
19040         # Create a file with name longer than sizeof(struct stat) ==
19041         # 144 to see if we can get chars from the file name to appear
19042         # in the returned striping. Note that 'f' == 0x66.
19043         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
19044
19045         mkdir -p $DIR/$tdir
19046         mcreate $DIR/$tdir/$file
19047         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
19048                 error "IOC_MDC_GETFILEINFO returned garbage striping"
19049         fi
19050 }
19051 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
19052
19053 test_185() { # LU-2441
19054         # LU-3553 - no volatile file support in old servers
19055         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
19056                 skip "Need MDS version at least 2.3.60"
19057
19058         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
19059         touch $DIR/$tdir/spoo
19060         local mtime1=$(stat -c "%Y" $DIR/$tdir)
19061         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
19062                 error "cannot create/write a volatile file"
19063         [ "$FILESET" == "" ] &&
19064         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
19065                 error "FID is still valid after close"
19066
19067         multiop_bg_pause $DIR/$tdir vVw4096_c
19068         local multi_pid=$!
19069
19070         local OLD_IFS=$IFS
19071         IFS=":"
19072         local fidv=($fid)
19073         IFS=$OLD_IFS
19074         # assume that the next FID for this client is sequential, since stdout
19075         # is unfortunately eaten by multiop_bg_pause
19076         local n=$((${fidv[1]} + 1))
19077         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
19078         if [ "$FILESET" == "" ]; then
19079                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
19080                         error "FID is missing before close"
19081         fi
19082         kill -USR1 $multi_pid
19083         # 1 second delay, so if mtime change we will see it
19084         sleep 1
19085         local mtime2=$(stat -c "%Y" $DIR/$tdir)
19086         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
19087 }
19088 run_test 185 "Volatile file support"
19089
19090 function create_check_volatile() {
19091         local idx=$1
19092         local tgt
19093
19094         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
19095         local PID=$!
19096         sleep 1
19097         local FID=$(cat /tmp/${tfile}.fid)
19098         [ "$FID" == "" ] && error "can't get FID for volatile"
19099         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
19100         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
19101         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
19102         kill -USR1 $PID
19103         wait
19104         sleep 1
19105         cancel_lru_locks mdc # flush opencache
19106         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
19107         return 0
19108 }
19109
19110 test_185a(){
19111         # LU-12516 - volatile creation via .lustre
19112         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
19113                 skip "Need MDS version at least 2.3.55"
19114
19115         create_check_volatile 0
19116         [ $MDSCOUNT -lt 2 ] && return 0
19117
19118         # DNE case
19119         create_check_volatile 1
19120
19121         return 0
19122 }
19123 run_test 185a "Volatile file creation in .lustre/fid/"
19124
19125 test_187a() {
19126         remote_mds_nodsh && skip "remote MDS with nodsh"
19127         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19128                 skip "Need MDS version at least 2.3.0"
19129
19130         local dir0=$DIR/$tdir/$testnum
19131         mkdir -p $dir0 || error "creating dir $dir0"
19132
19133         local file=$dir0/file1
19134         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
19135         local dv1=$($LFS data_version $file)
19136         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
19137         local dv2=$($LFS data_version $file)
19138         [[ $dv1 != $dv2 ]] ||
19139                 error "data version did not change on write $dv1 == $dv2"
19140
19141         # clean up
19142         rm -f $file1
19143 }
19144 run_test 187a "Test data version change"
19145
19146 test_187b() {
19147         remote_mds_nodsh && skip "remote MDS with nodsh"
19148         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
19149                 skip "Need MDS version at least 2.3.0"
19150
19151         local dir0=$DIR/$tdir/$testnum
19152         mkdir -p $dir0 || error "creating dir $dir0"
19153
19154         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
19155         [[ ${DV[0]} != ${DV[1]} ]] ||
19156                 error "data version did not change on write"\
19157                       " ${DV[0]} == ${DV[1]}"
19158
19159         # clean up
19160         rm -f $file1
19161 }
19162 run_test 187b "Test data version change on volatile file"
19163
19164 test_200() {
19165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19166         remote_mgs_nodsh && skip "remote MGS with nodsh"
19167         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19168
19169         local POOL=${POOL:-cea1}
19170         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
19171         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
19172         # Pool OST targets
19173         local first_ost=0
19174         local last_ost=$(($OSTCOUNT - 1))
19175         local ost_step=2
19176         local ost_list=$(seq $first_ost $ost_step $last_ost)
19177         local ost_range="$first_ost $last_ost $ost_step"
19178         local test_path=$POOL_ROOT/$POOL_DIR_NAME
19179         local file_dir=$POOL_ROOT/file_tst
19180         local subdir=$test_path/subdir
19181         local rc=0
19182
19183         while : ; do
19184                 # former test_200a test_200b
19185                 pool_add $POOL                          || { rc=$? ; break; }
19186                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
19187                 # former test_200c test_200d
19188                 mkdir -p $test_path
19189                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
19190                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
19191                 mkdir -p $subdir
19192                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
19193                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
19194                                                         || { rc=$? ; break; }
19195                 # former test_200e test_200f
19196                 local files=$((OSTCOUNT*3))
19197                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
19198                                                         || { rc=$? ; break; }
19199                 pool_create_files $POOL $file_dir $files "$ost_list" \
19200                                                         || { rc=$? ; break; }
19201                 # former test_200g test_200h
19202                 pool_lfs_df $POOL                       || { rc=$? ; break; }
19203                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
19204
19205                 # former test_201a test_201b test_201c
19206                 pool_remove_first_target $POOL          || { rc=$? ; break; }
19207
19208                 local f=$test_path/$tfile
19209                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
19210                 pool_remove $POOL $f                    || { rc=$? ; break; }
19211                 break
19212         done
19213
19214         destroy_test_pools
19215
19216         return $rc
19217 }
19218 run_test 200 "OST pools"
19219
19220 # usage: default_attr <count | size | offset>
19221 default_attr() {
19222         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
19223 }
19224
19225 # usage: check_default_stripe_attr
19226 check_default_stripe_attr() {
19227         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
19228         case $1 in
19229         --stripe-count|-c)
19230                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
19231         --stripe-size|-S)
19232                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
19233         --stripe-index|-i)
19234                 EXPECTED=-1;;
19235         *)
19236                 error "unknown getstripe attr '$1'"
19237         esac
19238
19239         [ $ACTUAL == $EXPECTED ] ||
19240                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
19241 }
19242
19243 test_204a() {
19244         test_mkdir $DIR/$tdir
19245         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
19246
19247         check_default_stripe_attr --stripe-count
19248         check_default_stripe_attr --stripe-size
19249         check_default_stripe_attr --stripe-index
19250 }
19251 run_test 204a "Print default stripe attributes"
19252
19253 test_204b() {
19254         test_mkdir $DIR/$tdir
19255         $LFS setstripe --stripe-count 1 $DIR/$tdir
19256
19257         check_default_stripe_attr --stripe-size
19258         check_default_stripe_attr --stripe-index
19259 }
19260 run_test 204b "Print default stripe size and offset"
19261
19262 test_204c() {
19263         test_mkdir $DIR/$tdir
19264         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19265
19266         check_default_stripe_attr --stripe-count
19267         check_default_stripe_attr --stripe-index
19268 }
19269 run_test 204c "Print default stripe count and offset"
19270
19271 test_204d() {
19272         test_mkdir $DIR/$tdir
19273         $LFS setstripe --stripe-index 0 $DIR/$tdir
19274
19275         check_default_stripe_attr --stripe-count
19276         check_default_stripe_attr --stripe-size
19277 }
19278 run_test 204d "Print default stripe count and size"
19279
19280 test_204e() {
19281         test_mkdir $DIR/$tdir
19282         $LFS setstripe -d $DIR/$tdir
19283
19284         check_default_stripe_attr --stripe-count --raw
19285         check_default_stripe_attr --stripe-size --raw
19286         check_default_stripe_attr --stripe-index --raw
19287 }
19288 run_test 204e "Print raw stripe attributes"
19289
19290 test_204f() {
19291         test_mkdir $DIR/$tdir
19292         $LFS setstripe --stripe-count 1 $DIR/$tdir
19293
19294         check_default_stripe_attr --stripe-size --raw
19295         check_default_stripe_attr --stripe-index --raw
19296 }
19297 run_test 204f "Print raw stripe size and offset"
19298
19299 test_204g() {
19300         test_mkdir $DIR/$tdir
19301         $LFS setstripe --stripe-size 65536 $DIR/$tdir
19302
19303         check_default_stripe_attr --stripe-count --raw
19304         check_default_stripe_attr --stripe-index --raw
19305 }
19306 run_test 204g "Print raw stripe count and offset"
19307
19308 test_204h() {
19309         test_mkdir $DIR/$tdir
19310         $LFS setstripe --stripe-index 0 $DIR/$tdir
19311
19312         check_default_stripe_attr --stripe-count --raw
19313         check_default_stripe_attr --stripe-size --raw
19314 }
19315 run_test 204h "Print raw stripe count and size"
19316
19317 # Figure out which job scheduler is being used, if any,
19318 # or use a fake one
19319 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
19320         JOBENV=SLURM_JOB_ID
19321 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
19322         JOBENV=LSB_JOBID
19323 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
19324         JOBENV=PBS_JOBID
19325 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
19326         JOBENV=LOADL_STEP_ID
19327 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
19328         JOBENV=JOB_ID
19329 else
19330         $LCTL list_param jobid_name > /dev/null 2>&1
19331         if [ $? -eq 0 ]; then
19332                 JOBENV=nodelocal
19333         else
19334                 JOBENV=FAKE_JOBID
19335         fi
19336 fi
19337 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
19338
19339 verify_jobstats() {
19340         local cmd=($1)
19341         shift
19342         local facets="$@"
19343
19344 # we don't really need to clear the stats for this test to work, since each
19345 # command has a unique jobid, but it makes debugging easier if needed.
19346 #       for facet in $facets; do
19347 #               local dev=$(convert_facet2label $facet)
19348 #               # clear old jobstats
19349 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
19350 #       done
19351
19352         # use a new JobID for each test, or we might see an old one
19353         [ "$JOBENV" = "FAKE_JOBID" ] &&
19354                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
19355
19356         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
19357
19358         [ "$JOBENV" = "nodelocal" ] && {
19359                 FAKE_JOBID=id.$testnum.%e.$RANDOM
19360                 $LCTL set_param jobid_name=$FAKE_JOBID
19361                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
19362         }
19363
19364         log "Test: ${cmd[*]}"
19365         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
19366
19367         if [ $JOBENV = "FAKE_JOBID" ]; then
19368                 FAKE_JOBID=$JOBVAL ${cmd[*]}
19369         else
19370                 ${cmd[*]}
19371         fi
19372
19373         # all files are created on OST0000
19374         for facet in $facets; do
19375                 local stats="*.$(convert_facet2label $facet).job_stats"
19376
19377                 # strip out libtool wrappers for in-tree executables
19378                 if (( $(do_facet $facet lctl get_param $stats |
19379                         sed -e 's/\.lt-/./' | grep -cw $JOBVAL) != 1 )); then
19380                         do_facet $facet lctl get_param $stats
19381                         error "No jobstats for $JOBVAL found on $facet::$stats"
19382                 fi
19383         done
19384 }
19385
19386 jobstats_set() {
19387         local new_jobenv=$1
19388
19389         set_persistent_param_and_check client "jobid_var" \
19390                 "$FSNAME.sys.jobid_var" $new_jobenv
19391 }
19392
19393 test_205a() { # Job stats
19394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19395         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
19396                 skip "Need MDS version with at least 2.7.1"
19397         remote_mgs_nodsh && skip "remote MGS with nodsh"
19398         remote_mds_nodsh && skip "remote MDS with nodsh"
19399         remote_ost_nodsh && skip "remote OST with nodsh"
19400         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
19401                 skip "Server doesn't support jobstats"
19402         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
19403
19404         local old_jobenv=$($LCTL get_param -n jobid_var)
19405         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
19406         stack_trap "jobstats_set $old_jobenv" EXIT
19407
19408         changelog_register
19409
19410         local old_jobid_name=$($LCTL get_param jobid_name)
19411         stack_trap "$LCTL set_param $old_jobid_name" EXIT
19412
19413         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
19414                                 mdt.*.job_cleanup_interval | head -n 1)
19415         local new_interval=5
19416         do_facet $SINGLEMDS \
19417                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
19418         stack_trap "do_facet $SINGLEMDS \
19419                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
19420         local start=$SECONDS
19421
19422         local cmd
19423         # mkdir
19424         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir"
19425         verify_jobstats "$cmd" "$SINGLEMDS"
19426         # rmdir
19427         cmd="rmdir $DIR/$tdir"
19428         verify_jobstats "$cmd" "$SINGLEMDS"
19429         # mkdir on secondary MDT
19430         if [ $MDSCOUNT -gt 1 ]; then
19431                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
19432                 verify_jobstats "$cmd" "mds2"
19433         fi
19434         # mknod
19435         cmd="mknod $DIR/$tfile c 1 3"
19436         verify_jobstats "$cmd" "$SINGLEMDS"
19437         # unlink
19438         cmd="rm -f $DIR/$tfile"
19439         verify_jobstats "$cmd" "$SINGLEMDS"
19440         # create all files on OST0000 so verify_jobstats can find OST stats
19441         # open & close
19442         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
19443         verify_jobstats "$cmd" "$SINGLEMDS"
19444         # setattr
19445         cmd="touch $DIR/$tfile"
19446         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19447         # write
19448         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
19449         verify_jobstats "$cmd" "ost1"
19450         # read
19451         cancel_lru_locks osc
19452         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
19453         verify_jobstats "$cmd" "ost1"
19454         # truncate
19455         cmd="$TRUNCATE $DIR/$tfile 0"
19456         verify_jobstats "$cmd" "$SINGLEMDS ost1"
19457         # rename
19458         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
19459         verify_jobstats "$cmd" "$SINGLEMDS"
19460         # jobstats expiry - sleep until old stats should be expired
19461         local left=$((new_interval + 5 - (SECONDS - start)))
19462         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
19463                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
19464                         "0" $left
19465         cmd="$LFS mkdir -i 0 -c 1 $DIR/$tdir.expire"
19466         verify_jobstats "$cmd" "$SINGLEMDS"
19467         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
19468             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
19469
19470         # Ensure that jobid are present in changelog (if supported by MDS)
19471         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
19472                 changelog_dump | tail -10
19473                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
19474                 [ $jobids -eq 9 ] ||
19475                         error "Wrong changelog jobid count $jobids != 9"
19476
19477                 # LU-5862
19478                 JOBENV="disable"
19479                 jobstats_set $JOBENV
19480                 touch $DIR/$tfile
19481                 changelog_dump | grep $tfile
19482                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
19483                 [ $jobids -eq 0 ] ||
19484                         error "Unexpected jobids when jobid_var=$JOBENV"
19485         fi
19486
19487         # test '%j' access to environment variable - if supported
19488         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"; then
19489                 JOBENV="JOBCOMPLEX"
19490                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19491
19492                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19493         fi
19494
19495         if lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%H.E"; then
19496                 JOBENV="JOBCOMPLEX"
19497                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname -s).E"
19498
19499                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19500         fi
19501
19502         # test '%j' access to per-session jobid - if supported
19503         if lctl list_param jobid_this_session > /dev/null 2>&1
19504         then
19505                 lctl set_param jobid_var=session jobid_name="S.%j.%e.%u.%h.E"
19506                 lctl set_param jobid_this_session=$USER
19507
19508                 JOBENV="JOBCOMPLEX"
19509                 JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
19510
19511                 verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
19512         fi
19513 }
19514 run_test 205a "Verify job stats"
19515
19516 # LU-13117, LU-13597, LU-16599
19517 test_205b() {
19518         (( $MDS1_VERSION >= $(version_code 2.13.54.91) )) ||
19519                 skip "Need MDS version at least 2.13.54.91"
19520
19521         local job_stats="mdt.*.job_stats"
19522         local old_jobid=$(do_facet mds1 $LCTL get_param jobid_var)
19523
19524         do_facet mds1 $LCTL set_param $job_stats=clear
19525
19526         # Setting jobid_var to USER might not be supported
19527         [[ -n "$old_jobid" ]] && stack_trap "$LCTL set_param $old_jobid"
19528         $LCTL set_param jobid_var=USER || true
19529         stack_trap "$LCTL set_param $($LCTL get_param jobid_name)"
19530         $LCTL set_param jobid_name="%j.%e.%u"
19531
19532         env -i USERTESTJOBSTATS=foolish touch $DIR/$tfile.1
19533         do_facet mds1 $LCTL get_param $job_stats | grep "job_id:.*foolish" &&
19534                 { do_facet mds1 $LCTL get_param $job_stats;
19535                   error "Unexpected jobid found"; }
19536         do_facet mds1 $LCTL get_param $job_stats | grep "open:.*min.*max.*sum"||
19537                 { do_facet mds1 $LCTL get_param $job_stats;
19538                   error "wrong job_stats format found"; }
19539
19540         (( $MDS1_VERSION <= $(version_code 2.15.0) )) &&
19541                 echo "MDS does not yet escape jobid" && return 0
19542
19543         mkdir_on_mdt0 $DIR/$tdir
19544         $LCTL set_param jobid_var=TEST205b
19545         env -i TEST205b="has sp" touch $DIR/$tdir/$tfile.2
19546         local jobid=$(do_facet mds1 $LCTL get_param $job_stats |
19547                       awk '/has\\x20sp/ {print $3}')
19548         [[ -n "$jobid" ]] || { do_facet mds1 $LCTL get_param $job_stats;
19549                   error "jobid not escaped"; }
19550
19551         if (( $MDS1_VERSION >= $(version_code 2.15.53.139) )); then
19552                 # need to run such a command on mds1:
19553                 # lctl set_param mdt.$FSNAME-MDT0000.job_stats='"has\x20sp.touch.0"'
19554                 #
19555                 # there might be multiple MDTs on single mds server, so need to
19556                 # specifiy MDT0000. Or the command will fail due to other MDTs
19557                 do_facet_vp mds1 $LCTL set_param mdt.$FSNAME-MDT0000.job_stats=$jobid ||
19558                         error "cannot clear escaped jobid in job_stats";
19559         else
19560                 echo "MDS does not support clearing escaped jobid"
19561         fi
19562 }
19563 run_test 205b "Verify job stats jobid and output format"
19564
19565 # LU-13733
19566 test_205c() {
19567         $LCTL set_param llite.*.stats=0
19568         dd if=/dev/zero of=$DIR/$tfile.1 bs=4k count=1
19569         $LCTL get_param llite.*.stats
19570         $LCTL get_param llite.*.stats | grep \
19571                 "write_bytes *1 samples \[bytes\] 4096 4096 4096 16777216" ||
19572                         error "wrong client stats format found"
19573 }
19574 run_test 205c "Verify client stats format"
19575
19576 test_205d() {
19577         local file=$DIR/$tdir/$tfile
19578
19579         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19580                 skip "need lustre >= 2.15.53 for lljobstat"
19581         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19582                 skip "need lustre >= 2.15.53 for lljobstat"
19583         verify_yaml_available || skip_env "YAML verification not installed"
19584
19585         test_mkdir -i 0 $DIR/$tdir
19586         $LFS setstripe -E 1M -L mdt -E -1 $file || error "create file failed"
19587
19588         dd if=/dev/zero of=$file bs=1M count=10 conv=sync ||
19589                 error "failed to write data to $file"
19590         mv $file $file.2
19591
19592         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats"
19593         echo -n 'verify rename_stats...'
19594         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.rename_stats" |
19595                 verify_yaml || error "rename_stats is not valid YAML"
19596         echo " OK"
19597
19598         echo -n 'verify mdt job_stats...'
19599         do_facet mds1 "$LCTL get_param -n mdt.$FSNAME-MDT0000.job_stats" |
19600                 verify_yaml || error "job_stats on mds1 is not valid YAML"
19601         echo " OK"
19602
19603         echo -n 'verify ost job_stats...'
19604         do_facet ost1 "$LCTL get_param -n obdfilter.$FSNAME-OST0000.job_stats" |
19605                 verify_yaml || error "job_stats on ost1 is not valid YAML"
19606         echo " OK"
19607 }
19608 run_test 205d "verify the format of some stats files"
19609
19610 test_205e() {
19611         local ops_comma
19612         local file=$DIR/$tdir/$tfile
19613         local -a cli_params
19614
19615         (( $MDS1_VERSION >= $(version_code 2.15.53) )) ||
19616                 skip "need lustre >= 2.15.53 for lljobstat"
19617         (( $OST1_VERSION >= $(version_code 2.15.53) )) ||
19618                 skip "need lustre >= 2.15.53 for lljobstat"
19619         verify_yaml_available || skip_env "YAML verification not installed"
19620
19621         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19622         $LCTL set_param jobid_var=nodelocal jobid_name=205e.%e.%u
19623         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19624
19625         mkdir_on_mdt0 $DIR/$tdir || error "failed to create dir"
19626
19627         $LFS setstripe -E EOF -i 0 -c 1 $file ||
19628                 error "failed to create $file on ost1"
19629         dd if=/dev/zero of=$file bs=1M count=10 oflag=sync ||
19630                 error "failed to write data to $file"
19631
19632         do_facet mds1 "$LCTL get_param *.*.job_stats"
19633         do_facet ost1 "$LCTL get_param *.*.job_stats"
19634
19635         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000"
19636         do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" | verify_yaml ||
19637                 error "The output of lljobstat is not an valid YAML"
19638
19639         # verify that job dd.0 does exist and has some ops on ost1
19640         # typically this line is like:
19641         # - 205e.dd.0:            {ops: 20, ...}
19642         ops_comma=$(do_facet ost1 "lljobstat -n 1 -i 0 -c 1000" |
19643                     awk '$2=="205e.dd.0:" {print $4}')
19644
19645         (( ${ops_comma%,} >= 10 )) ||
19646                 error "cannot find job 205e.dd.0 with ops >= 10"
19647 }
19648 run_test 205e "verify the output of lljobstat"
19649
19650 test_205f() {
19651         verify_yaml_available || skip_env "YAML verification not installed"
19652
19653         # check both qos_ost_weights and qos_mdt_weights
19654         do_facet mds1 $LCTL get_param -n lod.*.qos*weights
19655         do_facet mds1 $LCTL get_param -n lod.*.qos*weights | verify_yaml ||
19656                 error "qos_ost_weights is not valid YAML"
19657 }
19658 run_test 205f "verify qos_ost_weights YAML format "
19659
19660 __test_205_jobstats_dump() {
19661         local -a pids
19662         local nbr_instance=$1
19663
19664         while true; do
19665                 if (( ${#pids[@]} >= nbr_instance )); then
19666                         wait ${pids[@]}
19667                         pids=()
19668                 fi
19669
19670                 do_facet mds1 "$LCTL get_param mdt.*.job_stats > /dev/null" &
19671                 pids+=( $! )
19672         done
19673 }
19674
19675 __test_205_cleanup() {
19676         kill $@
19677         # Clear all job entries
19678         do_facet mds1 "$LCTL set_param mdt.*.job_stats=clear"
19679 }
19680
19681 test_205g() {
19682         local -a mds1_params
19683         local -a cli_params
19684         local pids
19685         local interval=5
19686
19687         mds1_params=( $(do_facet mds1 $LCTL get_param mdt.*.job_cleanup_interval) )
19688         do_facet mds1 $LCTL set_param mdt.*.job_cleanup_interval=$interval
19689         stack_trap "do_facet mds1 $LCTL set_param ${mds1_params[*]}" EXIT
19690
19691         cli_params=( $($LCTL get_param jobid_name jobid_var) )
19692         $LCTL set_param jobid_var=TEST205G_ID jobid_name=%j.%p
19693         stack_trap "$LCTL set_param ${cli_params[*]}" EXIT
19694
19695         # start jobs loop
19696         export TEST205G_ID=205g
19697         stack_trap "unset TEST205G_ID" EXIT
19698         while true; do
19699                 printf $DIR/$tfile.{0001..1000} | xargs -P10 -n1 touch
19700         done & pids="$! "
19701
19702         __test_205_jobstats_dump 4 & pids+="$! "
19703         stack_trap "__test_205_cleanup $pids" EXIT INT
19704
19705         [[ $SLOW == "no" ]] && sleep 90 || sleep 240
19706 }
19707 run_test 205g "stress test for job_stats procfile"
19708
19709 # LU-1480, LU-1773 and LU-1657
19710 test_206() {
19711         mkdir -p $DIR/$tdir
19712         $LFS setstripe -c -1 $DIR/$tdir
19713 #define OBD_FAIL_LOV_INIT 0x1403
19714         $LCTL set_param fail_loc=0xa0001403
19715         $LCTL set_param fail_val=1
19716         touch $DIR/$tdir/$tfile || true
19717 }
19718 run_test 206 "fail lov_init_raid0() doesn't lbug"
19719
19720 test_207a() {
19721         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19722         local fsz=`stat -c %s $DIR/$tfile`
19723         cancel_lru_locks mdc
19724
19725         # do not return layout in getattr intent
19726 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
19727         $LCTL set_param fail_loc=0x170
19728         local sz=`stat -c %s $DIR/$tfile`
19729
19730         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
19731
19732         rm -rf $DIR/$tfile
19733 }
19734 run_test 207a "can refresh layout at glimpse"
19735
19736 test_207b() {
19737         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
19738         local cksum=`md5sum $DIR/$tfile`
19739         local fsz=`stat -c %s $DIR/$tfile`
19740         cancel_lru_locks mdc
19741         cancel_lru_locks osc
19742
19743         # do not return layout in getattr intent
19744 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
19745         $LCTL set_param fail_loc=0x171
19746
19747         # it will refresh layout after the file is opened but before read issues
19748         echo checksum is "$cksum"
19749         echo "$cksum" |md5sum -c --quiet || error "file differs"
19750
19751         rm -rf $DIR/$tfile
19752 }
19753 run_test 207b "can refresh layout at open"
19754
19755 test_208() {
19756         # FIXME: in this test suite, only RD lease is used. This is okay
19757         # for now as only exclusive open is supported. After generic lease
19758         # is done, this test suite should be revised. - Jinshan
19759
19760         remote_mds_nodsh && skip "remote MDS with nodsh"
19761         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
19762                 skip "Need MDS version at least 2.4.52"
19763
19764         echo "==== test 1: verify get lease work"
19765         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
19766
19767         echo "==== test 2: verify lease can be broken by upcoming open"
19768         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19769         local PID=$!
19770         sleep 2
19771
19772         $MULTIOP $DIR/$tfile oO_RDWR:c
19773         kill -USR1 $PID && wait $PID || error "break lease error"
19774
19775         echo "==== test 3: verify lease can't be granted if an open already exists"
19776         $MULTIOP $DIR/$tfile oO_RDWR:_c &
19777         local PID=$!
19778         sleep 2
19779
19780         $MULTIOP $DIR/$tfile oO_RDWR:eReUc && error "apply lease should fail"
19781         kill -USR1 $PID && wait $PID || error "open file error"
19782
19783         echo "==== test 4: lease can sustain over recovery"
19784         $MULTIOP $DIR/$tfile oO_RDWR:eR_E+eUc &
19785         PID=$!
19786         sleep 2
19787
19788         fail mds1
19789
19790         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
19791
19792         echo "==== test 5: lease broken can't be regained by replay"
19793         $MULTIOP $DIR/$tfile oO_RDWR:eR_E-eUc &
19794         PID=$!
19795         sleep 2
19796
19797         # open file to break lease and then recovery
19798         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
19799         fail mds1
19800
19801         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
19802
19803         rm -f $DIR/$tfile
19804 }
19805 run_test 208 "Exclusive open"
19806
19807 test_209() {
19808         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
19809                 skip_env "must have disp_stripe"
19810
19811         touch $DIR/$tfile
19812         sync; sleep 5; sync;
19813
19814         echo 3 > /proc/sys/vm/drop_caches
19815         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19816                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19817         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19818
19819         # open/close 500 times
19820         for i in $(seq 500); do
19821                 cat $DIR/$tfile
19822         done
19823
19824         echo 3 > /proc/sys/vm/drop_caches
19825         [ -f /sys/kernel/slab/ptlrpc_cache/shrink ] &&
19826                 echo 1 > /sys/kernel/slab/ptlrpc_cache/shrink
19827         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
19828
19829         echo "before: $req_before, after: $req_after"
19830         [ $((req_after - req_before)) -ge 300 ] &&
19831                 error "open/close requests are not freed"
19832         return 0
19833 }
19834 run_test 209 "read-only open/close requests should be freed promptly"
19835
19836 test_210() {
19837         local pid
19838
19839         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eW_E+eUc &
19840         pid=$!
19841         sleep 1
19842
19843         $LFS getstripe $DIR/$tfile
19844         kill -USR1 $pid
19845         wait $pid || error "multiop failed"
19846
19847         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
19848         pid=$!
19849         sleep 1
19850
19851         $LFS getstripe $DIR/$tfile
19852         kill -USR1 $pid
19853         wait $pid || error "multiop failed"
19854 }
19855 run_test 210 "lfs getstripe does not break leases"
19856
19857 test_212() {
19858         size=`date +%s`
19859         size=$((size % 8192 + 1))
19860         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
19861         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
19862         rm -f $DIR/f212 $DIR/f212.xyz
19863 }
19864 run_test 212 "Sendfile test ============================================"
19865
19866 test_213() {
19867         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
19868         cancel_lru_locks osc
19869         lctl set_param fail_loc=0x8000040f
19870         # generate a read lock
19871         cat $DIR/$tfile > /dev/null
19872         # write to the file, it will try to cancel the above read lock.
19873         cat /etc/hosts >> $DIR/$tfile
19874 }
19875 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
19876
19877 test_214() { # for bug 20133
19878         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
19879         for (( i=0; i < 340; i++ )) ; do
19880                 touch $DIR/$tdir/d214c/a$i
19881         done
19882
19883         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
19884         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
19885         ls $DIR/d214c || error "ls $DIR/d214c failed"
19886         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
19887         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
19888 }
19889 run_test 214 "hash-indexed directory test - bug 20133"
19890
19891 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
19892 create_lnet_proc_files() {
19893         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
19894 }
19895
19896 # counterpart of create_lnet_proc_files
19897 remove_lnet_proc_files() {
19898         rm -f $TMP/lnet_$1.sys
19899 }
19900
19901 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19902 # 3rd arg as regexp for body
19903 check_lnet_proc_stats() {
19904         local l=$(cat "$TMP/lnet_$1" |wc -l)
19905         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
19906
19907         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
19908 }
19909
19910 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
19911 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
19912 # optional and can be regexp for 2nd line (lnet.routes case)
19913 check_lnet_proc_entry() {
19914         local blp=2          # blp stands for 'position of 1st line of body'
19915         [ -z "$5" ] || blp=3 # lnet.routes case
19916
19917         local l=$(cat "$TMP/lnet_$1" |wc -l)
19918         # subtracting one from $blp because the body can be empty
19919         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
19920
19921         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
19922                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
19923
19924         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
19925                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
19926
19927         # bail out if any unexpected line happened
19928         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
19929         [ "$?" != 0 ] || error "$2 misformatted"
19930 }
19931
19932 test_215() { # for bugs 18102, 21079, 21517
19933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19934
19935         local N='(0|[1-9][0-9]*)'       # non-negative numeric
19936         local P='[1-9][0-9]*'           # positive numeric
19937         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
19938         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
19939         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
19940         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
19941
19942         local L1 # regexp for 1st line
19943         local L2 # regexp for 2nd line (optional)
19944         local BR # regexp for the rest (body)
19945
19946         # lnet.stats should look as 11 space-separated non-negative numerics
19947         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
19948         create_lnet_proc_files "stats"
19949         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
19950         remove_lnet_proc_files "stats"
19951
19952         # lnet.routes should look like this:
19953         # Routing disabled/enabled
19954         # net hops priority state router
19955         # where net is a string like tcp0, hops > 0, priority >= 0,
19956         # state is up/down,
19957         # router is a string like 192.168.1.1@tcp2
19958         L1="^Routing (disabled|enabled)$"
19959         L2="^net +hops +priority +state +router$"
19960         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
19961         create_lnet_proc_files "routes"
19962         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
19963         remove_lnet_proc_files "routes"
19964
19965         # lnet.routers should look like this:
19966         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
19967         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
19968         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
19969         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
19970         L1="^ref +rtr_ref +alive +router$"
19971         BR="^$P +$P +(up|down) +$NID$"
19972         create_lnet_proc_files "routers"
19973         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
19974         remove_lnet_proc_files "routers"
19975
19976         # lnet.peers should look like this:
19977         # nid refs state last max rtr min tx min queue
19978         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
19979         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
19980         # numeric (0 or >0 or <0), queue >= 0.
19981         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
19982         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
19983         create_lnet_proc_files "peers"
19984         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
19985         remove_lnet_proc_files "peers"
19986
19987         # lnet.buffers  should look like this:
19988         # pages count credits min
19989         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
19990         L1="^pages +count +credits +min$"
19991         BR="^ +$N +$N +$I +$I$"
19992         create_lnet_proc_files "buffers"
19993         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
19994         remove_lnet_proc_files "buffers"
19995
19996         # lnet.nis should look like this:
19997         # nid status alive refs peer rtr max tx min
19998         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
19999         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
20000         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
20001         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
20002         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
20003         create_lnet_proc_files "nis"
20004         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
20005         remove_lnet_proc_files "nis"
20006
20007         # can we successfully write to lnet.stats?
20008         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
20009 }
20010 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
20011
20012 test_216() { # bug 20317
20013         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20014         remote_ost_nodsh && skip "remote OST with nodsh"
20015
20016         local node
20017         local facets=$(get_facets OST)
20018         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20019
20020         save_lustre_params client "osc.*.contention_seconds" > $p
20021         save_lustre_params $facets \
20022                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
20023         save_lustre_params $facets \
20024                 "ldlm.namespaces.filter-*.contended_locks" >> $p
20025         save_lustre_params $facets \
20026                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
20027         clear_stats osc.*.osc_stats
20028
20029         # agressive lockless i/o settings
20030         do_nodes $(comma_list $(osts_nodes)) \
20031                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
20032                         ldlm.namespaces.filter-*.contended_locks=0 \
20033                         ldlm.namespaces.filter-*.contention_seconds=60"
20034         lctl set_param -n osc.*.contention_seconds=60
20035
20036         $DIRECTIO write $DIR/$tfile 0 10 4096
20037         $CHECKSTAT -s 40960 $DIR/$tfile
20038
20039         # disable lockless i/o
20040         do_nodes $(comma_list $(osts_nodes)) \
20041                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
20042                         ldlm.namespaces.filter-*.contended_locks=32 \
20043                         ldlm.namespaces.filter-*.contention_seconds=0"
20044         lctl set_param -n osc.*.contention_seconds=0
20045         clear_stats osc.*.osc_stats
20046
20047         dd if=/dev/zero of=$DIR/$tfile count=0
20048         $CHECKSTAT -s 0 $DIR/$tfile
20049
20050         restore_lustre_params <$p
20051         rm -f $p
20052         rm $DIR/$tfile
20053 }
20054 run_test 216 "check lockless direct write updates file size and kms correctly"
20055
20056 test_217() { # bug 22430
20057         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20058
20059         local node
20060         local nid
20061
20062         for node in $(nodes_list); do
20063                 nid=$(host_nids_address $node $NETTYPE)
20064                 if [[ $nid = *-* ]] ; then
20065                         echo "lctl ping $(h2nettype $nid)"
20066                         lctl ping $(h2nettype $nid)
20067                 else
20068                         echo "skipping $node (no hyphen detected)"
20069                 fi
20070         done
20071 }
20072 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
20073
20074 test_218() {
20075        # do directio so as not to populate the page cache
20076        log "creating a 10 Mb file"
20077        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
20078        log "starting reads"
20079        dd if=$DIR/$tfile of=/dev/null bs=4096 &
20080        log "truncating the file"
20081        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
20082        log "killing dd"
20083        kill %+ || true # reads might have finished
20084        echo "wait until dd is finished"
20085        wait
20086        log "removing the temporary file"
20087        rm -rf $DIR/$tfile || error "tmp file removal failed"
20088 }
20089 run_test 218 "parallel read and truncate should not deadlock"
20090
20091 test_219() {
20092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20093
20094         # write one partial page
20095         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
20096         # set no grant so vvp_io_commit_write will do sync write
20097         $LCTL set_param fail_loc=0x411
20098         # write a full page at the end of file
20099         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
20100
20101         $LCTL set_param fail_loc=0
20102         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
20103         $LCTL set_param fail_loc=0x411
20104         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
20105
20106         # LU-4201
20107         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
20108         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
20109 }
20110 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
20111
20112 test_220() { #LU-325
20113         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20114         remote_ost_nodsh && skip "remote OST with nodsh"
20115         remote_mds_nodsh && skip "remote MDS with nodsh"
20116         remote_mgs_nodsh && skip "remote MGS with nodsh"
20117
20118         local OSTIDX=0
20119
20120         # create on MDT0000 so the last_id and next_id are correct
20121         mkdir_on_mdt0 $DIR/$tdir
20122         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
20123         OST=${OST%_UUID}
20124
20125         # on the mdt's osc
20126         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
20127         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
20128                         osp.$mdtosc_proc1.prealloc_last_id)
20129         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
20130                         osp.$mdtosc_proc1.prealloc_next_id)
20131
20132         $LFS df -i
20133
20134         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
20135         #define OBD_FAIL_OST_ENOINO              0x229
20136         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
20137         create_pool $FSNAME.$TESTNAME || return 1
20138         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
20139
20140         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
20141
20142         MDSOBJS=$((last_id - next_id))
20143         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
20144
20145         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
20146         echo "OST still has $count kbytes free"
20147
20148         echo "create $MDSOBJS files @next_id..."
20149         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
20150
20151         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20152                         osp.$mdtosc_proc1.prealloc_last_id)
20153         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
20154                         osp.$mdtosc_proc1.prealloc_next_id)
20155
20156         echo "after creation, last_id=$last_id2, next_id=$next_id2"
20157         $LFS df -i
20158
20159         echo "cleanup..."
20160
20161         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
20162         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
20163
20164         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
20165                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
20166         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
20167                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
20168         echo "unlink $MDSOBJS files @$next_id..."
20169         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
20170 }
20171 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
20172
20173 test_221() {
20174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20175
20176         dd if=`which date` of=$MOUNT/date oflag=sync
20177         chmod +x $MOUNT/date
20178
20179         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
20180         $LCTL set_param fail_loc=0x80001401
20181
20182         $MOUNT/date > /dev/null
20183         rm -f $MOUNT/date
20184 }
20185 run_test 221 "make sure fault and truncate race to not cause OOM"
20186
20187 test_222a () {
20188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20189
20190         rm -rf $DIR/$tdir
20191         test_mkdir $DIR/$tdir
20192         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20193         createmany -o $DIR/$tdir/$tfile 10
20194         cancel_lru_locks mdc
20195         cancel_lru_locks osc
20196         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20197         $LCTL set_param fail_loc=0x31a
20198         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
20199         $LCTL set_param fail_loc=0
20200         rm -r $DIR/$tdir
20201 }
20202 run_test 222a "AGL for ls should not trigger CLIO lock failure"
20203
20204 test_222b () {
20205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20206
20207         rm -rf $DIR/$tdir
20208         test_mkdir $DIR/$tdir
20209         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20210         createmany -o $DIR/$tdir/$tfile 10
20211         cancel_lru_locks mdc
20212         cancel_lru_locks osc
20213         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
20214         $LCTL set_param fail_loc=0x31a
20215         rm -r $DIR/$tdir || error "AGL for rmdir failed"
20216         $LCTL set_param fail_loc=0
20217 }
20218 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
20219
20220 test_223 () {
20221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20222
20223         rm -rf $DIR/$tdir
20224         test_mkdir $DIR/$tdir
20225         $LFS setstripe -c 1 -i 0 $DIR/$tdir
20226         createmany -o $DIR/$tdir/$tfile 10
20227         cancel_lru_locks mdc
20228         cancel_lru_locks osc
20229         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
20230         $LCTL set_param fail_loc=0x31b
20231         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
20232         $LCTL set_param fail_loc=0
20233         rm -r $DIR/$tdir
20234 }
20235 run_test 223 "osc reenqueue if without AGL lock granted ======================="
20236
20237 test_224a() { # LU-1039, MRP-303
20238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20239         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
20240         $LCTL set_param fail_loc=0x508
20241         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 conv=fsync
20242         $LCTL set_param fail_loc=0
20243         df $DIR
20244 }
20245 run_test 224a "Don't panic on bulk IO failure"
20246
20247 test_224bd_sub() { # LU-1039, MRP-303
20248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20249         local timeout=$1
20250
20251         shift
20252         dd if=/dev/urandom of=$TMP/$tfile bs=1M count=1
20253
20254         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20255
20256         dd if=$TMP/$tfile of=$DIR/$tfile bs=1M count=1
20257         cancel_lru_locks osc
20258         set_checksums 0
20259         stack_trap "set_checksums $ORIG_CSUM" EXIT
20260         local at_max_saved=0
20261
20262         # adaptive timeouts may prevent seeing the issue
20263         if at_is_enabled; then
20264                 at_max_saved=$(at_max_get mds)
20265                 at_max_set 0 mds client
20266                 stack_trap "at_max_set $at_max_saved mds client" EXIT
20267         fi
20268
20269         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
20270         do_facet ost1 $LCTL set_param fail_val=$timeout fail_loc=0x80000515
20271         dd of=$TMP/$tfile.new if=$DIR/$tfile bs=1M count=1 || "$@"
20272
20273         do_facet ost1 $LCTL set_param fail_loc=0
20274         cmp $TMP/$tfile $TMP/$tfile.new || error "file contents wrong"
20275         df $DIR
20276 }
20277
20278 test_224b() {
20279         test_224bd_sub 3 error "dd failed"
20280 }
20281 run_test 224b "Don't panic on bulk IO failure"
20282
20283 test_224c() { # LU-6441
20284         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20285         remote_mds_nodsh && skip "remote MDS with nodsh"
20286
20287         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
20288         save_writethrough $p
20289         set_cache writethrough on
20290
20291         local pages_per_rpc=$($LCTL get_param osc.*.max_pages_per_rpc)
20292         local at_max=$($LCTL get_param -n at_max)
20293         local timeout=$($LCTL get_param -n timeout)
20294         local test_at="at_max"
20295         local param_at="$FSNAME.sys.at_max"
20296         local test_timeout="timeout"
20297         local param_timeout="$FSNAME.sys.timeout"
20298
20299         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
20300
20301         set_persistent_param_and_check client "$test_at" "$param_at" 0
20302         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
20303
20304         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
20305         do_facet ost1 "$LCTL set_param fail_loc=0x520"
20306         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20307         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
20308         sync
20309         do_facet ost1 "$LCTL set_param fail_loc=0"
20310
20311         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
20312         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
20313                 $timeout
20314
20315         $LCTL set_param -n $pages_per_rpc
20316         restore_lustre_params < $p
20317         rm -f $p
20318 }
20319 run_test 224c "Don't hang if one of md lost during large bulk RPC"
20320
20321 test_224d() { # LU-11169
20322         test_224bd_sub $((TIMEOUT + 2)) error "dd failed"
20323 }
20324 run_test 224d "Don't corrupt data on bulk IO timeout"
20325
20326 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
20327 test_225a () {
20328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20329         if [ -z ${MDSSURVEY} ]; then
20330                 skip_env "mds-survey not found"
20331         fi
20332         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20333                 skip "Need MDS version at least 2.2.51"
20334
20335         local mds=$(facet_host $SINGLEMDS)
20336         local target=$(do_nodes $mds 'lctl dl' |
20337                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20338
20339         local cmd1="file_count=1000 thrhi=4"
20340         local cmd2="dir_count=2 layer=mdd stripe_count=0"
20341         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20342         local cmd="$cmd1 $cmd2 $cmd3"
20343
20344         rm -f ${TMP}/mds_survey*
20345         echo + $cmd
20346         eval $cmd || error "mds-survey with zero-stripe failed"
20347         cat ${TMP}/mds_survey*
20348         rm -f ${TMP}/mds_survey*
20349 }
20350 run_test 225a "Metadata survey sanity with zero-stripe"
20351
20352 test_225b () {
20353         if [ -z ${MDSSURVEY} ]; then
20354                 skip_env "mds-survey not found"
20355         fi
20356         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
20357                 skip "Need MDS version at least 2.2.51"
20358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20359         remote_mds_nodsh && skip "remote MDS with nodsh"
20360         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
20361                 skip_env "Need to mount OST to test"
20362         fi
20363
20364         local mds=$(facet_host $SINGLEMDS)
20365         local target=$(do_nodes $mds 'lctl dl' |
20366                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
20367
20368         local cmd1="file_count=1000 thrhi=4"
20369         local cmd2="dir_count=2 layer=mdd stripe_count=1"
20370         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
20371         local cmd="$cmd1 $cmd2 $cmd3"
20372
20373         rm -f ${TMP}/mds_survey*
20374         echo + $cmd
20375         eval $cmd || error "mds-survey with stripe_count failed"
20376         cat ${TMP}/mds_survey*
20377         rm -f ${TMP}/mds_survey*
20378 }
20379 run_test 225b "Metadata survey sanity with stripe_count = 1"
20380
20381 mcreate_path2fid () {
20382         local mode=$1
20383         local major=$2
20384         local minor=$3
20385         local name=$4
20386         local desc=$5
20387         local path=$DIR/$tdir/$name
20388         local fid
20389         local rc
20390         local fid_path
20391
20392         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
20393                 error "cannot create $desc"
20394
20395         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
20396         rc=$?
20397         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
20398
20399         fid_path=$($LFS fid2path $MOUNT $fid)
20400         rc=$?
20401         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
20402
20403         [ "$path" == "$fid_path" ] ||
20404                 error "fid2path returned $fid_path, expected $path"
20405
20406         echo "pass with $path and $fid"
20407 }
20408
20409 test_226a () {
20410         rm -rf $DIR/$tdir
20411         mkdir -p $DIR/$tdir
20412
20413         mcreate_path2fid 0010666 0 0 fifo "FIFO"
20414         mcreate_path2fid 0020666 1 3 null "character special file (null)"
20415         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
20416         mcreate_path2fid 0040666 0 0 dir "directory"
20417         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
20418         mcreate_path2fid 0100666 0 0 file "regular file"
20419         mcreate_path2fid 0120666 0 0 link "symbolic link"
20420         mcreate_path2fid 0140666 0 0 sock "socket"
20421 }
20422 run_test 226a "call path2fid and fid2path on files of all type"
20423
20424 test_226b () {
20425         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20426
20427         local MDTIDX=1
20428
20429         rm -rf $DIR/$tdir
20430         mkdir -p $DIR/$tdir
20431         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
20432                 error "create remote directory failed"
20433         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
20434         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
20435                                 "character special file (null)"
20436         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
20437                                 "character special file (no device)"
20438         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
20439         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
20440                                 "block special file (loop)"
20441         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
20442         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
20443         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
20444 }
20445 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
20446
20447 test_226c () {
20448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20449         [[ $MDS1_VERSION -ge $(version_code 2.13.55) ]] ||
20450                 skip "Need MDS version at least 2.13.55"
20451
20452         local submnt=/mnt/submnt
20453         local srcfile=/etc/passwd
20454         local dstfile=$submnt/passwd
20455         local path
20456         local fid
20457
20458         rm -rf $DIR/$tdir
20459         rm -rf $submnt
20460         $LFS setdirstripe -c -1 -i 1 $DIR/$tdir ||
20461                 error "create remote directory failed"
20462         mkdir -p $submnt || error "create $submnt failed"
20463         $MOUNT_CMD $MGSNID:/$FSNAME/$tdir $submnt ||
20464                 error "mount $submnt failed"
20465         stack_trap "umount $submnt" EXIT
20466
20467         cp $srcfile $dstfile
20468         fid=$($LFS path2fid $dstfile)
20469         path=$($LFS fid2path $submnt "$fid")
20470         [ "$path" = "$dstfile" ] ||
20471                 error "fid2path $submnt $fid failed ($path != $dstfile)"
20472 }
20473 run_test 226c "call path2fid and fid2path under remote dir with subdir mount"
20474
20475 # LU-1299 Executing or running ldd on a truncated executable does not
20476 # cause an out-of-memory condition.
20477 test_227() {
20478         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20479         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
20480
20481         dd if=$(which date) of=$MOUNT/date bs=1k count=1
20482         chmod +x $MOUNT/date
20483
20484         $MOUNT/date > /dev/null
20485         ldd $MOUNT/date > /dev/null
20486         rm -f $MOUNT/date
20487 }
20488 run_test 227 "running truncated executable does not cause OOM"
20489
20490 # LU-1512 try to reuse idle OI blocks
20491 test_228a() {
20492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20493         remote_mds_nodsh && skip "remote MDS with nodsh"
20494         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20495
20496         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20497         local myDIR=$DIR/$tdir
20498
20499         mkdir -p $myDIR
20500         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20501         $LCTL set_param fail_loc=0x80001002
20502         createmany -o $myDIR/t- 10000
20503         $LCTL set_param fail_loc=0
20504         # The guard is current the largest FID holder
20505         touch $myDIR/guard
20506         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20507                     tr -d '[')
20508         local IDX=$(($SEQ % 64))
20509
20510         do_facet $SINGLEMDS sync
20511         # Make sure journal flushed.
20512         sleep 6
20513         local blk1=$(do_facet $SINGLEMDS \
20514                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20515                      grep Blockcount | awk '{print $4}')
20516
20517         # Remove old files, some OI blocks will become idle.
20518         unlinkmany $myDIR/t- 10000
20519         # Create new files, idle OI blocks should be reused.
20520         createmany -o $myDIR/t- 2000
20521         do_facet $SINGLEMDS sync
20522         # Make sure journal flushed.
20523         sleep 6
20524         local blk2=$(do_facet $SINGLEMDS \
20525                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20526                      grep Blockcount | awk '{print $4}')
20527
20528         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20529 }
20530 run_test 228a "try to reuse idle OI blocks"
20531
20532 test_228b() {
20533         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20534         remote_mds_nodsh && skip "remote MDS with nodsh"
20535         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20536
20537         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20538         local myDIR=$DIR/$tdir
20539
20540         mkdir -p $myDIR
20541         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20542         $LCTL set_param fail_loc=0x80001002
20543         createmany -o $myDIR/t- 10000
20544         $LCTL set_param fail_loc=0
20545         # The guard is current the largest FID holder
20546         touch $myDIR/guard
20547         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20548                     tr -d '[')
20549         local IDX=$(($SEQ % 64))
20550
20551         do_facet $SINGLEMDS sync
20552         # Make sure journal flushed.
20553         sleep 6
20554         local blk1=$(do_facet $SINGLEMDS \
20555                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20556                      grep Blockcount | awk '{print $4}')
20557
20558         # Remove old files, some OI blocks will become idle.
20559         unlinkmany $myDIR/t- 10000
20560
20561         # stop the MDT
20562         stop $SINGLEMDS || error "Fail to stop MDT."
20563         # remount the MDT
20564         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
20565                 error "Fail to start MDT."
20566
20567         client_up || error "Fail to df."
20568         # Create new files, idle OI blocks should be reused.
20569         createmany -o $myDIR/t- 2000
20570         do_facet $SINGLEMDS sync
20571         # Make sure journal flushed.
20572         sleep 6
20573         local blk2=$(do_facet $SINGLEMDS \
20574                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20575                      grep Blockcount | awk '{print $4}')
20576
20577         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20578 }
20579 run_test 228b "idle OI blocks can be reused after MDT restart"
20580
20581 #LU-1881
20582 test_228c() {
20583         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20584         remote_mds_nodsh && skip "remote MDS with nodsh"
20585         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20586
20587         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
20588         local myDIR=$DIR/$tdir
20589
20590         mkdir -p $myDIR
20591         #define OBD_FAIL_SEQ_EXHAUST             0x1002
20592         $LCTL set_param fail_loc=0x80001002
20593         # 20000 files can guarantee there are index nodes in the OI file
20594         createmany -o $myDIR/t- 20000
20595         $LCTL set_param fail_loc=0
20596         # The guard is current the largest FID holder
20597         touch $myDIR/guard
20598         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
20599                     tr -d '[')
20600         local IDX=$(($SEQ % 64))
20601
20602         do_facet $SINGLEMDS sync
20603         # Make sure journal flushed.
20604         sleep 6
20605         local blk1=$(do_facet $SINGLEMDS \
20606                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20607                      grep Blockcount | awk '{print $4}')
20608
20609         # Remove old files, some OI blocks will become idle.
20610         unlinkmany $myDIR/t- 20000
20611         rm -f $myDIR/guard
20612         # The OI file should become empty now
20613
20614         # Create new files, idle OI blocks should be reused.
20615         createmany -o $myDIR/t- 2000
20616         do_facet $SINGLEMDS sync
20617         # Make sure journal flushed.
20618         sleep 6
20619         local blk2=$(do_facet $SINGLEMDS \
20620                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
20621                      grep Blockcount | awk '{print $4}')
20622
20623         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
20624 }
20625 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
20626
20627 test_229() { # LU-2482, LU-3448
20628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20629         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20630         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
20631                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
20632
20633         rm -f $DIR/$tfile
20634
20635         # Create a file with a released layout and stripe count 2.
20636         $MULTIOP $DIR/$tfile H2c ||
20637                 error "failed to create file with released layout"
20638
20639         $LFS getstripe -v $DIR/$tfile
20640
20641         local pattern=$($LFS getstripe -L $DIR/$tfile)
20642         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
20643
20644         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
20645                 error "getstripe"
20646         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
20647         stat $DIR/$tfile || error "failed to stat released file"
20648
20649         chown $RUNAS_ID $DIR/$tfile ||
20650                 error "chown $RUNAS_ID $DIR/$tfile failed"
20651
20652         chgrp $RUNAS_ID $DIR/$tfile ||
20653                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
20654
20655         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
20656         rm $DIR/$tfile || error "failed to remove released file"
20657 }
20658 run_test 229 "getstripe/stat/rm/attr changes work on released files"
20659
20660 test_230a() {
20661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20662         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20663         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20664                 skip "Need MDS version at least 2.11.52"
20665
20666         local MDTIDX=1
20667
20668         test_mkdir $DIR/$tdir
20669         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
20670         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
20671         [ $mdt_idx -ne 0 ] &&
20672                 error "create local directory on wrong MDT $mdt_idx"
20673
20674         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
20675                         error "create remote directory failed"
20676         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
20677         [ $mdt_idx -ne $MDTIDX ] &&
20678                 error "create remote directory on wrong MDT $mdt_idx"
20679
20680         createmany -o $DIR/$tdir/test_230/t- 10 ||
20681                 error "create files on remote directory failed"
20682         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
20683         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
20684         rm -r $DIR/$tdir || error "unlink remote directory failed"
20685 }
20686 run_test 230a "Create remote directory and files under the remote directory"
20687
20688 test_230b() {
20689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20690         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20691         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20692                 skip "Need MDS version at least 2.11.52"
20693
20694         local MDTIDX=1
20695         local mdt_index
20696         local i
20697         local file
20698         local pid
20699         local stripe_count
20700         local migrate_dir=$DIR/$tdir/migrate_dir
20701         local other_dir=$DIR/$tdir/other_dir
20702
20703         test_mkdir $DIR/$tdir
20704         test_mkdir -i0 -c1 $migrate_dir
20705         test_mkdir -i0 -c1 $other_dir
20706         for ((i=0; i<10; i++)); do
20707                 mkdir -p $migrate_dir/dir_${i}
20708                 createmany -o $migrate_dir/dir_${i}/f 10 ||
20709                         error "create files under remote dir failed $i"
20710         done
20711
20712         cp /etc/passwd $migrate_dir/$tfile
20713         cp /etc/passwd $other_dir/$tfile
20714         chattr +SAD $migrate_dir
20715         chattr +SAD $migrate_dir/$tfile
20716
20717         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20718         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20719         local old_dir_mode=$(stat -c%f $migrate_dir)
20720         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
20721
20722         mkdir -p $migrate_dir/dir_default_stripe2
20723         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
20724         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
20725
20726         mkdir -p $other_dir
20727         ln $migrate_dir/$tfile $other_dir/luna
20728         ln $migrate_dir/$tfile $migrate_dir/sofia
20729         ln $other_dir/$tfile $migrate_dir/david
20730         ln -s $migrate_dir/$tfile $other_dir/zachary
20731         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
20732         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
20733
20734         local len
20735         local lnktgt
20736
20737         # inline symlink
20738         for len in 58 59 60; do
20739                 lnktgt=$(str_repeat 'l' $len)
20740                 touch $migrate_dir/$lnktgt
20741                 ln -s $lnktgt $migrate_dir/${len}char_ln
20742         done
20743
20744         # PATH_MAX
20745         for len in 4094 4095; do
20746                 lnktgt=$(str_repeat 'l' $len)
20747                 ln -s $lnktgt $migrate_dir/${len}char_ln
20748         done
20749
20750         # NAME_MAX
20751         for len in 254 255; do
20752                 touch $migrate_dir/$(str_repeat 'l' $len)
20753         done
20754
20755         $LFS migrate -m $MDTIDX $migrate_dir ||
20756                 error "fails on migrating remote dir to MDT1"
20757
20758         echo "migratate to MDT1, then checking.."
20759         for ((i = 0; i < 10; i++)); do
20760                 for file in $(find $migrate_dir/dir_${i}); do
20761                         mdt_index=$($LFS getstripe -m $file)
20762                         # broken symlink getstripe will fail
20763                         [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20764                                 error "$file is not on MDT${MDTIDX}"
20765                 done
20766         done
20767
20768         # the multiple link file should still in MDT0
20769         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
20770         [ $mdt_index == 0 ] ||
20771                 error "$file is not on MDT${MDTIDX}"
20772
20773         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20774         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20775                 error " expect $old_dir_flag get $new_dir_flag"
20776
20777         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20778         [ "$old_file_flag" = "$new_file_flag" ] ||
20779                 error " expect $old_file_flag get $new_file_flag"
20780
20781         local new_dir_mode=$(stat -c%f $migrate_dir)
20782         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20783                 error "expect mode $old_dir_mode get $new_dir_mode"
20784
20785         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20786         [ "$old_file_mode" = "$new_file_mode" ] ||
20787                 error "expect mode $old_file_mode get $new_file_mode"
20788
20789         diff /etc/passwd $migrate_dir/$tfile ||
20790                 error "$tfile different after migration"
20791
20792         diff /etc/passwd $other_dir/luna ||
20793                 error "luna different after migration"
20794
20795         diff /etc/passwd $migrate_dir/sofia ||
20796                 error "sofia different after migration"
20797
20798         diff /etc/passwd $migrate_dir/david ||
20799                 error "david different after migration"
20800
20801         diff /etc/passwd $other_dir/zachary ||
20802                 error "zachary different after migration"
20803
20804         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20805                 error "${tfile}_ln different after migration"
20806
20807         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20808                 error "${tfile}_ln_other different after migration"
20809
20810         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
20811         [ $stripe_count = 2 ] ||
20812                 error "dir strpe_count $d != 2 after migration."
20813
20814         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
20815         [ $stripe_count = 2 ] ||
20816                 error "file strpe_count $d != 2 after migration."
20817
20818         #migrate back to MDT0
20819         MDTIDX=0
20820
20821         $LFS migrate -m $MDTIDX $migrate_dir ||
20822                 error "fails on migrating remote dir to MDT0"
20823
20824         echo "migrate back to MDT0, checking.."
20825         for file in $(find $migrate_dir); do
20826                 mdt_index=$($LFS getstripe -m $file)
20827                 [ $mdt_index -ne $MDTIDX ] && stat -L $file &&
20828                         error "$file is not on MDT${MDTIDX}"
20829         done
20830
20831         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
20832         [ "$old_dir_flag" = "$new_dir_flag" ] ||
20833                 error " expect $old_dir_flag get $new_dir_flag"
20834
20835         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
20836         [ "$old_file_flag" = "$new_file_flag" ] ||
20837                 error " expect $old_file_flag get $new_file_flag"
20838
20839         local new_dir_mode=$(stat -c%f $migrate_dir)
20840         [ "$old_dir_mode" = "$new_dir_mode" ] ||
20841                 error "expect mode $old_dir_mode get $new_dir_mode"
20842
20843         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
20844         [ "$old_file_mode" = "$new_file_mode" ] ||
20845                 error "expect mode $old_file_mode get $new_file_mode"
20846
20847         diff /etc/passwd ${migrate_dir}/$tfile ||
20848                 error "$tfile different after migration"
20849
20850         diff /etc/passwd ${other_dir}/luna ||
20851                 error "luna different after migration"
20852
20853         diff /etc/passwd ${migrate_dir}/sofia ||
20854                 error "sofia different after migration"
20855
20856         diff /etc/passwd ${other_dir}/zachary ||
20857                 error "zachary different after migration"
20858
20859         diff /etc/passwd $migrate_dir/${tfile}_ln ||
20860                 error "${tfile}_ln different after migration"
20861
20862         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
20863                 error "${tfile}_ln_other different after migration"
20864
20865         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
20866         [ $stripe_count = 2 ] ||
20867                 error "dir strpe_count $d != 2 after migration."
20868
20869         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
20870         [ $stripe_count = 2 ] ||
20871                 error "file strpe_count $d != 2 after migration."
20872
20873         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20874 }
20875 run_test 230b "migrate directory"
20876
20877 test_230c() {
20878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20879         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20880         remote_mds_nodsh && skip "remote MDS with nodsh"
20881         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20882                 skip "Need MDS version at least 2.11.52"
20883
20884         local MDTIDX=1
20885         local total=3
20886         local mdt_index
20887         local file
20888         local migrate_dir=$DIR/$tdir/migrate_dir
20889
20890         #If migrating directory fails in the middle, all entries of
20891         #the directory is still accessiable.
20892         test_mkdir $DIR/$tdir
20893         test_mkdir -i0 -c1 $migrate_dir
20894         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
20895         stat $migrate_dir
20896         createmany -o $migrate_dir/f $total ||
20897                 error "create files under ${migrate_dir} failed"
20898
20899         # fail after migrating top dir, and this will fail only once, so the
20900         # first sub file migration will fail (currently f3), others succeed.
20901         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
20902         do_facet mds1 lctl set_param fail_loc=0x1801
20903         local t=$(ls $migrate_dir | wc -l)
20904         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
20905                 error "migrate should fail"
20906         local u=$(ls $migrate_dir | wc -l)
20907         [ "$u" == "$t" ] || error "$u != $t during migration"
20908
20909         # add new dir/file should succeed
20910         mkdir $migrate_dir/dir ||
20911                 error "mkdir failed under migrating directory"
20912         touch $migrate_dir/file ||
20913                 error "create file failed under migrating directory"
20914
20915         # add file with existing name should fail
20916         for file in $migrate_dir/f*; do
20917                 stat $file > /dev/null || error "stat $file failed"
20918                 $OPENFILE -f O_CREAT:O_EXCL $file &&
20919                         error "open(O_CREAT|O_EXCL) $file should fail"
20920                 $MULTIOP $file m && error "create $file should fail"
20921                 touch $DIR/$tdir/remote_dir/$tfile ||
20922                         error "touch $tfile failed"
20923                 ln $DIR/$tdir/remote_dir/$tfile $file &&
20924                         error "link $file should fail"
20925                 mdt_index=$($LFS getstripe -m $file)
20926                 if [ $mdt_index == 0 ]; then
20927                         # file failed to migrate is not allowed to rename to
20928                         mv $DIR/$tdir/remote_dir/$tfile $file &&
20929                                 error "rename to $file should fail"
20930                 else
20931                         mv $DIR/$tdir/remote_dir/$tfile $file ||
20932                                 error "rename to $file failed"
20933                 fi
20934                 echo hello >> $file || error "write $file failed"
20935         done
20936
20937         # resume migration with different options should fail
20938         $LFS migrate -m 0 $migrate_dir &&
20939                 error "migrate -m 0 $migrate_dir should fail"
20940
20941         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
20942                 error "migrate -c 2 $migrate_dir should fail"
20943
20944         # resume migration should succeed
20945         $LFS migrate -m $MDTIDX $migrate_dir ||
20946                 error "migrate $migrate_dir failed"
20947
20948         echo "Finish migration, then checking.."
20949         for file in $(find $migrate_dir); do
20950                 mdt_index=$($LFS getstripe -m $file)
20951                 [ $mdt_index == $MDTIDX ] ||
20952                         error "$file is not on MDT${MDTIDX}"
20953         done
20954
20955         rm -rf $DIR/$tdir || error "rm dir failed after migration"
20956 }
20957 run_test 230c "check directory accessiblity if migration failed"
20958
20959 test_230d() {
20960         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20961         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20962         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20963                 skip "Need MDS version at least 2.11.52"
20964         # LU-11235
20965         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
20966
20967         local migrate_dir=$DIR/$tdir/migrate_dir
20968         local old_index
20969         local new_index
20970         local old_count
20971         local new_count
20972         local new_hash
20973         local mdt_index
20974         local i
20975         local j
20976
20977         old_index=$((RANDOM % MDSCOUNT))
20978         old_count=$((MDSCOUNT - old_index))
20979         new_index=$((RANDOM % MDSCOUNT))
20980         new_count=$((MDSCOUNT - new_index))
20981         new_hash=1 # for all_char
20982
20983         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
20984         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
20985
20986         test_mkdir $DIR/$tdir
20987         test_mkdir -i $old_index -c $old_count $migrate_dir
20988
20989         for ((i=0; i<100; i++)); do
20990                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
20991                 createmany -o $migrate_dir/dir_${i}/f 100 ||
20992                         error "create files under remote dir failed $i"
20993         done
20994
20995         echo -n "Migrate from MDT$old_index "
20996         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
20997         echo -n "to MDT$new_index"
20998         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
20999         echo
21000
21001         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
21002         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
21003                 error "migrate remote dir error"
21004
21005         echo "Finish migration, then checking.."
21006         for file in $(find $migrate_dir -maxdepth 1); do
21007                 mdt_index=$($LFS getstripe -m $file)
21008                 if [ $mdt_index -lt $new_index ] ||
21009                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
21010                         error "$file is on MDT$mdt_index"
21011                 fi
21012         done
21013
21014         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21015 }
21016 run_test 230d "check migrate big directory"
21017
21018 test_230e() {
21019         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21020         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21021         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21022                 skip "Need MDS version at least 2.11.52"
21023
21024         local i
21025         local j
21026         local a_fid
21027         local b_fid
21028
21029         mkdir_on_mdt0 $DIR/$tdir
21030         mkdir $DIR/$tdir/migrate_dir
21031         mkdir $DIR/$tdir/other_dir
21032         touch $DIR/$tdir/migrate_dir/a
21033         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
21034         ls $DIR/$tdir/other_dir
21035
21036         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21037                 error "migrate dir fails"
21038
21039         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21040         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21041
21042         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21043         [ $mdt_index == 0 ] || error "a is not on MDT0"
21044
21045         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
21046                 error "migrate dir fails"
21047
21048         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
21049         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
21050
21051         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21052         [ $mdt_index == 1 ] || error "a is not on MDT1"
21053
21054         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
21055         [ $mdt_index == 1 ] || error "b is not on MDT1"
21056
21057         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21058         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
21059
21060         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
21061
21062         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21063 }
21064 run_test 230e "migrate mulitple local link files"
21065
21066 test_230f() {
21067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21069         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21070                 skip "Need MDS version at least 2.11.52"
21071
21072         local a_fid
21073         local ln_fid
21074
21075         mkdir -p $DIR/$tdir
21076         mkdir $DIR/$tdir/migrate_dir
21077         $LFS mkdir -i1 $DIR/$tdir/other_dir
21078         touch $DIR/$tdir/migrate_dir/a
21079         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
21080         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
21081         ls $DIR/$tdir/other_dir
21082
21083         # a should be migrated to MDT1, since no other links on MDT0
21084         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21085                 error "#1 migrate dir fails"
21086         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
21087         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
21088         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21089         [ $mdt_index == 1 ] || error "a is not on MDT1"
21090
21091         # a should stay on MDT1, because it is a mulitple link file
21092         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21093                 error "#2 migrate dir fails"
21094         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21095         [ $mdt_index == 1 ] || error "a is not on MDT1"
21096
21097         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
21098                 error "#3 migrate dir fails"
21099
21100         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
21101         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
21102         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
21103
21104         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
21105         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
21106
21107         # a should be migrated to MDT0, since no other links on MDT1
21108         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
21109                 error "#4 migrate dir fails"
21110         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
21111         [ $mdt_index == 0 ] || error "a is not on MDT0"
21112
21113         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21114 }
21115 run_test 230f "migrate mulitple remote link files"
21116
21117 test_230g() {
21118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21120         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21121                 skip "Need MDS version at least 2.11.52"
21122
21123         mkdir -p $DIR/$tdir/migrate_dir
21124
21125         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
21126                 error "migrating dir to non-exist MDT succeeds"
21127         true
21128 }
21129 run_test 230g "migrate dir to non-exist MDT"
21130
21131 test_230h() {
21132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21133         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21134         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21135                 skip "Need MDS version at least 2.11.52"
21136
21137         local mdt_index
21138
21139         mkdir -p $DIR/$tdir/migrate_dir
21140
21141         $LFS migrate -m1 $DIR &&
21142                 error "migrating mountpoint1 should fail"
21143
21144         $LFS migrate -m1 $DIR/$tdir/.. &&
21145                 error "migrating mountpoint2 should fail"
21146
21147         # same as mv
21148         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
21149                 error "migrating $tdir/migrate_dir/.. should fail"
21150
21151         true
21152 }
21153 run_test 230h "migrate .. and root"
21154
21155 test_230i() {
21156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21157         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21158         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21159                 skip "Need MDS version at least 2.11.52"
21160
21161         mkdir -p $DIR/$tdir/migrate_dir
21162
21163         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
21164                 error "migration fails with a tailing slash"
21165
21166         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
21167                 error "migration fails with two tailing slashes"
21168 }
21169 run_test 230i "lfs migrate -m tolerates trailing slashes"
21170
21171 test_230j() {
21172         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21173         [ $MDS1_VERSION -lt $(version_code 2.13.52) ] &&
21174                 skip "Need MDS version at least 2.11.52"
21175
21176         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21177         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
21178                 error "create $tfile failed"
21179         cat /etc/passwd > $DIR/$tdir/$tfile
21180
21181         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21182
21183         cmp /etc/passwd $DIR/$tdir/$tfile ||
21184                 error "DoM file mismatch after migration"
21185 }
21186 run_test 230j "DoM file data not changed after dir migration"
21187
21188 test_230k() {
21189         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
21190         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21191                 skip "Need MDS version at least 2.11.56"
21192
21193         local total=20
21194         local files_on_starting_mdt=0
21195
21196         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
21197         $LFS getdirstripe $DIR/$tdir
21198         for i in $(seq $total); do
21199                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
21200                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21201                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21202         done
21203
21204         echo "$files_on_starting_mdt files on MDT0"
21205
21206         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
21207         $LFS getdirstripe $DIR/$tdir
21208
21209         files_on_starting_mdt=0
21210         for i in $(seq $total); do
21211                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21212                         error "file $tfile.$i mismatch after migration"
21213                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
21214                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21215         done
21216
21217         echo "$files_on_starting_mdt files on MDT1 after migration"
21218         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
21219
21220         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
21221         $LFS getdirstripe $DIR/$tdir
21222
21223         files_on_starting_mdt=0
21224         for i in $(seq $total); do
21225                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
21226                         error "file $tfile.$i mismatch after 2nd migration"
21227                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
21228                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
21229         done
21230
21231         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
21232         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
21233
21234         true
21235 }
21236 run_test 230k "file data not changed after dir migration"
21237
21238 test_230l() {
21239         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21240         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21241                 skip "Need MDS version at least 2.11.56"
21242
21243         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
21244         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
21245                 error "create files under remote dir failed $i"
21246         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
21247 }
21248 run_test 230l "readdir between MDTs won't crash"
21249
21250 test_230m() {
21251         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21252         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21253                 skip "Need MDS version at least 2.11.56"
21254
21255         local MDTIDX=1
21256         local mig_dir=$DIR/$tdir/migrate_dir
21257         local longstr="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
21258         local shortstr="b"
21259         local val
21260
21261         echo "Creating files and dirs with xattrs"
21262         test_mkdir $DIR/$tdir
21263         test_mkdir -i0 -c1 $mig_dir
21264         mkdir $mig_dir/dir
21265         setfattr -n user.attr1 -v $longstr $mig_dir/dir ||
21266                 error "cannot set xattr attr1 on dir"
21267         setfattr -n user.attr2 -v $shortstr $mig_dir/dir ||
21268                 error "cannot set xattr attr2 on dir"
21269         touch $mig_dir/dir/f0
21270         setfattr -n user.attr1 -v $longstr $mig_dir/dir/f0 ||
21271                 error "cannot set xattr attr1 on file"
21272         setfattr -n user.attr2 -v $shortstr $mig_dir/dir/f0 ||
21273                 error "cannot set xattr attr2 on file"
21274         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21275         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21276         [ "$val" = $longstr ] || error "xattr attr1 not set properly on dir"
21277         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21278         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on dir"
21279         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21280         [ "$val" = $longstr ] || error "xattr attr1 not set properly on file"
21281         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21282         [ "$val" = $shortstr ] || error "xattr attr2 not set properly on file"
21283
21284         echo "Migrating to MDT1"
21285         $LFS migrate -m $MDTIDX $mig_dir ||
21286                 error "fails on migrating dir to MDT1"
21287
21288         sync ; sync ; echo 3 > /proc/sys/vm/drop_caches
21289         echo "Checking xattrs"
21290         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir 2>/dev/null)
21291         [ "$val" = $longstr ] ||
21292                 error "expecting xattr1 $longstr on dir, found $val"
21293         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir 2>/dev/null)
21294         [ "$val" = $shortstr ] ||
21295                 error "expecting xattr2 $shortstr on dir, found $val"
21296         val=$(getfattr --only-values -n user.attr1 $mig_dir/dir/f0 2>/dev/null)
21297         [ "$val" = $longstr ] ||
21298                 error "expecting xattr1 $longstr on file, found $val"
21299         val=$(getfattr --only-values -n user.attr2 $mig_dir/dir/f0 2>/dev/null)
21300         [ "$val" = $shortstr ] ||
21301                 error "expecting xattr2 $shortstr on file, found $val"
21302 }
21303 run_test 230m "xattrs not changed after dir migration"
21304
21305 test_230n() {
21306         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21307         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
21308                 skip "Need MDS version at least 2.13.53"
21309
21310         $LFS mkdir -i 0 $DIR/$tdir || error "mkdir $tdir failed"
21311         cat /etc/hosts > $DIR/$tdir/$tfile
21312         $LFS mirror extend -N1 $DIR/$tdir/$tfile || error "Mirroring failed"
21313         $LFS migrate -m 1 $DIR/$tdir || error "Migration failed"
21314
21315         cmp /etc/hosts $DIR/$tdir/$tfile ||
21316                 error "File data mismatch after migration"
21317 }
21318 run_test 230n "Dir migration with mirrored file"
21319
21320 test_230o() {
21321         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
21322         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
21323                 skip "Need MDS version at least 2.13.52"
21324
21325         local mdts=$(comma_list $(mdts_nodes))
21326         local timeout=100
21327         local restripe_status
21328         local delta
21329         local i
21330
21331         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21332
21333         # in case "crush" hash type is not set
21334         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21335
21336         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21337                            mdt.*MDT0000.enable_dir_restripe)
21338         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21339         stack_trap "do_nodes $mdts $LCTL set_param \
21340                     mdt.*.enable_dir_restripe=$restripe_status"
21341
21342         mkdir $DIR/$tdir
21343         createmany -m $DIR/$tdir/f 100 ||
21344                 error "create files under remote dir failed $i"
21345         createmany -d $DIR/$tdir/d 100 ||
21346                 error "create dirs under remote dir failed $i"
21347
21348         for i in $(seq 2 $MDSCOUNT); do
21349                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21350                 $LFS setdirstripe -c $i $DIR/$tdir ||
21351                         error "split -c $i $tdir failed"
21352                 wait_update $HOSTNAME \
21353                         "$LFS getdirstripe -H $DIR/$tdir" "crush" $timeout ||
21354                         error "dir split not finished"
21355                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21356                         awk '/migrate/ {sum += $2} END { print sum }')
21357                 echo "$delta migrated when dir split $((i - 1)) to $i stripes"
21358                 # delta is around total_files/stripe_count
21359                 (( $delta < 200 / (i - 1) + 4 )) ||
21360                         error "$delta files migrated >= $((200 / (i - 1) + 4))"
21361         done
21362 }
21363 run_test 230o "dir split"
21364
21365 test_230p() {
21366         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21367         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21368                 skip "Need MDS version at least 2.13.52"
21369
21370         local mdts=$(comma_list $(mdts_nodes))
21371         local timeout=100
21372         local restripe_status
21373         local delta
21374         local c
21375
21376         [[ $mds1_FSTYPE == zfs ]] && timeout=300
21377
21378         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21379
21380         restripe_status=$(do_facet mds1 $LCTL get_param -n \
21381                            mdt.*MDT0000.enable_dir_restripe)
21382         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=1"
21383         stack_trap "do_nodes $mdts $LCTL set_param \
21384                     mdt.*.enable_dir_restripe=$restripe_status"
21385
21386         test_mkdir -c $MDSCOUNT -H crush $DIR/$tdir
21387         createmany -m $DIR/$tdir/f 100 ||
21388                 error "create files under remote dir failed"
21389         createmany -d $DIR/$tdir/d 100 ||
21390                 error "create dirs under remote dir failed"
21391
21392         for c in $(seq $((MDSCOUNT - 1)) -1 1); do
21393                 local mdt_hash="crush"
21394
21395                 do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear >/dev/null"
21396                 $LFS setdirstripe -c $c $DIR/$tdir ||
21397                         error "split -c $c $tdir failed"
21398                 if (( MDS1_VERSION >= $(version_code 2.14.51) )); then
21399                         mdt_hash="$mdt_hash,fixed"
21400                 elif [ $c -eq 1 ]; then
21401                         mdt_hash="none"
21402                 fi
21403                 wait_update $HOSTNAME \
21404                         "$LFS getdirstripe -H $DIR/$tdir" $mdt_hash $timeout ||
21405                         error "dir merge not finished"
21406                 delta=$(do_nodes $mdts "lctl get_param -n mdt.*MDT*.md_stats" |
21407                         awk '/migrate/ {sum += $2} END { print sum }')
21408                 echo "$delta migrated when dir merge $((c + 1)) to $c stripes"
21409                 # delta is around total_files/stripe_count
21410                 (( delta < 200 / c + 4 )) ||
21411                         error "$delta files migrated >= $((200 / c + 4))"
21412         done
21413 }
21414 run_test 230p "dir merge"
21415
21416 test_230q() {
21417         (( MDSCOUNT > 1)) || skip "needs >= 2 MDTs"
21418         (( MDS1_VERSION >= $(version_code 2.13.52) )) ||
21419                 skip "Need MDS version at least 2.13.52"
21420
21421         local mdts=$(comma_list $(mdts_nodes))
21422         local saved_threshold=$(do_facet mds1 \
21423                         $LCTL get_param -n mdt.*-MDT0000.dir_split_count)
21424         local saved_delta=$(do_facet mds1 \
21425                         $LCTL get_param -n mdt.*-MDT0000.dir_split_delta)
21426         local threshold=100
21427         local delta=2
21428         local total=0
21429         local stripe_count=0
21430         local stripe_index
21431         local nr_files
21432         local create
21433
21434         # test with fewer files on ZFS
21435         [ "$mds1_FSTYPE" == "zfs" ] && threshold=40
21436
21437         stack_trap "do_nodes $mdts $LCTL set_param \
21438                     mdt.*.dir_split_count=$saved_threshold"
21439         stack_trap "do_nodes $mdts $LCTL set_param \
21440                     mdt.*.dir_split_delta=$saved_delta"
21441         stack_trap "do_nodes $mdts $LCTL set_param mdt.*.dir_restripe_nsonly=1"
21442         do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_auto_split=1"
21443         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_count=$threshold"
21444         do_nodes $mdts "$LCTL set_param mdt.*.dir_split_delta=$delta"
21445         do_nodes $mdts "$LCTL set_param mdt.*.dir_restripe_nsonly=0"
21446         do_nodes $mdts "$LCTL set_param lod.*.mdt_hash=crush"
21447
21448         $LFS mkdir -i -1 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
21449         stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
21450
21451         create=$((threshold * 3 / 2))
21452         while [ $stripe_count -lt $MDSCOUNT ]; do
21453                 createmany -m $DIR/$tdir/f $total $create ||
21454                         error "create sub files failed"
21455                 stat $DIR/$tdir > /dev/null
21456                 total=$((total + create))
21457                 stripe_count=$((stripe_count + delta))
21458                 [ $stripe_count -gt $MDSCOUNT ] && stripe_count=$MDSCOUNT
21459
21460                 wait_update $HOSTNAME \
21461                         "$LFS getdirstripe -c $DIR/$tdir" "$stripe_count" 40 ||
21462                         error "stripe count $($LFS getdirstripe -c $DIR/$tdir) != $stripe_count"
21463
21464                 wait_update $HOSTNAME \
21465                         "$LFS getdirstripe -H $DIR/$tdir" "crush" 200 ||
21466                         error "stripe hash $($LFS getdirstripe -H $DIR/$tdir) != crush"
21467
21468                 nr_files=$($LFS find -m 1 $DIR/$tdir | grep -c -w $stripe_index)
21469                 echo "$nr_files/$total files on MDT$stripe_index after split"
21470                 # allow 10% margin of imbalance with crush hash
21471                 (( $nr_files <= $total / $stripe_count + $create / 10)) ||
21472                         error "$nr_files files on MDT$stripe_index after split"
21473
21474                 nr_files=$($LFS find -type f $DIR/$tdir | wc -l)
21475                 [ $nr_files -eq $total ] ||
21476                         error "total sub files $nr_files != $total"
21477         done
21478
21479         (( MDS1_VERSION >= $(version_code 2.14.51) )) || return 0
21480
21481         echo "fixed layout directory won't auto split"
21482         $LFS migrate -m 0 $DIR/$tdir || error "migrate $tdir failed"
21483         wait_update $HOSTNAME "$LFS getdirstripe -H $DIR/$tdir" "crush,fixed" \
21484                 10 || error "stripe hash $($LFS getdirstripe -H $DIR/$tdir)"
21485         wait_update $HOSTNAME "$LFS getdirstripe -c $DIR/$tdir" 1 10 ||
21486                 error "stripe count $($LFS getdirstripe -c $DIR/$tdir)"
21487 }
21488 run_test 230q "dir auto split"
21489
21490 test_230r() {
21491         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
21492         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21493         [[ $MDS1_VERSION -ge $(version_code 2.13.54) ]] ||
21494                 skip "Need MDS version at least 2.13.54"
21495
21496         # maximum amount of local locks:
21497         # parent striped dir - 2 locks
21498         # new stripe in parent to migrate to - 1 lock
21499         # source and target - 2 locks
21500         # Total 5 locks for regular file
21501         mkdir -p $DIR/$tdir
21502         $LFS mkdir -i1 -c2 $DIR/$tdir/dir1
21503         touch $DIR/$tdir/dir1/eee
21504
21505         # create 4 hardlink for 4 more locks
21506         # Total: 9 locks > RS_MAX_LOCKS (8)
21507         $LFS mkdir -i1 -c1 $DIR/$tdir/dir2
21508         $LFS mkdir -i1 -c1 $DIR/$tdir/dir3
21509         $LFS mkdir -i1 -c1 $DIR/$tdir/dir4
21510         $LFS mkdir -i1 -c1 $DIR/$tdir/dir5
21511         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir2/eee
21512         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir3/eee
21513         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir4/eee
21514         ln $DIR/$tdir/dir1/eee $DIR/$tdir/dir5/eee
21515
21516         cancel_lru_locks mdc
21517
21518         $LFS migrate -m1 -c1 $DIR/$tdir/dir1 ||
21519                 error "migrate dir fails"
21520
21521         rm -rf $DIR/$tdir || error "rm dir failed after migration"
21522 }
21523 run_test 230r "migrate with too many local locks"
21524
21525 test_230s() {
21526         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
21527                 skip "Need MDS version at least 2.14.52"
21528
21529         local mdts=$(comma_list $(mdts_nodes))
21530         local restripe_status=$(do_facet mds1 $LCTL get_param -n \
21531                                 mdt.*MDT0000.enable_dir_restripe)
21532
21533         stack_trap "do_nodes $mdts $LCTL set_param \
21534                     mdt.*.enable_dir_restripe=$restripe_status"
21535
21536         local st
21537         for st in 0 1; do
21538                 do_nodes $mdts "$LCTL set_param mdt.*.enable_dir_restripe=$st"
21539                 test_mkdir $DIR/$tdir
21540                 $LFS mkdir $DIR/$tdir |& grep "File exists" ||
21541                         error "$LFS mkdir should return EEXIST if target exists"
21542                 rmdir $DIR/$tdir
21543         done
21544 }
21545 run_test 230s "lfs mkdir should return -EEXIST if target exists"
21546
21547 test_230t()
21548 {
21549         [[ $MDSCOUNT -ge 2 ]] || skip_env "needs >= 2 MDTs"
21550         [[ $MDS1_VERSION -ge $(version_code 2.14.50) ]] ||
21551                 skip "Need MDS version at least 2.14.50"
21552
21553         test_mkdir $DIR/$tdir || error "mkdir $tdir failed"
21554         test_mkdir $DIR/$tdir/subdir || error "mkdir subdir failed"
21555         $LFS project -p 1 -s $DIR/$tdir ||
21556                 error "set $tdir project id failed"
21557         $LFS project -p 2 -s $DIR/$tdir/subdir ||
21558                 error "set subdir project id failed"
21559         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir || error "migrate failed"
21560 }
21561 run_test 230t "migrate directory with project ID set"
21562
21563 test_230u()
21564 {
21565         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21566         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21567                 skip "Need MDS version at least 2.14.53"
21568
21569         local count
21570
21571         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
21572         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21573         $LFS migrate -m -1 $DIR/$tdir/sub{0..99} || error "migrate sub failed"
21574         for i in $(seq 0 $((MDSCOUNT - 1))); do
21575                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21576                 echo "$count dirs migrated to MDT$i"
21577         done
21578         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21579         (( count >= MDSCOUNT - 1 )) || error "dirs migrated to $count MDTs"
21580 }
21581 run_test 230u "migrate directory by QOS"
21582
21583 test_230v()
21584 {
21585         (( MDSCOUNT > 3 )) || skip_env "needs >= 4 MDTs"
21586         (( MDS1_VERSION >= $(version_code 2.14.53) )) ||
21587                 skip "Need MDS version at least 2.14.53"
21588
21589         local count
21590
21591         mkdir $DIR/$tdir || error "mkdir $tdir failed"
21592         mkdir $DIR/$tdir/sub{0..99} || error "mkdir sub failed"
21593         $LFS migrate -m 0,2,1 $DIR/$tdir || error "migrate $tdir failed"
21594         for i in $(seq 0 $((MDSCOUNT - 1))); do
21595                 count=$($LFS getstripe -m $DIR/$tdir/sub* | grep -c ^$i)
21596                 echo "$count subdirs migrated to MDT$i"
21597                 (( i == 3 )) && (( count > 0 )) &&
21598                         error "subdir shouldn't be migrated to MDT3"
21599         done
21600         count=$($LFS getstripe -m $DIR/$tdir/sub* | sort -u | wc -l)
21601         (( count == 3 )) || error "dirs migrated to $count MDTs"
21602 }
21603 run_test 230v "subdir migrated to the MDT where its parent is located"
21604
21605 test_230w() {
21606         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21607         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21608                 skip "Need MDS version at least 2.15.0"
21609
21610         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21611         createmany -o $DIR/$tdir/f 10 || error "create files failed"
21612         createmany -d $DIR/$tdir/d 10 || error "create dirs failed"
21613
21614         $LFS migrate -m 1 -c $MDSCOUNT -d $DIR/$tdir ||
21615                 error "migrate failed"
21616
21617         (( $($LFS getdirstripe -c $DIR/$tdir) == MDSCOUNT )) ||
21618                 error "$tdir stripe count mismatch"
21619
21620         for i in $(seq 0 9); do
21621                 (( $($LFS getdirstripe -c $DIR/$tdir/d$i) == 0 )) ||
21622                         error "d$i is striped"
21623         done
21624 }
21625 run_test 230w "non-recursive mode dir migration"
21626
21627 test_230x() {
21628         (( MDSCOUNT > 1 )) || skip "needs >= 2 MDTs"
21629         (( MDS1_VERSION >= $(version_code 2.15.0) )) ||
21630                 skip "Need MDS version at least 2.15.0"
21631
21632         mkdir -p $DIR/$tdir || error "mkdir failed"
21633         createmany -d $DIR/$tdir/sub 100 || error "createmany failed"
21634
21635         local mdt_name=$(mdtname_from_index 0)
21636         local low=$(do_facet mds2 $LCTL get_param -n \
21637                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low)
21638         local high=$(do_facet mds2 $LCTL get_param -n \
21639                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high)
21640         local ffree=$($LFS df -i $MOUNT | awk "/$mdt_name/ { print \$4 }")
21641         local maxage=$(do_facet mds2 $LCTL get_param -n \
21642                 osp.*$mdt_name-osp-MDT0001.maxage)
21643
21644         stack_trap "do_facet mds2 $LCTL set_param -n \
21645                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low \
21646                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high" EXIT
21647         stack_trap "do_facet mds2 $LCTL set_param -n \
21648                 osp.*$mdt_name-osp-MDT0001.maxage=$maxage" EXIT
21649
21650         do_facet mds2 $LCTL set_param -n \
21651                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$((ffree + 1))
21652         do_facet mds2 $LCTL set_param -n osp.*$mdt_name-osp-MDT0001.maxage=1
21653         sleep 4
21654         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir &&
21655                 error "migrate $tdir should fail"
21656
21657         do_facet mds2 $LCTL set_param -n \
21658                 osp.*$mdt_name-osp-MDT0001.reserved_ino_low=$low
21659         do_facet mds2 $LCTL set_param -n \
21660                 osp.*$mdt_name-osp-MDT0001.reserved_ino_high=$high
21661         sleep 4
21662         $LFS migrate -m 1 -c $MDSCOUNT $DIR/$tdir ||
21663                 error "migrate failed"
21664         (( $($LFS getdirstripe -c $DIR/$tdir) == $MDSCOUNT )) ||
21665                 error "$tdir stripe count mismatch"
21666 }
21667 run_test 230x "dir migration check space"
21668
21669 test_231a()
21670 {
21671         # For simplicity this test assumes that max_pages_per_rpc
21672         # is the same across all OSCs
21673         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
21674         local bulk_size=$((max_pages * PAGE_SIZE))
21675         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
21676                                        head -n 1)
21677
21678         mkdir -p $DIR/$tdir
21679         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
21680                 error "failed to set stripe with -S ${brw_size}M option"
21681
21682         # clear the OSC stats
21683         $LCTL set_param osc.*.stats=0 &>/dev/null
21684         stop_writeback
21685
21686         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
21687         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
21688                 oflag=direct &>/dev/null || error "dd failed"
21689
21690         sync; sleep 1; sync # just to be safe
21691         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
21692         if [ x$nrpcs != "x1" ]; then
21693                 $LCTL get_param osc.*.stats
21694                 error "found $nrpcs ost_write RPCs, not 1 as expected"
21695         fi
21696
21697         start_writeback
21698         # Drop the OSC cache, otherwise we will read from it
21699         cancel_lru_locks osc
21700
21701         # clear the OSC stats
21702         $LCTL set_param osc.*.stats=0 &>/dev/null
21703
21704         # Client reads $bulk_size.
21705         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
21706                 iflag=direct &>/dev/null || error "dd failed"
21707
21708         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
21709         if [ x$nrpcs != "x1" ]; then
21710                 $LCTL get_param osc.*.stats
21711                 error "found $nrpcs ost_read RPCs, not 1 as expected"
21712         fi
21713 }
21714 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
21715
21716 test_231b() {
21717         mkdir -p $DIR/$tdir
21718         local i
21719         for i in {0..1023}; do
21720                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
21721                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
21722                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
21723         done
21724         sync
21725 }
21726 run_test 231b "must not assert on fully utilized OST request buffer"
21727
21728 test_232a() {
21729         mkdir -p $DIR/$tdir
21730         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21731
21732         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21733         do_facet ost1 $LCTL set_param fail_loc=0x31c
21734
21735         # ignore dd failure
21736         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
21737
21738         do_facet ost1 $LCTL set_param fail_loc=0
21739         umount_client $MOUNT || error "umount failed"
21740         mount_client $MOUNT || error "mount failed"
21741         stop ost1 || error "cannot stop ost1"
21742         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21743 }
21744 run_test 232a "failed lock should not block umount"
21745
21746 test_232b() {
21747         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
21748                 skip "Need MDS version at least 2.10.58"
21749
21750         mkdir -p $DIR/$tdir
21751         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
21752         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
21753         sync
21754         cancel_lru_locks osc
21755
21756         #define OBD_FAIL_LDLM_OST_LVB            0x31c
21757         do_facet ost1 $LCTL set_param fail_loc=0x31c
21758
21759         # ignore failure
21760         $LFS data_version $DIR/$tdir/$tfile || true
21761
21762         do_facet ost1 $LCTL set_param fail_loc=0
21763         umount_client $MOUNT || error "umount failed"
21764         mount_client $MOUNT || error "mount failed"
21765         stop ost1 || error "cannot stop ost1"
21766         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
21767 }
21768 run_test 232b "failed data version lock should not block umount"
21769
21770 test_233a() {
21771         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
21772                 skip "Need MDS version at least 2.3.64"
21773         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21774
21775         local fid=$($LFS path2fid $MOUNT)
21776
21777         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21778                 error "cannot access $MOUNT using its FID '$fid'"
21779 }
21780 run_test 233a "checking that OBF of the FS root succeeds"
21781
21782 test_233b() {
21783         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
21784                 skip "Need MDS version at least 2.5.90"
21785         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
21786
21787         local fid=$($LFS path2fid $MOUNT/.lustre)
21788
21789         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21790                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
21791
21792         fid=$($LFS path2fid $MOUNT/.lustre/fid)
21793         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
21794                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
21795 }
21796 run_test 233b "checking that OBF of the FS .lustre succeeds"
21797
21798 test_234() {
21799         local p="$TMP/sanityN-$TESTNAME.parameters"
21800         save_lustre_params client "llite.*.xattr_cache" > $p
21801         lctl set_param llite.*.xattr_cache 1 ||
21802                 skip_env "xattr cache is not supported"
21803
21804         mkdir -p $DIR/$tdir || error "mkdir failed"
21805         touch $DIR/$tdir/$tfile || error "touch failed"
21806         # OBD_FAIL_LLITE_XATTR_ENOMEM
21807         $LCTL set_param fail_loc=0x1405
21808         getfattr -n user.attr $DIR/$tdir/$tfile &&
21809                 error "getfattr should have failed with ENOMEM"
21810         $LCTL set_param fail_loc=0x0
21811         rm -rf $DIR/$tdir
21812
21813         restore_lustre_params < $p
21814         rm -f $p
21815 }
21816 run_test 234 "xattr cache should not crash on ENOMEM"
21817
21818 test_235() {
21819         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
21820                 skip "Need MDS version at least 2.4.52"
21821
21822         flock_deadlock $DIR/$tfile
21823         local RC=$?
21824         case $RC in
21825                 0)
21826                 ;;
21827                 124) error "process hangs on a deadlock"
21828                 ;;
21829                 *) error "error executing flock_deadlock $DIR/$tfile"
21830                 ;;
21831         esac
21832 }
21833 run_test 235 "LU-1715: flock deadlock detection does not work properly"
21834
21835 #LU-2935
21836 test_236() {
21837         check_swap_layouts_support
21838
21839         local ref1=/etc/passwd
21840         local ref2=/etc/group
21841         local file1=$DIR/$tdir/f1
21842         local file2=$DIR/$tdir/f2
21843
21844         test_mkdir -c1 $DIR/$tdir
21845         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
21846         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
21847         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
21848         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
21849         local fd=$(free_fd)
21850         local cmd="exec $fd<>$file2"
21851         eval $cmd
21852         rm $file2
21853         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
21854                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
21855         cmd="exec $fd>&-"
21856         eval $cmd
21857         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
21858
21859         #cleanup
21860         rm -rf $DIR/$tdir
21861 }
21862 run_test 236 "Layout swap on open unlinked file"
21863
21864 # LU-4659 linkea consistency
21865 test_238() {
21866         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
21867                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
21868                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
21869                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
21870
21871         touch $DIR/$tfile
21872         ln $DIR/$tfile $DIR/$tfile.lnk
21873         touch $DIR/$tfile.new
21874         mv $DIR/$tfile.new $DIR/$tfile
21875         local fid1=$($LFS path2fid $DIR/$tfile)
21876         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
21877         local path1=$($LFS fid2path $FSNAME "$fid1")
21878         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
21879         local path2=$($LFS fid2path $FSNAME "$fid2")
21880         [ $tfile.lnk == $path2 ] ||
21881                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
21882         rm -f $DIR/$tfile*
21883 }
21884 run_test 238 "Verify linkea consistency"
21885
21886 test_239A() { # was test_239
21887         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
21888                 skip "Need MDS version at least 2.5.60"
21889
21890         local list=$(comma_list $(mdts_nodes))
21891
21892         mkdir -p $DIR/$tdir
21893         createmany -o $DIR/$tdir/f- 5000
21894         unlinkmany $DIR/$tdir/f- 5000
21895         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
21896                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
21897         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
21898                         osp.*MDT*.sync_in_flight" | calc_sum)
21899         [ "$changes" -eq 0 ] || error "$changes not synced"
21900 }
21901 run_test 239A "osp_sync test"
21902
21903 test_239a() { #LU-5297
21904         remote_mds_nodsh && skip "remote MDS with nodsh"
21905
21906         touch $DIR/$tfile
21907         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
21908         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
21909         chgrp $RUNAS_GID $DIR/$tfile
21910         wait_delete_completed
21911 }
21912 run_test 239a "process invalid osp sync record correctly"
21913
21914 test_239b() { #LU-5297
21915         remote_mds_nodsh && skip "remote MDS with nodsh"
21916
21917         touch $DIR/$tfile1
21918         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
21919         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
21920         chgrp $RUNAS_GID $DIR/$tfile1
21921         wait_delete_completed
21922         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21923         touch $DIR/$tfile2
21924         chgrp $RUNAS_GID $DIR/$tfile2
21925         wait_delete_completed
21926 }
21927 run_test 239b "process osp sync record with ENOMEM error correctly"
21928
21929 test_240() {
21930         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
21931         remote_mds_nodsh && skip "remote MDS with nodsh"
21932
21933         mkdir -p $DIR/$tdir
21934
21935         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
21936                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
21937         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
21938                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
21939
21940         umount_client $MOUNT || error "umount failed"
21941         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
21942         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
21943         mount_client $MOUNT || error "failed to mount client"
21944
21945         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
21946         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
21947 }
21948 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
21949
21950 test_241_bio() {
21951         local count=$1
21952         local bsize=$2
21953
21954         for LOOP in $(seq $count); do
21955                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
21956                 cancel_lru_locks $OSC || true
21957         done
21958 }
21959
21960 test_241_dio() {
21961         local count=$1
21962         local bsize=$2
21963
21964         for LOOP in $(seq $1); do
21965                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
21966                         2>/dev/null
21967         done
21968 }
21969
21970 test_241a() { # was test_241
21971         local bsize=$PAGE_SIZE
21972
21973         (( bsize < 40960 )) && bsize=40960
21974         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21975         ls -la $DIR/$tfile
21976         cancel_lru_locks $OSC
21977         test_241_bio 1000 $bsize &
21978         PID=$!
21979         test_241_dio 1000 $bsize
21980         wait $PID
21981 }
21982 run_test 241a "bio vs dio"
21983
21984 test_241b() {
21985         local bsize=$PAGE_SIZE
21986
21987         (( bsize < 40960 )) && bsize=40960
21988         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
21989         ls -la $DIR/$tfile
21990         test_241_dio 1000 $bsize &
21991         PID=$!
21992         test_241_dio 1000 $bsize
21993         wait $PID
21994 }
21995 run_test 241b "dio vs dio"
21996
21997 test_242() {
21998         remote_mds_nodsh && skip "remote MDS with nodsh"
21999
22000         mkdir_on_mdt0 $DIR/$tdir
22001         touch $DIR/$tdir/$tfile
22002
22003         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
22004         do_facet mds1 lctl set_param fail_loc=0x105
22005         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
22006
22007         do_facet mds1 lctl set_param fail_loc=0
22008         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
22009 }
22010 run_test 242 "mdt_readpage failure should not cause directory unreadable"
22011
22012 test_243()
22013 {
22014         test_mkdir $DIR/$tdir
22015         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
22016 }
22017 run_test 243 "various group lock tests"
22018
22019 test_244a()
22020 {
22021         test_mkdir $DIR/$tdir
22022         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
22023         sendfile_grouplock $DIR/$tdir/$tfile || \
22024                 error "sendfile+grouplock failed"
22025         rm -rf $DIR/$tdir
22026 }
22027 run_test 244a "sendfile with group lock tests"
22028
22029 test_244b()
22030 {
22031         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
22032
22033         local threads=50
22034         local size=$((1024*1024))
22035
22036         test_mkdir $DIR/$tdir
22037         for i in $(seq 1 $threads); do
22038                 local file=$DIR/$tdir/file_$((i / 10))
22039                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
22040                 local pids[$i]=$!
22041         done
22042         for i in $(seq 1 $threads); do
22043                 wait ${pids[$i]}
22044         done
22045 }
22046 run_test 244b "multi-threaded write with group lock"
22047
22048 test_245a() {
22049         local flagname="multi_mod_rpcs"
22050         local connect_data_name="max_mod_rpcs"
22051         local out
22052
22053         # check if multiple modify RPCs flag is set
22054         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
22055                 grep "connect_flags:")
22056         echo "$out"
22057
22058         echo "$out" | grep -qw $flagname
22059         if [ $? -ne 0 ]; then
22060                 echo "connect flag $flagname is not set"
22061                 return
22062         fi
22063
22064         # check if multiple modify RPCs data is set
22065         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
22066         echo "$out"
22067
22068         echo "$out" | grep -qw $connect_data_name ||
22069                 error "import should have connect data $connect_data_name"
22070 }
22071 run_test 245a "check mdc connection flag/data: multiple modify RPCs"
22072
22073 test_245b() {
22074         local flagname="multi_mod_rpcs"
22075         local connect_data_name="max_mod_rpcs"
22076         local out
22077
22078         remote_mds_nodsh && skip "remote MDS with nodsh"
22079         [[ $MDSCOUNT -ge 2 ]] || skip "needs >= 2 MDTs"
22080
22081         # check if multiple modify RPCs flag is set
22082         out=$(do_facet mds1 \
22083               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import |
22084               grep "connect_flags:")
22085         echo "$out"
22086
22087         [[ "$out" =~ $flagname ]] || skip "connect flag $flagname is not set"
22088
22089         # check if multiple modify RPCs data is set
22090         out=$(do_facet mds1 \
22091               $LCTL get_param osp.$FSNAME-MDT0001-osp-MDT0000.import)
22092
22093         [[ "$out" =~ $connect_data_name ]] ||
22094                 {
22095                         echo "$out"
22096                         error "missing connect data $connect_data_name"
22097                 }
22098 }
22099 run_test 245b "check osp connection flag/data: multiple modify RPCs"
22100
22101 cleanup_247() {
22102         local submount=$1
22103
22104         trap 0
22105         umount_client $submount
22106         rmdir $submount
22107 }
22108
22109 test_247a() {
22110         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22111                 grep -q subtree ||
22112                 skip_env "Fileset feature is not supported"
22113
22114         local submount=${MOUNT}_$tdir
22115
22116         mkdir $MOUNT/$tdir
22117         mkdir -p $submount || error "mkdir $submount failed"
22118         FILESET="$FILESET/$tdir" mount_client $submount ||
22119                 error "mount $submount failed"
22120         trap "cleanup_247 $submount" EXIT
22121         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
22122         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
22123                 error "read $MOUNT/$tdir/$tfile failed"
22124         cleanup_247 $submount
22125 }
22126 run_test 247a "mount subdir as fileset"
22127
22128 test_247b() {
22129         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22130                 skip_env "Fileset feature is not supported"
22131
22132         local submount=${MOUNT}_$tdir
22133
22134         rm -rf $MOUNT/$tdir
22135         mkdir -p $submount || error "mkdir $submount failed"
22136         SKIP_FILESET=1
22137         FILESET="$FILESET/$tdir" mount_client $submount &&
22138                 error "mount $submount should fail"
22139         rmdir $submount
22140 }
22141 run_test 247b "mount subdir that dose not exist"
22142
22143 test_247c() {
22144         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22145                 skip_env "Fileset feature is not supported"
22146
22147         local submount=${MOUNT}_$tdir
22148
22149         mkdir -p $MOUNT/$tdir/dir1
22150         mkdir -p $submount || error "mkdir $submount failed"
22151         trap "cleanup_247 $submount" EXIT
22152         FILESET="$FILESET/$tdir" mount_client $submount ||
22153                 error "mount $submount failed"
22154         local fid=$($LFS path2fid $MOUNT/)
22155         $LFS fid2path $submount $fid && error "fid2path should fail"
22156         cleanup_247 $submount
22157 }
22158 run_test 247c "running fid2path outside subdirectory root"
22159
22160 test_247d() {
22161         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22162                 skip "Fileset feature is not supported"
22163
22164         local submount=${MOUNT}_$tdir
22165
22166         mkdir -p $MOUNT/$tdir/dir1
22167         mkdir -p $submount || error "mkdir $submount failed"
22168         FILESET="$FILESET/$tdir" mount_client $submount ||
22169                 error "mount $submount failed"
22170         trap "cleanup_247 $submount" EXIT
22171
22172         local td=$submount/dir1
22173         local fid=$($LFS path2fid $td)
22174         [ -z "$fid" ] && error "path2fid unable to get $td FID"
22175
22176         # check that we get the same pathname back
22177         local rootpath
22178         local found
22179         for rootpath in "$submount" "$submount///" "$submount/dir1"; do
22180                 echo "$rootpath $fid"
22181                 found=$($LFS fid2path $rootpath "$fid")
22182                 [ -n "$found" ] || error "fid2path should succeed"
22183                 [ "$found" == "$td" ] || error "fid2path $found != $td"
22184         done
22185         # check wrong root path format
22186         rootpath=$submount"_wrong"
22187         found=$($LFS fid2path $rootpath "$fid")
22188         [ -z "$found" ] || error "fid2path should fail ($rootpath != $submount)"
22189
22190         cleanup_247 $submount
22191 }
22192 run_test 247d "running fid2path inside subdirectory root"
22193
22194 # LU-8037
22195 test_247e() {
22196         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
22197                 grep -q subtree ||
22198                 skip "Fileset feature is not supported"
22199
22200         local submount=${MOUNT}_$tdir
22201
22202         mkdir $MOUNT/$tdir
22203         mkdir -p $submount || error "mkdir $submount failed"
22204         FILESET="$FILESET/.." mount_client $submount &&
22205                 error "mount $submount should fail"
22206         rmdir $submount
22207 }
22208 run_test 247e "mount .. as fileset"
22209
22210 test_247f() {
22211         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
22212         (( $MDS1_VERSION >= $(version_code 2.14.50.162) )) ||
22213                 skip "Need at least version 2.14.50.162"
22214         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
22215                 skip "Fileset feature is not supported"
22216
22217         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
22218         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote ||
22219                 error "mkdir remote failed"
22220         $LFS mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir/remote/subdir ||
22221                 error "mkdir remote/subdir failed"
22222         $LFS mkdir -i 0 -c $MDSCOUNT $DIR/$tdir/striped ||
22223                 error "mkdir striped failed"
22224         mkdir $DIR/$tdir/striped/subdir || error "mkdir striped/subdir failed"
22225
22226         local submount=${MOUNT}_$tdir
22227
22228         mkdir -p $submount || error "mkdir $submount failed"
22229         stack_trap "rmdir $submount"
22230
22231         local dir
22232         local fileset=$FILESET
22233         local mdts=$(comma_list $(mdts_nodes))
22234
22235         do_nodes $mdts "$LCTL set_param mdt.*.enable_remote_subdir_mount=1"
22236         for dir in $tdir/remote $tdir/remote/subdir $tdir/striped \
22237                 $tdir/striped/subdir $tdir/striped/.; do
22238                 FILESET="$fileset/$dir" mount_client $submount ||
22239                         error "mount $dir failed"
22240                 umount_client $submount
22241         done
22242 }
22243 run_test 247f "mount striped or remote directory as fileset"
22244
22245 test_subdir_mount_lock()
22246 {
22247         local testdir=$1
22248         local submount=${MOUNT}_$(basename $testdir)
22249
22250         touch $DIR/$testdir/$tfile || error "touch $tfile failed"
22251
22252         mkdir -p $submount || error "mkdir $submount failed"
22253         stack_trap "rmdir $submount"
22254
22255         FILESET="$fileset/$testdir" mount_client $submount ||
22256                 error "mount $FILESET failed"
22257         stack_trap "umount $submount"
22258
22259         local mdts=$(comma_list $(mdts_nodes))
22260
22261         local nrpcs
22262
22263         stat $submount > /dev/null || error "stat $submount failed"
22264         cancel_lru_locks $MDC
22265         stat $submount > /dev/null || error "stat $submount failed"
22266         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22267         do_nodes $mdts "$LCTL set_param mdt.*.md_stats=clear > /dev/null"
22268         stat $submount/$tfile > /dev/null || error "stat $tfile failed"
22269         nrpcs=$(do_nodes $mdts "lctl get_param -n mdt.*.md_stats" |
22270                 awk '/getattr/ {sum += $2} END {print sum}')
22271
22272         [ -z "$nrpcs" ] || error "$nrpcs extra getattr sent"
22273 }
22274
22275 test_247g() {
22276         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22277
22278         $LFS mkdir -i 0 -c 4 -H fnv_1a_64 $DIR/$tdir ||
22279                 error "mkdir $tdir failed"
22280         test_subdir_mount_lock $tdir
22281 }
22282 run_test 247g "striped directory submount revalidate ROOT from cache"
22283
22284 test_247h() {
22285         (( $MDSCOUNT > 1 )) || skip_env "needs > 1 MDTs"
22286         (( $MDS1_VERSION >= $(version_code 2.15.51) )) ||
22287                 skip "Need MDS version at least 2.15.51"
22288
22289         $LFS mkdir -i 1 -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
22290         test_subdir_mount_lock $tdir
22291         mkdir_on_mdt -i 0 $DIR/$tdir/$tdir.0 || error "mkdir $tdir.0 failed"
22292         mkdir_on_mdt -i 1 $DIR/$tdir/$tdir.0/$tdir.1 ||
22293                 error "mkdir $tdir.1 failed"
22294         test_subdir_mount_lock $tdir/$tdir.0/$tdir.1
22295 }
22296 run_test 247h "remote directory submount revalidate ROOT from cache"
22297
22298 test_248a() {
22299         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
22300         [ -z "$fast_read_sav" ] && skip "no fast read support"
22301
22302         # create a large file for fast read verification
22303         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
22304
22305         # make sure the file is created correctly
22306         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
22307                 { rm -f $DIR/$tfile; skip "file creation error"; }
22308
22309         echo "Test 1: verify that fast read is 4 times faster on cache read"
22310
22311         # small read with fast read enabled
22312         $LCTL set_param -n llite.*.fast_read=1
22313         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22314                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22315                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22316         # small read with fast read disabled
22317         $LCTL set_param -n llite.*.fast_read=0
22318         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
22319                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22320                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22321
22322         # verify that fast read is 4 times faster for cache read
22323         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
22324                 error_not_in_vm "fast read was not 4 times faster: " \
22325                            "$t_fast vs $t_slow"
22326
22327         echo "Test 2: verify the performance between big and small read"
22328         $LCTL set_param -n llite.*.fast_read=1
22329
22330         # 1k non-cache read
22331         cancel_lru_locks osc
22332         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22333                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22334                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22335
22336         # 1M non-cache read
22337         cancel_lru_locks osc
22338         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
22339                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
22340                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
22341
22342         # verify that big IO is not 4 times faster than small IO
22343         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
22344                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
22345
22346         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
22347         rm -f $DIR/$tfile
22348 }
22349 run_test 248a "fast read verification"
22350
22351 test_248b() {
22352         # Default short_io_bytes=16384, try both smaller and larger sizes.
22353         # Lustre O_DIRECT read and write needs to be a multiple of PAGE_SIZE.
22354         # 6017024 = 2^12*13*113 = 47008*128 = 11752*512 = 4096*1469 = 53248*113
22355         echo "bs=53248 count=113 normal buffered write"
22356         dd if=/dev/urandom of=$TMP/$tfile.0 bs=53248 count=113 ||
22357                 error "dd of initial data file failed"
22358         stack_trap "rm -f $DIR/$tfile.[0-3] $TMP/$tfile.[0-3]" EXIT
22359
22360         echo "bs=47008 count=128 oflag=dsync normal write $tfile.0"
22361         dd if=$TMP/$tfile.0 of=$DIR/$tfile.0 bs=47008 count=128 oflag=dsync ||
22362                 error "dd with sync normal writes failed"
22363         cmp $TMP/$tfile.0 $DIR/$tfile.0 || error "compare $DIR/$tfile.0 failed"
22364
22365         echo "bs=11752 count=512 oflag=dsync small write $tfile.1"
22366         dd if=$TMP/$tfile.0 of=$DIR/$tfile.1 bs=11752 count=512 oflag=dsync ||
22367                 error "dd with sync small writes failed"
22368         cmp $TMP/$tfile.0 $DIR/$tfile.1 || error "compare $DIR/$tfile.1 failed"
22369
22370         cancel_lru_locks osc
22371
22372         # calculate the small O_DIRECT size and count for the client PAGE_SIZE
22373         local num=$((13 * 113 / (PAGE_SIZE / 4096)))
22374         echo "bs=$PAGE_SIZE count=$num iflag=direct small read $tfile.1"
22375         dd if=$DIR/$tfile.1 of=$TMP/$tfile.1 bs=$PAGE_SIZE count=$num \
22376                 iflag=direct || error "dd with O_DIRECT small read failed"
22377         # adjust bytes checked to handle larger PAGE_SIZE for ARM/PPC
22378         cmp --bytes=$((PAGE_SIZE * num)) $TMP/$tfile.0 $TMP/$tfile.1 ||
22379                 error "compare $TMP/$tfile.1 failed"
22380
22381         local save=$($LCTL get_param -n osc.*OST000*.short_io_bytes | head -n 1)
22382         stack_trap "$LCTL set_param osc.$FSNAME-*.short_io_bytes=$save" EXIT
22383
22384         # just to see what the maximum tunable value is, and test parsing
22385         echo "test invalid parameter 2MB"
22386         $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=2M &&
22387                 error "too-large short_io_bytes allowed"
22388         echo "test maximum parameter 512KB"
22389         # if we can set a larger short_io_bytes, run test regardless of version
22390         if ! $LCTL set_param osc.$FSNAME-OST0000*.short_io_bytes=512K; then
22391                 # older clients may not allow setting it this large, that's OK
22392                 [ $CLIENT_VERSION -ge $(version_code 2.13.50) ] ||
22393                         skip "Need at least client version 2.13.50"
22394                 error "medium short_io_bytes failed"
22395         fi
22396         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22397         size=$($LCTL get_param -n osc.$FSNAME-OST0000*.short_io_bytes)
22398
22399         echo "test large parameter 64KB"
22400         $LCTL set_param osc.$FSNAME-*.short_io_bytes=65536
22401         $LCTL get_param osc.$FSNAME-OST0000*.short_io_bytes
22402
22403         echo "bs=47008 count=128 oflag=dsync large write $tfile.2"
22404         dd if=$TMP/$tfile.0 of=$DIR/$tfile.2 bs=47008 count=128 oflag=dsync ||
22405                 error "dd with sync large writes failed"
22406         cmp $TMP/$tfile.0 $DIR/$tfile.2 || error "compare $DIR/$tfile.2 failed"
22407
22408         # calculate the large O_DIRECT size and count for the client PAGE_SIZE
22409         local size=$(((4096 * 13 + PAGE_SIZE - 1) / PAGE_SIZE * PAGE_SIZE))
22410         num=$((113 * 4096 / PAGE_SIZE))
22411         echo "bs=$size count=$num oflag=direct large write $tfile.3"
22412         dd if=$TMP/$tfile.0 of=$DIR/$tfile.3 bs=$size count=$num oflag=direct ||
22413                 error "dd with O_DIRECT large writes failed"
22414         cmp --bytes=$((size * num)) $TMP/$tfile.0 $DIR/$tfile.3 ||
22415                 error "compare $DIR/$tfile.3 failed"
22416
22417         cancel_lru_locks osc
22418
22419         echo "bs=$size count=$num iflag=direct large read $tfile.2"
22420         dd if=$DIR/$tfile.2 of=$TMP/$tfile.2 bs=$size count=$num iflag=direct ||
22421                 error "dd with O_DIRECT large read failed"
22422         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.2 ||
22423                 error "compare $TMP/$tfile.2 failed"
22424
22425         echo "bs=$size count=$num iflag=direct large read $tfile.3"
22426         dd if=$DIR/$tfile.3 of=$TMP/$tfile.3 bs=$size count=$num iflag=direct ||
22427                 error "dd with O_DIRECT large read failed"
22428         cmp --bytes=$((size * num)) $TMP/$tfile.0 $TMP/$tfile.3 ||
22429                 error "compare $TMP/$tfile.3 failed"
22430 }
22431 run_test 248b "test short_io read and write for both small and large sizes"
22432
22433 test_249() { # LU-7890
22434         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
22435                 skip "Need at least version 2.8.54"
22436
22437         rm -f $DIR/$tfile
22438         $LFS setstripe -c 1 $DIR/$tfile
22439         # Offset 2T == 4k * 512M
22440         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
22441                 error "dd to 2T offset failed"
22442 }
22443 run_test 249 "Write above 2T file size"
22444
22445 test_250() {
22446         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
22447          && skip "no 16TB file size limit on ZFS"
22448
22449         $LFS setstripe -c 1 $DIR/$tfile
22450         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
22451         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
22452         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
22453         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
22454                 conv=notrunc,fsync && error "append succeeded"
22455         return 0
22456 }
22457 run_test 250 "Write above 16T limit"
22458
22459 test_251() {
22460         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
22461
22462         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
22463         #Skip once - writing the first stripe will succeed
22464         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22465         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
22466                 error "short write happened"
22467
22468         $LCTL set_param fail_loc=0xa0001407 fail_val=1
22469         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
22470                 error "short read happened"
22471
22472         rm -f $DIR/$tfile
22473 }
22474 run_test 251 "Handling short read and write correctly"
22475
22476 test_252() {
22477         remote_mds_nodsh && skip "remote MDS with nodsh"
22478         remote_ost_nodsh && skip "remote OST with nodsh"
22479         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
22480                 skip_env "ldiskfs only test"
22481         fi
22482
22483         local tgt
22484         local dev
22485         local out
22486         local uuid
22487         local num
22488         local gen
22489
22490         # check lr_reader on OST0000
22491         tgt=ost1
22492         dev=$(facet_device $tgt)
22493         out=$(do_facet $tgt $LR_READER $dev)
22494         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22495         echo "$out"
22496         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
22497         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
22498                 error "Invalid uuid returned by $LR_READER on target $tgt"
22499         echo -e "uuid returned by $LR_READER is '$uuid'\n"
22500
22501         # check lr_reader -c on MDT0000
22502         tgt=mds1
22503         dev=$(facet_device $tgt)
22504         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
22505                 skip "$LR_READER does not support additional options"
22506         fi
22507         out=$(do_facet $tgt $LR_READER -c $dev)
22508         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22509         echo "$out"
22510         num=$(echo "$out" | grep -c "mdtlov")
22511         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
22512                 error "Invalid number of mdtlov clients returned by $LR_READER"
22513         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
22514
22515         # check lr_reader -cr on MDT0000
22516         out=$(do_facet $tgt $LR_READER -cr $dev)
22517         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
22518         echo "$out"
22519         echo "$out" | grep -q "^reply_data:$" ||
22520                 error "$LR_READER should have returned 'reply_data' section"
22521         num=$(echo "$out" | grep -c "client_generation")
22522         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
22523 }
22524 run_test 252 "check lr_reader tool"
22525
22526 test_253() {
22527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22528         remote_mds_nodsh && skip "remote MDS with nodsh"
22529         remote_mgs_nodsh && skip "remote MGS with nodsh"
22530
22531         local ostidx=0
22532         local rc=0
22533         local ost_name=$(ostname_from_index $ostidx)
22534
22535         # on the mdt's osc
22536         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
22537         do_facet $SINGLEMDS $LCTL get_param -n \
22538                 osp.$mdtosc_proc1.reserved_mb_high ||
22539                 skip  "remote MDS does not support reserved_mb_high"
22540
22541         rm -rf $DIR/$tdir
22542         wait_mds_ost_sync
22543         wait_delete_completed
22544         mkdir $DIR/$tdir
22545
22546         pool_add $TESTNAME || error "Pool creation failed"
22547         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
22548
22549         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
22550                 error "Setstripe failed"
22551
22552         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
22553
22554         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
22555                     grep "watermarks")
22556         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
22557
22558         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22559                         osp.$mdtosc_proc1.prealloc_status)
22560         echo "prealloc_status $oa_status"
22561
22562         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
22563                 error "File creation should fail"
22564
22565         #object allocation was stopped, but we still able to append files
22566         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
22567                 oflag=append || error "Append failed"
22568
22569         rm -f $DIR/$tdir/$tfile.0
22570
22571         # For this test, we want to delete the files we created to go out of
22572         # space but leave the watermark, so we remain nearly out of space
22573         ost_watermarks_enospc_delete_files $tfile $ostidx
22574
22575         wait_delete_completed
22576
22577         sleep_maxage
22578
22579         for i in $(seq 10 12); do
22580                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
22581                         2>/dev/null || error "File creation failed after rm"
22582         done
22583
22584         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
22585                         osp.$mdtosc_proc1.prealloc_status)
22586         echo "prealloc_status $oa_status"
22587
22588         if (( oa_status != 0 )); then
22589                 error "Object allocation still disable after rm"
22590         fi
22591 }
22592 run_test 253 "Check object allocation limit"
22593
22594 test_254() {
22595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22596         remote_mds_nodsh && skip "remote MDS with nodsh"
22597
22598         local mdt=$(facet_svc $SINGLEMDS)
22599
22600         do_facet $SINGLEMDS $LCTL get_param -n mdd.$mdt.changelog_size ||
22601                 skip "MDS does not support changelog_size"
22602
22603         local cl_user
22604
22605         changelog_register || error "changelog_register failed"
22606
22607         changelog_clear 0 || error "changelog_clear failed"
22608
22609         local size1=$(do_facet $SINGLEMDS \
22610                       $LCTL get_param -n mdd.$mdt.changelog_size)
22611         echo "Changelog size $size1"
22612
22613         rm -rf $DIR/$tdir
22614         $LFS mkdir -i 0 $DIR/$tdir
22615         # change something
22616         mkdir -p $DIR/$tdir/pics/2008/zachy
22617         touch $DIR/$tdir/pics/2008/zachy/timestamp
22618         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
22619         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
22620         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
22621         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
22622         rm $DIR/$tdir/pics/desktop.jpg
22623
22624         local size2=$(do_facet $SINGLEMDS \
22625                       $LCTL get_param -n mdd.$mdt.changelog_size)
22626         echo "Changelog size after work $size2"
22627
22628         (( $size2 > $size1 )) ||
22629                 error "new Changelog size=$size2 less than old size=$size1"
22630 }
22631 run_test 254 "Check changelog size"
22632
22633 ladvise_no_type()
22634 {
22635         local type=$1
22636         local file=$2
22637
22638         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
22639                 awk -F: '{print $2}' | grep $type > /dev/null
22640         if [ $? -ne 0 ]; then
22641                 return 0
22642         fi
22643         return 1
22644 }
22645
22646 ladvise_no_ioctl()
22647 {
22648         local file=$1
22649
22650         lfs ladvise -a willread $file > /dev/null 2>&1
22651         if [ $? -eq 0 ]; then
22652                 return 1
22653         fi
22654
22655         lfs ladvise -a willread $file 2>&1 |
22656                 grep "Inappropriate ioctl for device" > /dev/null
22657         if [ $? -eq 0 ]; then
22658                 return 0
22659         fi
22660         return 1
22661 }
22662
22663 percent() {
22664         bc <<<"scale=2; ($1 - $2) * 100 / $2"
22665 }
22666
22667 # run a random read IO workload
22668 # usage: random_read_iops <filename> <filesize> <iosize>
22669 random_read_iops() {
22670         local file=$1
22671         local fsize=$2
22672         local iosize=${3:-4096}
22673
22674         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
22675                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
22676 }
22677
22678 drop_file_oss_cache() {
22679         local file="$1"
22680         local nodes="$2"
22681
22682         $LFS ladvise -a dontneed $file 2>/dev/null ||
22683                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
22684 }
22685
22686 ladvise_willread_performance()
22687 {
22688         local repeat=10
22689         local average_origin=0
22690         local average_cache=0
22691         local average_ladvise=0
22692
22693         for ((i = 1; i <= $repeat; i++)); do
22694                 echo "Iter $i/$repeat: reading without willread hint"
22695                 cancel_lru_locks osc
22696                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22697                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
22698                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
22699                 average_origin=$(bc <<<"$average_origin + $speed_origin")
22700
22701                 cancel_lru_locks osc
22702                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
22703                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
22704                 average_cache=$(bc <<<"$average_cache + $speed_cache")
22705
22706                 cancel_lru_locks osc
22707                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
22708                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
22709                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
22710                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
22711                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
22712         done
22713         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
22714         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
22715         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
22716
22717         speedup_cache=$(percent $average_cache $average_origin)
22718         speedup_ladvise=$(percent $average_ladvise $average_origin)
22719
22720         echo "Average uncached read: $average_origin"
22721         echo "Average speedup with OSS cached read: " \
22722                 "$average_cache = +$speedup_cache%"
22723         echo "Average speedup with ladvise willread: " \
22724                 "$average_ladvise = +$speedup_ladvise%"
22725
22726         local lowest_speedup=20
22727         if (( ${average_cache%.*} < $lowest_speedup )); then
22728                 echo "Speedup with OSS cached read less than $lowest_speedup%,"\
22729                      " got $average_cache%. Skipping ladvise willread check."
22730                 return 0
22731         fi
22732
22733         # the test won't work on ZFS until it supports 'ladvise dontneed', but
22734         # it is still good to run until then to exercise 'ladvise willread'
22735         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22736                 [ "$ost1_FSTYPE" = "zfs" ] &&
22737                 echo "osd-zfs does not support dontneed or drop_caches" &&
22738                 return 0
22739
22740         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
22741         (( ${average_ladvise%.*} > ${lowest_speedup%.*} )) ||
22742                 error_not_in_vm "Speedup with willread is less than " \
22743                         "$lowest_speedup%, got $average_ladvise%"
22744 }
22745
22746 test_255a() {
22747         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22748                 skip "lustre < 2.8.54 does not support ladvise "
22749         remote_ost_nodsh && skip "remote OST with nodsh"
22750
22751         stack_trap "rm -f $DIR/$tfile"
22752         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
22753
22754         ladvise_no_type willread $DIR/$tfile &&
22755                 skip "willread ladvise is not supported"
22756
22757         ladvise_no_ioctl $DIR/$tfile &&
22758                 skip "ladvise ioctl is not supported"
22759
22760         local size_mb=100
22761         local size=$((size_mb * 1048576))
22762         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22763                 error "dd to $DIR/$tfile failed"
22764
22765         lfs ladvise -a willread $DIR/$tfile ||
22766                 error "Ladvise failed with no range argument"
22767
22768         lfs ladvise -a willread -s 0 $DIR/$tfile ||
22769                 error "Ladvise failed with no -l or -e argument"
22770
22771         lfs ladvise -a willread -e 1 $DIR/$tfile ||
22772                 error "Ladvise failed with only -e argument"
22773
22774         lfs ladvise -a willread -l 1 $DIR/$tfile ||
22775                 error "Ladvise failed with only -l argument"
22776
22777         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
22778                 error "End offset should not be smaller than start offset"
22779
22780         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
22781                 error "End offset should not be equal to start offset"
22782
22783         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
22784                 error "Ladvise failed with overflowing -s argument"
22785
22786         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
22787                 error "Ladvise failed with overflowing -e argument"
22788
22789         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
22790                 error "Ladvise failed with overflowing -l argument"
22791
22792         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
22793                 error "Ladvise succeeded with conflicting -l and -e arguments"
22794
22795         echo "Synchronous ladvise should wait"
22796         local delay=4
22797 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
22798         do_nodes $(comma_list $(osts_nodes)) \
22799                 $LCTL set_param fail_val=$delay fail_loc=0x237
22800
22801         local start_ts=$SECONDS
22802         lfs ladvise -a willread $DIR/$tfile ||
22803                 error "Ladvise failed with no range argument"
22804         local end_ts=$SECONDS
22805         local inteval_ts=$((end_ts - start_ts))
22806
22807         if [ $inteval_ts -lt $(($delay - 1)) ]; then
22808                 error "Synchronous advice didn't wait reply"
22809         fi
22810
22811         echo "Asynchronous ladvise shouldn't wait"
22812         local start_ts=$SECONDS
22813         lfs ladvise -a willread -b $DIR/$tfile ||
22814                 error "Ladvise failed with no range argument"
22815         local end_ts=$SECONDS
22816         local inteval_ts=$((end_ts - start_ts))
22817
22818         if [ $inteval_ts -gt $(($delay / 2)) ]; then
22819                 error "Asynchronous advice blocked"
22820         fi
22821
22822         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
22823         ladvise_willread_performance
22824 }
22825 run_test 255a "check 'lfs ladvise -a willread'"
22826
22827 facet_meminfo() {
22828         local facet=$1
22829         local info=$2
22830
22831         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
22832 }
22833
22834 test_255b() {
22835         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
22836                 skip "lustre < 2.8.54 does not support ladvise "
22837         remote_ost_nodsh && skip "remote OST with nodsh"
22838
22839         stack_trap "rm -f $DIR/$tfile"
22840         lfs setstripe -c 1 -i 0 $DIR/$tfile
22841
22842         ladvise_no_type dontneed $DIR/$tfile &&
22843                 skip "dontneed ladvise is not supported"
22844
22845         ladvise_no_ioctl $DIR/$tfile &&
22846                 skip "ladvise ioctl is not supported"
22847
22848         ! $LFS ladvise -a dontneed $DIR/$tfile &&
22849                 [ "$ost1_FSTYPE" = "zfs" ] &&
22850                 skip "zfs-osd does not support 'ladvise dontneed'"
22851
22852         local size_mb=100
22853         local size=$((size_mb * 1048576))
22854         # In order to prevent disturbance of other processes, only check 3/4
22855         # of the memory usage
22856         local kibibytes=$((size_mb * 1024 * 3 / 4))
22857
22858         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
22859                 error "dd to $DIR/$tfile failed"
22860
22861         #force write to complete before dropping OST cache & checking memory
22862         sync
22863
22864         local total=$(facet_meminfo ost1 MemTotal)
22865         echo "Total memory: $total KiB"
22866
22867         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
22868         local before_read=$(facet_meminfo ost1 Cached)
22869         echo "Cache used before read: $before_read KiB"
22870
22871         lfs ladvise -a willread $DIR/$tfile ||
22872                 error "Ladvise willread failed"
22873         local after_read=$(facet_meminfo ost1 Cached)
22874         echo "Cache used after read: $after_read KiB"
22875
22876         lfs ladvise -a dontneed $DIR/$tfile ||
22877                 error "Ladvise dontneed again failed"
22878         local no_read=$(facet_meminfo ost1 Cached)
22879         echo "Cache used after dontneed ladvise: $no_read KiB"
22880
22881         if [ $total -lt $((before_read + kibibytes)) ]; then
22882                 echo "Memory is too small, abort checking"
22883                 return 0
22884         fi
22885
22886         if [ $((before_read + kibibytes)) -gt $after_read ]; then
22887                 error "Ladvise willread should use more memory" \
22888                         "than $kibibytes KiB"
22889         fi
22890
22891         if [ $((no_read + kibibytes)) -gt $after_read ]; then
22892                 error "Ladvise dontneed should release more memory" \
22893                         "than $kibibytes KiB"
22894         fi
22895 }
22896 run_test 255b "check 'lfs ladvise -a dontneed'"
22897
22898 test_255c() {
22899         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
22900                 skip "lustre < 2.10.50 does not support lockahead"
22901
22902         local ost1_imp=$(get_osc_import_name client ost1)
22903         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
22904                          cut -d'.' -f2)
22905         local count
22906         local new_count
22907         local difference
22908         local i
22909         local rc
22910
22911         test_mkdir -p $DIR/$tdir
22912         $LFS setstripe -i 0 -c 1 $DIR/$tdir
22913
22914         #test 10 returns only success/failure
22915         i=10
22916         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22917         rc=$?
22918         if [ $rc -eq 255 ]; then
22919                 error "Ladvise test${i} failed, ${rc}"
22920         fi
22921
22922         #test 11 counts lock enqueue requests, all others count new locks
22923         i=11
22924         count=$(do_facet ost1 \
22925                 $LCTL get_param -n ost.OSS.ost.stats)
22926         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
22927
22928         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22929         rc=$?
22930         if [ $rc -eq 255 ]; then
22931                 error "Ladvise test${i} failed, ${rc}"
22932         fi
22933
22934         new_count=$(do_facet ost1 \
22935                 $LCTL get_param -n ost.OSS.ost.stats)
22936         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
22937                    awk '{ print $2 }')
22938
22939         difference="$((new_count - count))"
22940         if [ $difference -ne $rc ]; then
22941                 error "Ladvise test${i}, bad enqueue count, returned " \
22942                       "${rc}, actual ${difference}"
22943         fi
22944
22945         for i in $(seq 12 21); do
22946                 # If we do not do this, we run the risk of having too many
22947                 # locks and starting lock cancellation while we are checking
22948                 # lock counts.
22949                 cancel_lru_locks osc
22950
22951                 count=$($LCTL get_param -n \
22952                        ldlm.namespaces.$imp_name.lock_unused_count)
22953
22954                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
22955                 rc=$?
22956                 if [ $rc -eq 255 ]; then
22957                         error "Ladvise test ${i} failed, ${rc}"
22958                 fi
22959
22960                 new_count=$($LCTL get_param -n \
22961                        ldlm.namespaces.$imp_name.lock_unused_count)
22962                 difference="$((new_count - count))"
22963
22964                 # Test 15 output is divided by 100 to map down to valid return
22965                 if [ $i -eq 15 ]; then
22966                         rc="$((rc * 100))"
22967                 fi
22968
22969                 if [ $difference -ne $rc ]; then
22970                         error "Ladvise test ${i}, bad lock count, returned " \
22971                               "${rc}, actual ${difference}"
22972                 fi
22973         done
22974
22975         #test 22 returns only success/failure
22976         i=22
22977         lockahead_test -d $DIR/$tdir -t $i -f $tfile
22978         rc=$?
22979         if [ $rc -eq 255 ]; then
22980                 error "Ladvise test${i} failed, ${rc}"
22981         fi
22982 }
22983 run_test 255c "suite of ladvise lockahead tests"
22984
22985 test_256() {
22986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22987         remote_mds_nodsh && skip "remote MDS with nodsh"
22988         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
22989         changelog_users $SINGLEMDS | grep "^cl" &&
22990                 skip "active changelog user"
22991
22992         local cl_user
22993         local cat_sl
22994         local mdt_dev
22995
22996         mdt_dev=$(facet_device $SINGLEMDS)
22997         echo $mdt_dev
22998
22999         changelog_register || error "changelog_register failed"
23000
23001         rm -rf $DIR/$tdir
23002         mkdir_on_mdt -i$(($(facet_number $SINGLEMDS) - 1)) $DIR/$tdir
23003
23004         changelog_clear 0 || error "changelog_clear failed"
23005
23006         # change something
23007         touch $DIR/$tdir/{1..10}
23008
23009         # stop the MDT
23010         stop $SINGLEMDS || error "Fail to stop MDT"
23011
23012         # remount the MDT
23013         start $SINGLEMDS $(facet_device $SINGLEMDS) $MDS_MOUNT_OPTS ||
23014                 error "Fail to start MDT"
23015
23016         #after mount new plainllog is used
23017         touch $DIR/$tdir/{11..19}
23018         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
23019         stack_trap "rm -f $tmpfile"
23020         cat_sl=$(do_facet $SINGLEMDS "sync; \
23021                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23022                  llog_reader $tmpfile | grep -c type=1064553b")
23023         do_facet $SINGLEMDS llog_reader $tmpfile
23024
23025         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
23026
23027         changelog_clear 0 || error "changelog_clear failed"
23028
23029         cat_sl=$(do_facet $SINGLEMDS "sync; \
23030                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
23031                  llog_reader $tmpfile | grep -c type=1064553b")
23032
23033         if (( cat_sl == 2 )); then
23034                 error "Empty plain llog was not deleted from changelog catalog"
23035         elif (( cat_sl != 1 )); then
23036                 error "Active plain llog shouldn't be deleted from catalog"
23037         fi
23038 }
23039 run_test 256 "Check llog delete for empty and not full state"
23040
23041 test_257() {
23042         remote_mds_nodsh && skip "remote MDS with nodsh"
23043         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
23044                 skip "Need MDS version at least 2.8.55"
23045
23046         test_mkdir $DIR/$tdir
23047
23048         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
23049                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
23050         stat $DIR/$tdir
23051
23052 #define OBD_FAIL_MDS_XATTR_REP                  0x161
23053         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23054         local facet=mds$((mdtidx + 1))
23055         set_nodes_failloc $(facet_active_host $facet) 0x80000161
23056         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
23057
23058         stop $facet || error "stop MDS failed"
23059         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
23060                 error "start MDS fail"
23061         wait_recovery_complete $facet
23062 }
23063 run_test 257 "xattr locks are not lost"
23064
23065 # Verify we take the i_mutex when security requires it
23066 test_258a() {
23067 #define OBD_FAIL_IMUTEX_SEC 0x141c
23068         $LCTL set_param fail_loc=0x141c
23069         touch $DIR/$tfile
23070         chmod u+s $DIR/$tfile
23071         chmod a+rwx $DIR/$tfile
23072         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23073         RC=$?
23074         if [ $RC -ne 0 ]; then
23075                 error "error, failed to take i_mutex, rc=$?"
23076         fi
23077         rm -f $DIR/$tfile
23078 }
23079 run_test 258a "verify i_mutex security behavior when suid attributes is set"
23080
23081 # Verify we do NOT take the i_mutex in the normal case
23082 test_258b() {
23083 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
23084         $LCTL set_param fail_loc=0x141d
23085         touch $DIR/$tfile
23086         chmod a+rwx $DIR
23087         chmod a+rw $DIR/$tfile
23088         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
23089         RC=$?
23090         if [ $RC -ne 0 ]; then
23091                 error "error, took i_mutex unnecessarily, rc=$?"
23092         fi
23093         rm -f $DIR/$tfile
23094
23095 }
23096 run_test 258b "verify i_mutex security behavior"
23097
23098 test_259() {
23099         local file=$DIR/$tfile
23100         local before
23101         local after
23102
23103         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
23104
23105         stack_trap "rm -f $file" EXIT
23106
23107         wait_delete_completed
23108         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23109         echo "before: $before"
23110
23111         $LFS setstripe -i 0 -c 1 $file
23112         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
23113         sync_all_data
23114         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23115         echo "after write: $after"
23116
23117 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
23118         do_facet ost1 $LCTL set_param fail_loc=0x2301
23119         $TRUNCATE $file 0
23120         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23121         echo "after truncate: $after"
23122
23123         stop ost1
23124         do_facet ost1 $LCTL set_param fail_loc=0
23125         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
23126         sleep 2
23127         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
23128         echo "after restart: $after"
23129         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
23130                 error "missing truncate?"
23131
23132         return 0
23133 }
23134 run_test 259 "crash at delayed truncate"
23135
23136 test_260() {
23137 #define OBD_FAIL_MDC_CLOSE               0x806
23138         $LCTL set_param fail_loc=0x80000806
23139         touch $DIR/$tfile
23140
23141 }
23142 run_test 260 "Check mdc_close fail"
23143
23144 ### Data-on-MDT sanity tests ###
23145 test_270a() {
23146         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23147                 skip "Need MDS version at least 2.10.55 for DoM"
23148
23149         # create DoM file
23150         local dom=$DIR/$tdir/dom_file
23151         local tmp=$DIR/$tdir/tmp_file
23152
23153         mkdir_on_mdt0 $DIR/$tdir
23154
23155         # basic checks for DoM component creation
23156         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
23157                 error "Can set MDT layout to non-first entry"
23158
23159         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
23160                 error "Can define multiple entries as MDT layout"
23161
23162         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
23163
23164         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
23165         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
23166         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
23167
23168         local mdtidx=$($LFS getstripe -m $dom)
23169         local mdtname=MDT$(printf %04x $mdtidx)
23170         local facet=mds$((mdtidx + 1))
23171         local space_check=1
23172
23173         # Skip free space checks with ZFS
23174         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
23175
23176         # write
23177         sync
23178         local size_tmp=$((65536 * 3))
23179         local mdtfree1=$(do_facet $facet \
23180                          lctl get_param -n osd*.*$mdtname.kbytesfree)
23181
23182         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23183         # check also direct IO along write
23184         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
23185         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23186         sync
23187         cmp $tmp $dom || error "file data is different"
23188         [ $(stat -c%s $dom) == $size_tmp ] ||
23189                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23190         if [ $space_check == 1 ]; then
23191                 local mdtfree2=$(do_facet $facet \
23192                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
23193
23194                 # increase in usage from by $size_tmp
23195                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23196                         error "MDT free space wrong after write: " \
23197                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23198         fi
23199
23200         # truncate
23201         local size_dom=10000
23202
23203         $TRUNCATE $dom $size_dom
23204         [ $(stat -c%s $dom) == $size_dom ] ||
23205                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
23206         if [ $space_check == 1 ]; then
23207                 mdtfree1=$(do_facet $facet \
23208                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23209                 # decrease in usage from $size_tmp to new $size_dom
23210                 [ $(($mdtfree1 - $mdtfree2)) -ge \
23211                   $(((size_tmp - size_dom) / 1024)) ] ||
23212                         error "MDT free space is wrong after truncate: " \
23213                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
23214         fi
23215
23216         # append
23217         cat $tmp >> $dom
23218         sync
23219         size_dom=$((size_dom + size_tmp))
23220         [ $(stat -c%s $dom) == $size_dom ] ||
23221                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
23222         if [ $space_check == 1 ]; then
23223                 mdtfree2=$(do_facet $facet \
23224                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23225                 # increase in usage by $size_tmp from previous
23226                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
23227                         error "MDT free space is wrong after append: " \
23228                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
23229         fi
23230
23231         # delete
23232         rm $dom
23233         if [ $space_check == 1 ]; then
23234                 mdtfree1=$(do_facet $facet \
23235                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23236                 # decrease in usage by $size_dom from previous
23237                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
23238                         error "MDT free space is wrong after removal: " \
23239                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
23240         fi
23241
23242         # combined striping
23243         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
23244                 error "Can't create DoM + OST striping"
23245
23246         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
23247         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
23248         # check also direct IO along write
23249         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
23250         sync
23251         cmp $tmp $dom || error "file data is different"
23252         [ $(stat -c%s $dom) == $size_tmp ] ||
23253                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
23254         rm $dom $tmp
23255
23256         return 0
23257 }
23258 run_test 270a "DoM: basic functionality tests"
23259
23260 test_270b() {
23261         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23262                 skip "Need MDS version at least 2.10.55"
23263
23264         local dom=$DIR/$tdir/dom_file
23265         local max_size=1048576
23266
23267         mkdir -p $DIR/$tdir
23268         $LFS setstripe -E $max_size -L mdt $dom
23269
23270         # truncate over the limit
23271         $TRUNCATE $dom $(($max_size + 1)) &&
23272                 error "successful truncate over the maximum size"
23273         # write over the limit
23274         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
23275                 error "successful write over the maximum size"
23276         # append over the limit
23277         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
23278         echo "12345" >> $dom && error "successful append over the maximum size"
23279         rm $dom
23280
23281         return 0
23282 }
23283 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
23284
23285 test_270c() {
23286         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23287                 skip "Need MDS version at least 2.10.55"
23288
23289         mkdir -p $DIR/$tdir
23290         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23291
23292         # check files inherit DoM EA
23293         touch $DIR/$tdir/first
23294         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
23295                 error "bad pattern"
23296         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
23297                 error "bad stripe count"
23298         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
23299                 error "bad stripe size"
23300
23301         # check directory inherits DoM EA and uses it as default
23302         mkdir $DIR/$tdir/subdir
23303         touch $DIR/$tdir/subdir/second
23304         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
23305                 error "bad pattern in sub-directory"
23306         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
23307                 error "bad stripe count in sub-directory"
23308         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
23309                 error "bad stripe size in sub-directory"
23310         return 0
23311 }
23312 run_test 270c "DoM: DoM EA inheritance tests"
23313
23314 test_270d() {
23315         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23316                 skip "Need MDS version at least 2.10.55"
23317
23318         mkdir -p $DIR/$tdir
23319         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23320
23321         # inherit default DoM striping
23322         mkdir $DIR/$tdir/subdir
23323         touch $DIR/$tdir/subdir/f1
23324
23325         # change default directory striping
23326         $LFS setstripe -c 1 $DIR/$tdir/subdir
23327         touch $DIR/$tdir/subdir/f2
23328         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
23329                 error "wrong default striping in file 2"
23330         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
23331                 error "bad pattern in file 2"
23332         return 0
23333 }
23334 run_test 270d "DoM: change striping from DoM to RAID0"
23335
23336 test_270e() {
23337         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23338                 skip "Need MDS version at least 2.10.55"
23339
23340         mkdir -p $DIR/$tdir/dom
23341         mkdir -p $DIR/$tdir/norm
23342         DOMFILES=20
23343         NORMFILES=10
23344         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
23345         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
23346
23347         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
23348         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
23349
23350         # find DoM files by layout
23351         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
23352         [ $NUM -eq  $DOMFILES ] ||
23353                 error "lfs find -L: found $NUM, expected $DOMFILES"
23354         echo "Test 1: lfs find 20 DOM files by layout: OK"
23355
23356         # there should be 1 dir with default DOM striping
23357         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
23358         [ $NUM -eq  1 ] ||
23359                 error "lfs find -L: found $NUM, expected 1 dir"
23360         echo "Test 2: lfs find 1 DOM dir by layout: OK"
23361
23362         # find DoM files by stripe size
23363         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
23364         [ $NUM -eq  $DOMFILES ] ||
23365                 error "lfs find -S: found $NUM, expected $DOMFILES"
23366         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
23367
23368         # find files by stripe offset except DoM files
23369         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
23370         [ $NUM -eq  $NORMFILES ] ||
23371                 error "lfs find -i: found $NUM, expected $NORMFILES"
23372         echo "Test 5: lfs find no DOM files by stripe index: OK"
23373         return 0
23374 }
23375 run_test 270e "DoM: lfs find with DoM files test"
23376
23377 test_270f() {
23378         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23379                 skip "Need MDS version at least 2.10.55"
23380
23381         local mdtname=${FSNAME}-MDT0000-mdtlov
23382         local dom=$DIR/$tdir/dom_file
23383         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
23384                                                 lod.$mdtname.dom_stripesize)
23385         local dom_limit=131072
23386
23387         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
23388         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23389                                                 lod.$mdtname.dom_stripesize)
23390         [ ${dom_limit} -eq ${dom_current} ] ||
23391                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
23392
23393         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23394         $LFS setstripe -d $DIR/$tdir
23395         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
23396                 error "Can't set directory default striping"
23397
23398         # exceed maximum stripe size
23399         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23400                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
23401         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
23402                 error "Able to create DoM component size more than LOD limit"
23403
23404         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23405         dom_current=$(do_facet mds1 $LCTL get_param -n \
23406                                                 lod.$mdtname.dom_stripesize)
23407         [ 0 -eq ${dom_current} ] ||
23408                 error "Can't set zero DoM stripe limit"
23409         rm $dom
23410
23411         # attempt to create DoM file on server with disabled DoM should
23412         # remove DoM entry from layout and be succeed
23413         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
23414                 error "Can't create DoM file (DoM is disabled)"
23415         [ $($LFS getstripe -L $dom) == "mdt" ] &&
23416                 error "File has DoM component while DoM is disabled"
23417         rm $dom
23418
23419         # attempt to create DoM file with only DoM stripe should return error
23420         $LFS setstripe -E $dom_limit -L mdt $dom &&
23421                 error "Able to create DoM-only file while DoM is disabled"
23422
23423         # too low values to be aligned with smallest stripe size 64K
23424         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
23425         dom_current=$(do_facet mds1 $LCTL get_param -n \
23426                                                 lod.$mdtname.dom_stripesize)
23427         [ 30000 -eq ${dom_current} ] &&
23428                 error "Can set too small DoM stripe limit"
23429
23430         # 64K is a minimal stripe size in Lustre, expect limit of that size
23431         [ 65536 -eq ${dom_current} ] ||
23432                 error "Limit is not set to 64K but ${dom_current}"
23433
23434         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
23435         dom_current=$(do_facet mds1 $LCTL get_param -n \
23436                                                 lod.$mdtname.dom_stripesize)
23437         echo $dom_current
23438         [ 2147483648 -eq ${dom_current} ] &&
23439                 error "Can set too large DoM stripe limit"
23440
23441         do_facet mds1 $LCTL set_param -n \
23442                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
23443         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
23444                 error "Can't create DoM component size after limit change"
23445         do_facet mds1 $LCTL set_param -n \
23446                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
23447         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
23448                 error "Can't create DoM file after limit decrease"
23449         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
23450                 error "Can create big DoM component after limit decrease"
23451         touch ${dom}_def ||
23452                 error "Can't create file with old default layout"
23453
23454         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
23455         return 0
23456 }
23457 run_test 270f "DoM: maximum DoM stripe size checks"
23458
23459 test_270g() {
23460         [ $MDS1_VERSION -ge $(version_code 2.13.52) ] ||
23461                 skip "Need MDS version at least 2.13.52"
23462         local dom=$DIR/$tdir/$tfile
23463
23464         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23465         local lodname=${FSNAME}-MDT0000-mdtlov
23466
23467         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23468         save_lustre_params mds1 "lod.${lodname}.dom_stripesize_max_kb" > $save
23469         save_lustre_params mds1 "lod.${lodname}.dom_threshold_free_mb" >> $save
23470         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23471
23472         local dom_limit=1024
23473         local dom_threshold="50%"
23474
23475         $LFS setstripe -d $DIR/$tdir
23476         $LFS setstripe -E ${dom_limit}K -L mdt $DIR/$tdir ||
23477                 error "Can't set directory default striping"
23478
23479         do_facet mds1 $LCTL set_param -n \
23480                                 lod.${lodname}.dom_stripesize_max_kb=$dom_limit
23481         # set 0 threshold and create DOM file to change tunable stripesize
23482         do_facet mds1 $LCTL set_param -n lod.${lodname}.dom_threshold_free_mb=0
23483         $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23484                 error "Failed to create $dom file"
23485         # now tunable dom_cur_stripesize should reach maximum
23486         local dom_current=$(do_facet mds1 $LCTL get_param -n \
23487                                         lod.${lodname}.dom_stripesize_cur_kb)
23488         [[ $dom_current == $dom_limit ]] ||
23489                 error "Current DOM stripesize is not maximum"
23490         rm $dom
23491
23492         # set threshold for further tests
23493         do_facet mds1 $LCTL set_param -n \
23494                         lod.${lodname}.dom_threshold_free_mb=$dom_threshold
23495         echo "DOM threshold is $dom_threshold free space"
23496         local dom_def
23497         local dom_set
23498         # Spoof bfree to exceed threshold
23499         #define OBD_FAIL_MDS_STATFS_SPOOF   0x168
23500         do_facet mds1 $LCTL set_param -n fail_loc=0x0168
23501         for spfree in 40 20 0 15 30 55; do
23502                 do_facet mds1 $LCTL set_param -n fail_val=$spfree
23503                 $LFS setstripe -E ${dom_limit}K -L mdt -E -1 $dom ||
23504                         error "Failed to create $dom file"
23505                 dom_def=$(do_facet mds1 $LCTL get_param -n \
23506                                         lod.${lodname}.dom_stripesize_cur_kb)
23507                 echo "Free space: ${spfree}%, default DOM stripe: ${dom_def}K"
23508                 [[ $dom_def != $dom_current ]] ||
23509                         error "Default stripe size was not changed"
23510                 if (( spfree > 0 )) ; then
23511                         dom_set=$($LFS getstripe -S $dom)
23512                         (( dom_set == dom_def * 1024 )) ||
23513                                 error "DOM component size is still old"
23514                 else
23515                         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23516                                 error "DoM component is set with no free space"
23517                 fi
23518                 rm $dom
23519                 dom_current=$dom_def
23520         done
23521 }
23522 run_test 270g "DoM: default DoM stripe size depends on free space"
23523
23524 test_270h() {
23525         [[ $MDS1_VERSION -ge $(version_code 2.13.53) ]] ||
23526                 skip "Need MDS version at least 2.13.53"
23527
23528         local mdtname=${FSNAME}-MDT0000-mdtlov
23529         local dom=$DIR/$tdir/$tfile
23530         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
23531
23532         save_lustre_params mds1 "lod.*.dom_stripesize" > $save
23533         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
23534
23535         $LFS mkdir -i 0 -c 1 $DIR/$tdir
23536         $LFS setstripe -E 1M -c1  -E -1 -c2 ${dom}_1 ||
23537                 error "can't create OST file"
23538         # mirrored file with DOM entry in the second mirror
23539         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 ${dom}_1 ||
23540                 error "can't create mirror with DoM component"
23541
23542         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
23543
23544         # DOM component in the middle and has other enries in the same mirror,
23545         # should succeed but lost DoM component
23546         $LFS setstripe --copy=${dom}_1 $dom ||
23547                 error "Can't create file from OST|DOM mirror layout"
23548         # check new file has no DoM layout after all
23549         [[ $($LFS getstripe -L $dom) != "mdt" ]] ||
23550                 error "File has DoM component while DoM is disabled"
23551 }
23552 run_test 270h "DoM: DoM stripe removal when disabled on server"
23553
23554 test_270i() {
23555         (( $MDS1_VERSION >= $(version_code 2.14.54) )) ||
23556                 skip "Need MDS version at least 2.14.54"
23557
23558         mkdir $DIR/$tdir
23559         # DoM with plain layout
23560         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir &&
23561                 error "default plain layout with DoM must fail"
23562         $LFS setstripe -L mdt -S 128k -c -1 $DIR/$tdir/$tfile &&
23563                 error "setstripe plain file layout with DoM must fail"
23564         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir &&
23565                 error "default DoM layout with bad striping must fail"
23566         $LFS setstripe -E 1M -L mdt -S 128k -c -1 -E eof $DIR/$tdir/$tfile &&
23567                 error "setstripe to DoM layout with bad striping must fail"
23568         return 0
23569 }
23570 run_test 270i "DoM: setting invalid DoM striping should fail"
23571
23572 test_271a() {
23573         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23574                 skip "Need MDS version at least 2.10.55"
23575
23576         local dom=$DIR/$tdir/dom
23577
23578         mkdir -p $DIR/$tdir
23579
23580         $LFS setstripe -E 1024K -L mdt $dom
23581
23582         lctl set_param -n mdc.*.stats=clear
23583         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23584         cat $dom > /dev/null
23585         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
23586         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
23587         ls $dom
23588         rm -f $dom
23589 }
23590 run_test 271a "DoM: data is cached for read after write"
23591
23592 test_271b() {
23593         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23594                 skip "Need MDS version at least 2.10.55"
23595
23596         local dom=$DIR/$tdir/dom
23597
23598         mkdir -p $DIR/$tdir
23599
23600         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23601
23602         lctl set_param -n mdc.*.stats=clear
23603         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
23604         cancel_lru_locks mdc
23605         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
23606         # second stat to check size is cached on client
23607         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
23608         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23609         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
23610         rm -f $dom
23611 }
23612 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
23613
23614 test_271ba() {
23615         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23616                 skip "Need MDS version at least 2.10.55"
23617
23618         local dom=$DIR/$tdir/dom
23619
23620         mkdir -p $DIR/$tdir
23621
23622         $LFS setstripe -E 1024K -L mdt -E EOF $dom
23623
23624         lctl set_param -n mdc.*.stats=clear
23625         lctl set_param -n osc.*.stats=clear
23626         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
23627         cancel_lru_locks mdc
23628         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23629         # second stat to check size is cached on client
23630         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
23631         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
23632         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
23633         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
23634         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
23635         rm -f $dom
23636 }
23637 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
23638
23639
23640 get_mdc_stats() {
23641         local mdtidx=$1
23642         local param=$2
23643         local mdt=MDT$(printf %04x $mdtidx)
23644
23645         if [ -z $param ]; then
23646                 lctl get_param -n mdc.*$mdt*.stats
23647         else
23648                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
23649         fi
23650 }
23651
23652 test_271c() {
23653         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
23654                 skip "Need MDS version at least 2.10.55"
23655
23656         local dom=$DIR/$tdir/dom
23657
23658         mkdir -p $DIR/$tdir
23659
23660         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23661
23662         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
23663         local facet=mds$((mdtidx + 1))
23664
23665         cancel_lru_locks mdc
23666         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
23667         createmany -o $dom 1000
23668         lctl set_param -n mdc.*.stats=clear
23669         smalliomany -w $dom 1000 200
23670         get_mdc_stats $mdtidx
23671         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23672         # Each file has 1 open, 1 IO enqueues, total 2000
23673         # but now we have also +1 getxattr for security.capability, total 3000
23674         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
23675         unlinkmany $dom 1000
23676
23677         cancel_lru_locks mdc
23678         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
23679         createmany -o $dom 1000
23680         lctl set_param -n mdc.*.stats=clear
23681         smalliomany -w $dom 1000 200
23682         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
23683         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
23684         # for OPEN and IO lock.
23685         [ $((enq - enq_2)) -ge 1000 ] ||
23686                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
23687         unlinkmany $dom 1000
23688         return 0
23689 }
23690 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
23691
23692 cleanup_271def_tests() {
23693         trap 0
23694         rm -f $1
23695 }
23696
23697 test_271d() {
23698         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23699                 skip "Need MDS version at least 2.10.57"
23700
23701         local dom=$DIR/$tdir/dom
23702         local tmp=$TMP/$tfile
23703         trap "cleanup_271def_tests $tmp" EXIT
23704
23705         mkdir -p $DIR/$tdir
23706
23707         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23708
23709         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23710
23711         cancel_lru_locks mdc
23712         dd if=/dev/urandom of=$tmp bs=1000 count=1
23713         dd if=$tmp of=$dom bs=1000 count=1
23714         cancel_lru_locks mdc
23715
23716         cat /etc/hosts >> $tmp
23717         lctl set_param -n mdc.*.stats=clear
23718
23719         # append data to the same file it should update local page
23720         echo "Append to the same page"
23721         cat /etc/hosts >> $dom
23722         local num=$(get_mdc_stats $mdtidx ost_read)
23723         local ra=$(get_mdc_stats $mdtidx req_active)
23724         local rw=$(get_mdc_stats $mdtidx req_waittime)
23725
23726         [ -z $num ] || error "$num READ RPC occured"
23727         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23728         echo "... DONE"
23729
23730         # compare content
23731         cmp $tmp $dom || error "file miscompare"
23732
23733         cancel_lru_locks mdc
23734         lctl set_param -n mdc.*.stats=clear
23735
23736         echo "Open and read file"
23737         cat $dom > /dev/null
23738         local num=$(get_mdc_stats $mdtidx ost_read)
23739         local ra=$(get_mdc_stats $mdtidx req_active)
23740         local rw=$(get_mdc_stats $mdtidx req_waittime)
23741
23742         [ -z $num ] || error "$num READ RPC occured"
23743         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23744         echo "... DONE"
23745
23746         # compare content
23747         cmp $tmp $dom || error "file miscompare"
23748
23749         return 0
23750 }
23751 run_test 271d "DoM: read on open (1K file in reply buffer)"
23752
23753 test_271f() {
23754         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
23755                 skip "Need MDS version at least 2.10.57"
23756
23757         local dom=$DIR/$tdir/dom
23758         local tmp=$TMP/$tfile
23759         trap "cleanup_271def_tests $tmp" EXIT
23760
23761         mkdir -p $DIR/$tdir
23762
23763         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
23764
23765         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
23766
23767         cancel_lru_locks mdc
23768         dd if=/dev/urandom of=$tmp bs=265000 count=1
23769         dd if=$tmp of=$dom bs=265000 count=1
23770         cancel_lru_locks mdc
23771         cat /etc/hosts >> $tmp
23772         lctl set_param -n mdc.*.stats=clear
23773
23774         echo "Append to the same page"
23775         cat /etc/hosts >> $dom
23776         local num=$(get_mdc_stats $mdtidx ost_read)
23777         local ra=$(get_mdc_stats $mdtidx req_active)
23778         local rw=$(get_mdc_stats $mdtidx req_waittime)
23779
23780         [ -z $num ] || error "$num READ RPC occured"
23781         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23782         echo "... DONE"
23783
23784         # compare content
23785         cmp $tmp $dom || error "file miscompare"
23786
23787         cancel_lru_locks mdc
23788         lctl set_param -n mdc.*.stats=clear
23789
23790         echo "Open and read file"
23791         cat $dom > /dev/null
23792         local num=$(get_mdc_stats $mdtidx ost_read)
23793         local ra=$(get_mdc_stats $mdtidx req_active)
23794         local rw=$(get_mdc_stats $mdtidx req_waittime)
23795
23796         [ -z $num ] && num=0
23797         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
23798         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
23799         echo "... DONE"
23800
23801         # compare content
23802         cmp $tmp $dom || error "file miscompare"
23803
23804         return 0
23805 }
23806 run_test 271f "DoM: read on open (200K file and read tail)"
23807
23808 test_271g() {
23809         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
23810                 skip "Skipping due to old client or server version"
23811
23812         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
23813         # to get layout
23814         $CHECKSTAT -t file $DIR1/$tfile
23815
23816         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
23817         MULTIOP_PID=$!
23818         sleep 1
23819         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
23820         $LCTL set_param fail_loc=0x80000314
23821         rm $DIR1/$tfile || error "Unlink fails"
23822         RC=$?
23823         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
23824         [ $RC -eq 0 ] || error "Failed write to stale object"
23825 }
23826 run_test 271g "Discard DoM data vs client flush race"
23827
23828 test_272a() {
23829         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23830                 skip "Need MDS version at least 2.11.50"
23831
23832         local dom=$DIR/$tdir/dom
23833         mkdir -p $DIR/$tdir
23834
23835         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
23836         dd if=/dev/urandom of=$dom bs=512K count=1 ||
23837                 error "failed to write data into $dom"
23838         local old_md5=$(md5sum $dom)
23839
23840         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
23841                 error "failed to migrate to the same DoM component"
23842
23843         local new_md5=$(md5sum $dom)
23844
23845         [ "$old_md5" == "$new_md5" ] ||
23846                 error "md5sum differ: $old_md5, $new_md5"
23847
23848         [ $($LFS getstripe -c $dom) -eq 2 ] ||
23849                 error "bad final stripe count: $($LFS getstripe -c $dom) != 2"
23850 }
23851 run_test 272a "DoM migration: new layout with the same DOM component"
23852
23853 test_272b() {
23854         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23855                 skip "Need MDS version at least 2.11.50"
23856
23857         local dom=$DIR/$tdir/dom
23858         mkdir -p $DIR/$tdir
23859         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23860
23861         local mdtidx=$($LFS getstripe -m $dom)
23862         local mdtname=MDT$(printf %04x $mdtidx)
23863         local facet=mds$((mdtidx + 1))
23864
23865         local mdtfree1=$(do_facet $facet \
23866                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23867         dd if=/dev/urandom of=$dom bs=2M count=1 ||
23868                 error "failed to write data into $dom"
23869         local old_md5=$(md5sum $dom)
23870         cancel_lru_locks mdc
23871         local mdtfree1=$(do_facet $facet \
23872                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23873
23874         $LFS migrate -c2 $dom ||
23875                 error "failed to migrate to the new composite layout"
23876         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23877                 error "MDT stripe was not removed"
23878
23879         cancel_lru_locks mdc
23880         local new_md5=$(md5sum $dom)
23881         [ "$old_md5" == "$new_md5" ] ||
23882                 error "$old_md5 != $new_md5"
23883
23884         # Skip free space checks with ZFS
23885         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23886                 local mdtfree2=$(do_facet $facet \
23887                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23888                 [ $mdtfree2 -gt $mdtfree1 ] ||
23889                         error "MDT space is not freed after migration"
23890         fi
23891         return 0
23892 }
23893 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
23894
23895 test_272c() {
23896         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
23897                 skip "Need MDS version at least 2.11.50"
23898
23899         local dom=$DIR/$tdir/$tfile
23900         mkdir -p $DIR/$tdir
23901         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23902
23903         local mdtidx=$($LFS getstripe -m $dom)
23904         local mdtname=MDT$(printf %04x $mdtidx)
23905         local facet=mds$((mdtidx + 1))
23906
23907         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23908                 error "failed to write data into $dom"
23909         local old_md5=$(md5sum $dom)
23910         cancel_lru_locks mdc
23911         local mdtfree1=$(do_facet $facet \
23912                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23913
23914         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
23915                 error "failed to migrate to the new composite layout"
23916         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
23917                 error "MDT stripe was not removed"
23918
23919         cancel_lru_locks mdc
23920         local new_md5=$(md5sum $dom)
23921         [ "$old_md5" == "$new_md5" ] ||
23922                 error "$old_md5 != $new_md5"
23923
23924         # Skip free space checks with ZFS
23925         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23926                 local mdtfree2=$(do_facet $facet \
23927                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23928                 [ $mdtfree2 -gt $mdtfree1 ] ||
23929                         error "MDS space is not freed after migration"
23930         fi
23931         return 0
23932 }
23933 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
23934
23935 test_272d() {
23936         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23937                 skip "Need MDS version at least 2.12.55"
23938
23939         local dom=$DIR/$tdir/$tfile
23940         mkdir -p $DIR/$tdir
23941         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
23942
23943         local mdtidx=$($LFS getstripe -m $dom)
23944         local mdtname=MDT$(printf %04x $mdtidx)
23945         local facet=mds$((mdtidx + 1))
23946
23947         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23948                 error "failed to write data into $dom"
23949         local old_md5=$(md5sum $dom)
23950         cancel_lru_locks mdc
23951         local mdtfree1=$(do_facet $facet \
23952                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23953
23954         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
23955                 error "failed mirroring to the new composite layout"
23956         $LFS mirror resync $dom ||
23957                 error "failed mirror resync"
23958         $LFS mirror split --mirror-id 1 -d $dom ||
23959                 error "failed mirror split"
23960
23961         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
23962                 error "MDT stripe was not removed"
23963
23964         cancel_lru_locks mdc
23965         local new_md5=$(md5sum $dom)
23966         [ "$old_md5" == "$new_md5" ] ||
23967                 error "$old_md5 != $new_md5"
23968
23969         # Skip free space checks with ZFS
23970         if [ "$(facet_fstype $facet)" != "zfs" ]; then
23971                 local mdtfree2=$(do_facet $facet \
23972                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
23973                 [ $mdtfree2 -gt $mdtfree1 ] ||
23974                         error "MDS space is not freed after DOM mirror deletion"
23975         fi
23976         return 0
23977 }
23978 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
23979
23980 test_272e() {
23981         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
23982                 skip "Need MDS version at least 2.12.55"
23983
23984         local dom=$DIR/$tdir/$tfile
23985         mkdir -p $DIR/$tdir
23986         $LFS setstripe -c 2 $dom
23987
23988         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
23989                 error "failed to write data into $dom"
23990         local old_md5=$(md5sum $dom)
23991         cancel_lru_locks
23992
23993         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
23994                 error "failed mirroring to the DOM layout"
23995         $LFS mirror resync $dom ||
23996                 error "failed mirror resync"
23997         $LFS mirror split --mirror-id 1 -d $dom ||
23998                 error "failed mirror split"
23999
24000         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24001                 error "MDT stripe wasn't set"
24002
24003         cancel_lru_locks
24004         local new_md5=$(md5sum $dom)
24005         [ "$old_md5" == "$new_md5" ] ||
24006                 error "$old_md5 != $new_md5"
24007
24008         return 0
24009 }
24010 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
24011
24012 test_272f() {
24013         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
24014                 skip "Need MDS version at least 2.12.55"
24015
24016         local dom=$DIR/$tdir/$tfile
24017         mkdir -p $DIR/$tdir
24018         $LFS setstripe -c 2 $dom
24019
24020         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
24021                 error "failed to write data into $dom"
24022         local old_md5=$(md5sum $dom)
24023         cancel_lru_locks
24024
24025         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
24026                 error "failed migrating to the DOM file"
24027
24028         [[ $($LFS getstripe -L --component-start=0 $dom) == 'mdt' ]] ||
24029                 error "MDT stripe wasn't set"
24030
24031         cancel_lru_locks
24032         local new_md5=$(md5sum $dom)
24033         [ "$old_md5" != "$new_md5" ] &&
24034                 error "$old_md5 != $new_md5"
24035
24036         return 0
24037 }
24038 run_test 272f "DoM migration: OST-striped file to DOM file"
24039
24040 test_273a() {
24041         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
24042                 skip "Need MDS version at least 2.11.50"
24043
24044         # Layout swap cannot be done if either file has DOM component,
24045         # this will never be supported, migration should be used instead
24046
24047         local dom=$DIR/$tdir/$tfile
24048         mkdir -p $DIR/$tdir
24049
24050         $LFS setstripe -c2 ${dom}_plain
24051         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
24052         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
24053                 error "can swap layout with DoM component"
24054         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
24055                 error "can swap layout with DoM component"
24056
24057         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
24058         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
24059                 error "can swap layout with DoM component"
24060         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
24061                 error "can swap layout with DoM component"
24062         return 0
24063 }
24064 run_test 273a "DoM: layout swapping should fail with DOM"
24065
24066 test_273b() {
24067         mkdir -p $DIR/$tdir
24068         $LFS setstripe -E 1M -L mdt -E -1 -c -1 $DIR/$tdir
24069
24070 #define OBD_FAIL_MDS_COMMITRW_DELAY      0x16b
24071         do_facet mds1 $LCTL set_param fail_loc=0x8000016b fail_val=2
24072
24073         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24074 }
24075 run_test 273b "DoM: race writeback and object destroy"
24076
24077 test_273c() {
24078         mkdir -p $DIR/$tdir
24079         $LFS setstripe -E 1M -E-1 -c-1 $DIR/$tdir
24080
24081         #define OBD_FAIL_OFD_COMMITRW_DELAY      0x1e1
24082         do_facet ost1 $LCTL set_param fail_loc=0x800001e1 fail_val=2
24083
24084         $MULTIOP $DIR/$tdir/$tfile Ouw2097152c
24085 }
24086 run_test 273c "race writeback and object destroy"
24087
24088 test_275() {
24089         remote_ost_nodsh && skip "remote OST with nodsh"
24090         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
24091                 skip "Need OST version >= 2.10.57"
24092
24093         local file=$DIR/$tfile
24094         local oss
24095
24096         oss=$(comma_list $(osts_nodes))
24097
24098         dd if=/dev/urandom of=$file bs=1M count=2 ||
24099                 error "failed to create a file"
24100         cancel_lru_locks osc
24101
24102         #lock 1
24103         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24104                 error "failed to read a file"
24105
24106 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
24107         $LCTL set_param fail_loc=0x8000031f
24108
24109         cancel_lru_locks osc &
24110         sleep 1
24111
24112 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
24113         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
24114         #IO takes another lock, but matches the PENDING one
24115         #and places it to the IO RPC
24116         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
24117                 error "failed to read a file with PENDING lock"
24118 }
24119 run_test 275 "Read on a canceled duplicate lock"
24120
24121 test_276() {
24122         remote_ost_nodsh && skip "remote OST with nodsh"
24123         local pid
24124
24125         do_facet ost1 "(while true; do \
24126                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
24127                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
24128         pid=$!
24129
24130         for LOOP in $(seq 20); do
24131                 stop ost1
24132                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
24133         done
24134         kill -9 $pid
24135         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
24136                 rm $TMP/sanity_276_pid"
24137 }
24138 run_test 276 "Race between mount and obd_statfs"
24139
24140 test_277() {
24141         $LCTL set_param ldlm.namespaces.*.lru_size=0
24142         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
24143         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24144                         grep ^used_mb | awk '{print $2}')
24145         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
24146         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
24147                 oflag=direct conv=notrunc
24148         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
24149                         grep ^used_mb | awk '{print $2}')
24150         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
24151 }
24152 run_test 277 "Direct IO shall drop page cache"
24153
24154 test_278() {
24155         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
24156         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24157         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
24158                 skip "needs the same host for mdt1 mdt2" && return
24159
24160         local pid1
24161         local pid2
24162
24163 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
24164         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
24165         stop mds2 &
24166         pid2=$!
24167
24168         stop mds1
24169
24170         echo "Starting MDTs"
24171         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
24172         wait $pid2
24173 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
24174 #will return NULL
24175         do_facet mds2 $LCTL set_param fail_loc=0
24176
24177         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
24178         wait_recovery_complete mds2
24179 }
24180 run_test 278 "Race starting MDS between MDTs stop/start"
24181
24182 test_280() {
24183         [ $MGS_VERSION -lt $(version_code 2.13.52) ] &&
24184                 skip "Need MGS version at least 2.13.52"
24185         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24186         combined_mgs_mds || skip "needs combined MGS/MDT"
24187
24188         umount_client $MOUNT
24189 #define OBD_FAIL_MDS_LLOG_UMOUNT_RACE   0x15e
24190         do_facet mgs $LCTL set_param fail_loc=0x8000015e fail_val=0
24191
24192         mount_client $MOUNT &
24193         sleep 1
24194         stop mgs || error "stop mgs failed"
24195         #for a race mgs would crash
24196         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
24197         # make sure we unmount client before remounting
24198         wait
24199         umount_client $MOUNT
24200         mount_client $MOUNT || error "mount client failed"
24201 }
24202 run_test 280 "Race between MGS umount and client llog processing"
24203
24204 cleanup_test_300() {
24205         trap 0
24206         umask $SAVE_UMASK
24207 }
24208 test_striped_dir() {
24209         local mdt_index=$1
24210         local stripe_count
24211         local stripe_index
24212
24213         mkdir -p $DIR/$tdir
24214
24215         SAVE_UMASK=$(umask)
24216         trap cleanup_test_300 RETURN EXIT
24217
24218         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
24219                                                 $DIR/$tdir/striped_dir ||
24220                 error "set striped dir error"
24221
24222         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
24223         [ "$mode" = "755" ] || error "expect 755 got $mode"
24224
24225         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
24226                 error "getdirstripe failed"
24227         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
24228         if [ "$stripe_count" != "2" ]; then
24229                 error "1:stripe_count is $stripe_count, expect 2"
24230         fi
24231         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
24232         if [ "$stripe_count" != "2" ]; then
24233                 error "2:stripe_count is $stripe_count, expect 2"
24234         fi
24235
24236         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
24237         if [ "$stripe_index" != "$mdt_index" ]; then
24238                 error "stripe_index is $stripe_index, expect $mdt_index"
24239         fi
24240
24241         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24242                 error "nlink error after create striped dir"
24243
24244         mkdir $DIR/$tdir/striped_dir/a
24245         mkdir $DIR/$tdir/striped_dir/b
24246
24247         stat $DIR/$tdir/striped_dir/a ||
24248                 error "create dir under striped dir failed"
24249         stat $DIR/$tdir/striped_dir/b ||
24250                 error "create dir under striped dir failed"
24251
24252         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
24253                 error "nlink error after mkdir"
24254
24255         rmdir $DIR/$tdir/striped_dir/a
24256         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
24257                 error "nlink error after rmdir"
24258
24259         rmdir $DIR/$tdir/striped_dir/b
24260         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
24261                 error "nlink error after rmdir"
24262
24263         chattr +i $DIR/$tdir/striped_dir
24264         createmany -o $DIR/$tdir/striped_dir/f 10 &&
24265                 error "immutable flags not working under striped dir!"
24266         chattr -i $DIR/$tdir/striped_dir
24267
24268         rmdir $DIR/$tdir/striped_dir ||
24269                 error "rmdir striped dir error"
24270
24271         cleanup_test_300
24272
24273         true
24274 }
24275
24276 test_300a() {
24277         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24278                 skip "skipped for lustre < 2.7.0"
24279         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24280         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24281
24282         test_striped_dir 0 || error "failed on striped dir on MDT0"
24283         test_striped_dir 1 || error "failed on striped dir on MDT0"
24284 }
24285 run_test 300a "basic striped dir sanity test"
24286
24287 test_300b() {
24288         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24289                 skip "skipped for lustre < 2.7.0"
24290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24291         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24292
24293         local i
24294         local mtime1
24295         local mtime2
24296         local mtime3
24297
24298         test_mkdir $DIR/$tdir || error "mkdir fail"
24299         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24300                 error "set striped dir error"
24301         for i in {0..9}; do
24302                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
24303                 sleep 1
24304                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
24305                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
24306                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
24307                 sleep 1
24308                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
24309                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
24310                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
24311         done
24312         true
24313 }
24314 run_test 300b "check ctime/mtime for striped dir"
24315
24316 test_300c() {
24317         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24318                 skip "skipped for lustre < 2.7.0"
24319         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24321
24322         local file_count
24323
24324         mkdir_on_mdt0 $DIR/$tdir
24325         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
24326                 error "set striped dir error"
24327
24328         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
24329                 error "chown striped dir failed"
24330
24331         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
24332                 error "create 5k files failed"
24333
24334         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
24335
24336         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
24337
24338         rm -rf $DIR/$tdir
24339 }
24340 run_test 300c "chown && check ls under striped directory"
24341
24342 test_300d() {
24343         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
24344                 skip "skipped for lustre < 2.7.0"
24345         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24347
24348         local stripe_count
24349         local file
24350
24351         mkdir -p $DIR/$tdir
24352         $LFS setstripe -c 2 $DIR/$tdir
24353
24354         #local striped directory
24355         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24356                 error "set striped dir error"
24357         #look at the directories for debug purposes
24358         ls -l $DIR/$tdir
24359         $LFS getdirstripe $DIR/$tdir
24360         ls -l $DIR/$tdir/striped_dir
24361         $LFS getdirstripe $DIR/$tdir/striped_dir
24362         createmany -o $DIR/$tdir/striped_dir/f 10 ||
24363                 error "create 10 files failed"
24364
24365         #remote striped directory
24366         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
24367                 error "set striped dir error"
24368         #look at the directories for debug purposes
24369         ls -l $DIR/$tdir
24370         $LFS getdirstripe $DIR/$tdir
24371         ls -l $DIR/$tdir/remote_striped_dir
24372         $LFS getdirstripe $DIR/$tdir/remote_striped_dir
24373         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
24374                 error "create 10 files failed"
24375
24376         for file in $(find $DIR/$tdir); do
24377                 stripe_count=$($LFS getstripe -c $file)
24378                 [ $stripe_count -eq 2 ] ||
24379                         error "wrong stripe $stripe_count for $file"
24380         done
24381
24382         rm -rf $DIR/$tdir
24383 }
24384 run_test 300d "check default stripe under striped directory"
24385
24386 test_300e() {
24387         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24388                 skip "Need MDS version at least 2.7.55"
24389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24390         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24391
24392         local stripe_count
24393         local file
24394
24395         mkdir -p $DIR/$tdir
24396
24397         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24398                 error "set striped dir error"
24399
24400         touch $DIR/$tdir/striped_dir/a
24401         touch $DIR/$tdir/striped_dir/b
24402         touch $DIR/$tdir/striped_dir/c
24403
24404         mkdir $DIR/$tdir/striped_dir/dir_a
24405         mkdir $DIR/$tdir/striped_dir/dir_b
24406         mkdir $DIR/$tdir/striped_dir/dir_c
24407
24408         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
24409                 error "set striped adir under striped dir error"
24410
24411         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
24412                 error "set striped bdir under striped dir error"
24413
24414         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
24415                 error "set striped cdir under striped dir error"
24416
24417         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
24418                 error "rename dir under striped dir fails"
24419
24420         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
24421                 error "rename dir under different stripes fails"
24422
24423         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
24424                 error "rename file under striped dir should succeed"
24425
24426         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
24427                 error "rename dir under striped dir should succeed"
24428
24429         rm -rf $DIR/$tdir
24430 }
24431 run_test 300e "check rename under striped directory"
24432
24433 test_300f() {
24434         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24435         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24436         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24437                 skip "Need MDS version at least 2.7.55"
24438
24439         local stripe_count
24440         local file
24441
24442         rm -rf $DIR/$tdir
24443         mkdir -p $DIR/$tdir
24444
24445         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
24446                 error "set striped dir error"
24447
24448         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
24449                 error "set striped dir error"
24450
24451         touch $DIR/$tdir/striped_dir/a
24452         mkdir $DIR/$tdir/striped_dir/dir_a
24453         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
24454                 error "create striped dir under striped dir fails"
24455
24456         touch $DIR/$tdir/striped_dir1/b
24457         mkdir $DIR/$tdir/striped_dir1/dir_b
24458         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
24459                 error "create striped dir under striped dir fails"
24460
24461         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
24462                 error "rename dir under different striped dir should fail"
24463
24464         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
24465                 error "rename striped dir under diff striped dir should fail"
24466
24467         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
24468                 error "rename file under diff striped dirs fails"
24469
24470         rm -rf $DIR/$tdir
24471 }
24472 run_test 300f "check rename cross striped directory"
24473
24474 test_300_check_default_striped_dir()
24475 {
24476         local dirname=$1
24477         local default_count=$2
24478         local default_index=$3
24479         local stripe_count
24480         local stripe_index
24481         local dir_stripe_index
24482         local dir
24483
24484         echo "checking $dirname $default_count $default_index"
24485         $LFS setdirstripe -D -c $default_count -i $default_index \
24486                                 -H all_char $DIR/$tdir/$dirname ||
24487                 error "set default stripe on striped dir error"
24488         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
24489         [ $stripe_count -eq $default_count ] ||
24490                 error "expect $default_count get $stripe_count for $dirname"
24491
24492         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
24493         [ $stripe_index -eq $default_index ] ||
24494                 error "expect $default_index get $stripe_index for $dirname"
24495
24496         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
24497                                                 error "create dirs failed"
24498
24499         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
24500         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
24501         for dir in $(find $DIR/$tdir/$dirname/*); do
24502                 stripe_count=$($LFS getdirstripe -c $dir)
24503                 (( $stripe_count == $default_count )) ||
24504                 (( $stripe_count == $MDSCOUNT && $default_count == -1 )) ||
24505                 (( $stripe_count == 0 )) || (( $default_count == 1 )) ||
24506                 error "stripe count $default_count != $stripe_count for $dir"
24507
24508                 stripe_index=$($LFS getdirstripe -i $dir)
24509                 [ $default_index -eq -1 ] ||
24510                         [ $stripe_index -eq $default_index ] ||
24511                         error "$stripe_index != $default_index for $dir"
24512
24513                 #check default stripe
24514                 stripe_count=$($LFS getdirstripe -D -c $dir)
24515                 [ $stripe_count -eq $default_count ] ||
24516                 error "default count $default_count != $stripe_count for $dir"
24517
24518                 stripe_index=$($LFS getdirstripe -D -i $dir)
24519                 [ $stripe_index -eq $default_index ] ||
24520                 error "default index $default_index != $stripe_index for $dir"
24521         done
24522         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
24523 }
24524
24525 test_300g() {
24526         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24527         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24528                 skip "Need MDS version at least 2.7.55"
24529
24530         local dir
24531         local stripe_count
24532         local stripe_index
24533
24534         mkdir_on_mdt0 $DIR/$tdir
24535         mkdir $DIR/$tdir/normal_dir
24536
24537         #Checking when client cache stripe index
24538         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
24539         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
24540                 error "create striped_dir failed"
24541
24542         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
24543                 error "create dir0 fails"
24544         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
24545         [ $stripe_index -eq 0 ] ||
24546                 error "dir0 expect index 0 got $stripe_index"
24547
24548         mkdir $DIR/$tdir/striped_dir/dir1 ||
24549                 error "create dir1 fails"
24550         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
24551         [ $stripe_index -eq 1 ] ||
24552                 error "dir1 expect index 1 got $stripe_index"
24553
24554         #check default stripe count/stripe index
24555         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
24556         test_300_check_default_striped_dir normal_dir 1 0
24557         test_300_check_default_striped_dir normal_dir -1 1
24558         test_300_check_default_striped_dir normal_dir 2 -1
24559
24560         #delete default stripe information
24561         echo "delete default stripeEA"
24562         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
24563                 error "set default stripe on striped dir error"
24564
24565         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
24566         for dir in $(find $DIR/$tdir/normal_dir/*); do
24567                 stripe_count=$($LFS getdirstripe -c $dir)
24568                 [ $stripe_count -eq 0 ] ||
24569                         error "expect 1 get $stripe_count for $dir"
24570         done
24571 }
24572 run_test 300g "check default striped directory for normal directory"
24573
24574 test_300h() {
24575         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24576         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24577                 skip "Need MDS version at least 2.7.55"
24578
24579         local dir
24580         local stripe_count
24581
24582         mkdir $DIR/$tdir
24583         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24584                 error "set striped dir error"
24585
24586         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
24587         test_300_check_default_striped_dir striped_dir 1 0
24588         test_300_check_default_striped_dir striped_dir -1 1
24589         test_300_check_default_striped_dir striped_dir 2 -1
24590
24591         #delete default stripe information
24592         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
24593                 error "set default stripe on striped dir error"
24594
24595         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
24596         for dir in $(find $DIR/$tdir/striped_dir/*); do
24597                 stripe_count=$($LFS getdirstripe -c $dir)
24598                 [ $stripe_count -eq 0 ] ||
24599                         error "expect 1 get $stripe_count for $dir"
24600         done
24601 }
24602 run_test 300h "check default striped directory for striped directory"
24603
24604 test_300i() {
24605         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
24606         (( $MDSCOUNT >= 2 )) || skip_env "needs >= 2 MDTs"
24607         (( $MDS1_VERSION >= $(version_code 2.7.55) )) ||
24608                 skip "Need MDS version at least 2.7.55"
24609
24610         local stripe_count
24611         local file
24612
24613         mkdir $DIR/$tdir
24614
24615         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24616                 error "set striped dir error"
24617
24618         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24619                 error "create files under striped dir failed"
24620
24621         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
24622                 error "set striped hashdir error"
24623
24624         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
24625                 error "create dir0 under hash dir failed"
24626         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
24627                 error "create dir1 under hash dir failed"
24628         $LFS setdirstripe -i0 -c$MDSCOUNT -H crush $DIR/$tdir/hashdir/d2 ||
24629                 error "create dir2 under hash dir failed"
24630
24631         # unfortunately, we need to umount to clear dir layout cache for now
24632         # once we fully implement dir layout, we can drop this
24633         umount_client $MOUNT || error "umount failed"
24634         mount_client $MOUNT || error "mount failed"
24635
24636         $LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir
24637         local dircnt=$($LFS find -H fnv_1a_64,crush $DIR/$tdir/hashdir | wc -l)
24638         (( $dircnt == 2 )) || error "lfs find striped dir got $dircnt != 2"
24639
24640         if (( $MDS1_VERSION > $(version_code 2.15.0) )); then
24641                 $LFS mkdir -i0 -c$MDSCOUNT -H crush2 $DIR/$tdir/hashdir/d3 ||
24642                         error "create crush2 dir $tdir/hashdir/d3 failed"
24643                 $LFS find -H crush2 $DIR/$tdir/hashdir
24644                 dircnt=$($LFS find -H crush2 $DIR/$tdir/hashdir | wc -l)
24645                 (( $dircnt == 1 )) || error "find crush2 dir got $dircnt != 1"
24646
24647                 # mkdir with an invalid hash type (hash=fail_val) from client
24648                 # should be replaced on MDS with a valid (default) hash type
24649                 #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24650                 $LCTL set_param fail_loc=0x1901 fail_val=99
24651                 $LFS mkdir -c2 $DIR/$tdir/hashdir/d99
24652
24653                 local hash=$($LFS getdirstripe -H $DIR/$tdir/hashdir/d99)
24654                 local expect=$(do_facet mds1 \
24655                         $LCTL get_param -n lod.$FSNAME-MDT0000-mdtlov.mdt_hash)
24656                 [[ $hash == $expect ]] ||
24657                         error "d99 hash '$hash' != expected hash '$expect'"
24658         fi
24659
24660         #set the stripe to be unknown hash type on read
24661         #define OBD_FAIL_LMV_UNKNOWN_STRIPE     0x1901
24662         $LCTL set_param fail_loc=0x1901 fail_val=99
24663         for ((i = 0; i < 10; i++)); do
24664                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
24665                         error "stat f-$i failed"
24666                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
24667         done
24668
24669         touch $DIR/$tdir/striped_dir/f0 &&
24670                 error "create under striped dir with unknown hash should fail"
24671
24672         $LCTL set_param fail_loc=0
24673
24674         umount_client $MOUNT || error "umount failed"
24675         mount_client $MOUNT || error "mount failed"
24676
24677         return 0
24678 }
24679 run_test 300i "client handle unknown hash type striped directory"
24680
24681 test_300j() {
24682         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24684         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24685                 skip "Need MDS version at least 2.7.55"
24686
24687         local stripe_count
24688         local file
24689
24690         mkdir $DIR/$tdir
24691
24692         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
24693         $LCTL set_param fail_loc=0x1702
24694         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
24695                 error "set striped dir error"
24696
24697         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
24698                 error "create files under striped dir failed"
24699
24700         $LCTL set_param fail_loc=0
24701
24702         rm -rf $DIR/$tdir || error "unlink striped dir fails"
24703
24704         return 0
24705 }
24706 run_test 300j "test large update record"
24707
24708 test_300k() {
24709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24710         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24711         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24712                 skip "Need MDS version at least 2.7.55"
24713
24714         # this test needs a huge transaction
24715         local kb
24716         kb=$(do_facet $SINGLEMDS "$LCTL get_param -n \
24717              osd*.$FSNAME-MDT0000.kbytestotal")
24718         [ $kb -lt $((1024*1024)) ] && skip "MDT0 too small: $kb"
24719
24720         local stripe_count
24721         local file
24722
24723         mkdir $DIR/$tdir
24724
24725         #define OBD_FAIL_LARGE_STRIPE   0x1703
24726         $LCTL set_param fail_loc=0x1703
24727         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
24728                 error "set striped dir error"
24729         $LCTL set_param fail_loc=0
24730
24731         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24732                 error "getstripeddir fails"
24733         rm -rf $DIR/$tdir/striped_dir ||
24734                 error "unlink striped dir fails"
24735
24736         return 0
24737 }
24738 run_test 300k "test large striped directory"
24739
24740 test_300l() {
24741         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24742         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24743         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24744                 skip "Need MDS version at least 2.7.55"
24745
24746         local stripe_index
24747
24748         test_mkdir -p $DIR/$tdir/striped_dir
24749         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
24750                         error "chown $RUNAS_ID failed"
24751         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
24752                 error "set default striped dir failed"
24753
24754         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
24755         $LCTL set_param fail_loc=0x80000158
24756         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
24757
24758         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
24759         [ $stripe_index -eq 1 ] ||
24760                 error "expect 1 get $stripe_index for $dir"
24761 }
24762 run_test 300l "non-root user to create dir under striped dir with stale layout"
24763
24764 test_300m() {
24765         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24766         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
24767         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24768                 skip "Need MDS version at least 2.7.55"
24769
24770         mkdir -p $DIR/$tdir/striped_dir
24771         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
24772                 error "set default stripes dir error"
24773
24774         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
24775
24776         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
24777         [ $stripe_count -eq 0 ] ||
24778                         error "expect 0 get $stripe_count for a"
24779
24780         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
24781                 error "set default stripes dir error"
24782
24783         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
24784
24785         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
24786         [ $stripe_count -eq 0 ] ||
24787                         error "expect 0 get $stripe_count for b"
24788
24789         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
24790                 error "set default stripes dir error"
24791
24792         mkdir $DIR/$tdir/striped_dir/c &&
24793                 error "default stripe_index is invalid, mkdir c should fails"
24794
24795         rm -rf $DIR/$tdir || error "rmdir fails"
24796 }
24797 run_test 300m "setstriped directory on single MDT FS"
24798
24799 cleanup_300n() {
24800         local list=$(comma_list $(mdts_nodes))
24801
24802         trap 0
24803         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24804 }
24805
24806 test_300n() {
24807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24809         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24810                 skip "Need MDS version at least 2.7.55"
24811         remote_mds_nodsh && skip "remote MDS with nodsh"
24812
24813         local stripe_index
24814         local list=$(comma_list $(mdts_nodes))
24815
24816         trap cleanup_300n RETURN EXIT
24817         mkdir -p $DIR/$tdir
24818         chmod 777 $DIR/$tdir
24819         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
24820                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24821                 error "create striped dir succeeds with gid=0"
24822
24823         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24824         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
24825                 error "create striped dir fails with gid=-1"
24826
24827         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24828         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
24829                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
24830                 error "set default striped dir succeeds with gid=0"
24831
24832
24833         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
24834         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
24835                 error "set default striped dir fails with gid=-1"
24836
24837
24838         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
24839         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
24840                                         error "create test_dir fails"
24841         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
24842                                         error "create test_dir1 fails"
24843         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
24844                                         error "create test_dir2 fails"
24845         cleanup_300n
24846 }
24847 run_test 300n "non-root user to create dir under striped dir with default EA"
24848
24849 test_300o() {
24850         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24851         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24852         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24853                 skip "Need MDS version at least 2.7.55"
24854
24855         local numfree1
24856         local numfree2
24857
24858         mkdir -p $DIR/$tdir
24859
24860         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
24861         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
24862         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
24863                 skip "not enough free inodes $numfree1 $numfree2"
24864         fi
24865
24866         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
24867         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
24868         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
24869                 skip "not enough free space $numfree1 $numfree2"
24870         fi
24871
24872         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
24873                 error "setdirstripe fails"
24874
24875         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
24876                 error "create dirs fails"
24877
24878         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
24879         ls $DIR/$tdir/striped_dir > /dev/null ||
24880                 error "ls striped dir fails"
24881         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
24882                 error "unlink big striped dir fails"
24883 }
24884 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
24885
24886 test_300p() {
24887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24888         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24889         remote_mds_nodsh && skip "remote MDS with nodsh"
24890
24891         mkdir_on_mdt0 $DIR/$tdir
24892
24893         #define OBD_FAIL_OUT_ENOSPC     0x1704
24894         do_facet mds2 lctl set_param fail_loc=0x80001704
24895         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
24896                  && error "create striped directory should fail"
24897
24898         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
24899
24900         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
24901         true
24902 }
24903 run_test 300p "create striped directory without space"
24904
24905 test_300q() {
24906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
24907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
24908
24909         local fd=$(free_fd)
24910         local cmd="exec $fd<$tdir"
24911         cd $DIR
24912         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
24913         eval $cmd
24914         cmd="exec $fd<&-"
24915         trap "eval $cmd" EXIT
24916         cd $tdir || error "cd $tdir fails"
24917         rmdir  ../$tdir || error "rmdir $tdir fails"
24918         mkdir local_dir && error "create dir succeeds"
24919         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
24920         eval $cmd
24921         return 0
24922 }
24923 run_test 300q "create remote directory under orphan directory"
24924
24925 test_300r() {
24926         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24927                 skip "Need MDS version at least 2.7.55" && return
24928         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24929
24930         mkdir $DIR/$tdir
24931
24932         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
24933                 error "set striped dir error"
24934
24935         $LFS getdirstripe $DIR/$tdir/striped_dir ||
24936                 error "getstripeddir fails"
24937
24938         local stripe_count
24939         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
24940                       awk '/lmv_stripe_count:/ { print $2 }')
24941
24942         [ $MDSCOUNT -ne $stripe_count ] &&
24943                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
24944
24945         rm -rf $DIR/$tdir/striped_dir ||
24946                 error "unlink striped dir fails"
24947 }
24948 run_test 300r "test -1 striped directory"
24949
24950 test_300s_helper() {
24951         local count=$1
24952
24953         local stripe_dir=$DIR/$tdir/striped_dir.$count
24954
24955         $LFS mkdir -c $count $stripe_dir ||
24956                 error "lfs mkdir -c error"
24957
24958         $LFS getdirstripe $stripe_dir ||
24959                 error "lfs getdirstripe fails"
24960
24961         local stripe_count
24962         stripe_count=$($LFS getdirstripe $stripe_dir |
24963                       awk '/lmv_stripe_count:/ { print $2 }')
24964
24965         [ $count -ne $stripe_count ] &&
24966                 error_noexit "bad stripe count $stripe_count expected $count"
24967
24968         local dupe_stripes
24969         dupe_stripes=$($LFS getdirstripe $stripe_dir |
24970                 awk '/0x/ {count[$1] += 1}; END {
24971                         for (idx in count) {
24972                                 if (count[idx]>1) {
24973                                         print "index " idx " count " count[idx]
24974                                 }
24975                         }
24976                 }')
24977
24978         if [[ -n "$dupe_stripes" ]] ; then
24979                 lfs getdirstripe $stripe_dir
24980                 error_noexit "Dupe MDT above: $dupe_stripes "
24981         fi
24982
24983         rm -rf $stripe_dir ||
24984                 error_noexit "unlink $stripe_dir fails"
24985 }
24986
24987 test_300s() {
24988         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
24989                 skip "Need MDS version at least 2.7.55" && return
24990         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
24991
24992         mkdir $DIR/$tdir
24993         for count in $(seq 2 $MDSCOUNT); do
24994                 test_300s_helper $count
24995         done
24996 }
24997 run_test 300s "test lfs mkdir -c without -i"
24998
24999 test_300t() {
25000         (( $MDS1_VERSION >= $(version_code 2.14.55) )) ||
25001                 skip "need MDS 2.14.55 or later"
25002         (( $MDSCOUNT >= 2 )) || skip "needs at least 2 MDTs"
25003
25004         local testdir="$DIR/$tdir/striped_dir"
25005         local dir1=$testdir/dir1
25006         local dir2=$testdir/dir2
25007
25008         mkdir -p $testdir
25009
25010         $LFS setdirstripe -D -c -1 --max-inherit=3 $testdir ||
25011                 error "failed to set default stripe count for $testdir"
25012
25013         mkdir $dir1
25014         local stripe_count=$($LFS getdirstripe -c $dir1)
25015
25016         (( $stripe_count == $MDSCOUNT )) || error "wrong stripe count"
25017
25018         local max_count=$((MDSCOUNT - 1))
25019         local mdts=$(comma_list $(mdts_nodes))
25020
25021         do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=$max_count
25022         stack_trap "do_nodes $mdts $LCTL set_param lod.*.max_mdt_stripecount=0"
25023
25024         mkdir $dir2
25025         stripe_count=$($LFS getdirstripe -c $dir2)
25026
25027         (( $stripe_count == $max_count )) || error "wrong stripe count"
25028 }
25029 run_test 300t "test max_mdt_stripecount"
25030
25031 prepare_remote_file() {
25032         mkdir $DIR/$tdir/src_dir ||
25033                 error "create remote source failed"
25034
25035         cp /etc/hosts $DIR/$tdir/src_dir/a ||
25036                  error "cp to remote source failed"
25037         touch $DIR/$tdir/src_dir/a
25038
25039         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
25040                 error "create remote target dir failed"
25041
25042         touch $DIR/$tdir/tgt_dir/b
25043
25044         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
25045                 error "rename dir cross MDT failed!"
25046
25047         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
25048                 error "src_child still exists after rename"
25049
25050         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
25051                 error "missing file(a) after rename"
25052
25053         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
25054                 error "diff after rename"
25055 }
25056
25057 test_310a() {
25058         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25060
25061         local remote_file=$DIR/$tdir/tgt_dir/b
25062
25063         mkdir -p $DIR/$tdir
25064
25065         prepare_remote_file || error "prepare remote file failed"
25066
25067         #open-unlink file
25068         $OPENUNLINK $remote_file $remote_file ||
25069                 error "openunlink $remote_file failed"
25070         $CHECKSTAT -a $remote_file || error "$remote_file exists"
25071 }
25072 run_test 310a "open unlink remote file"
25073
25074 test_310b() {
25075         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
25076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25077
25078         local remote_file=$DIR/$tdir/tgt_dir/b
25079
25080         mkdir -p $DIR/$tdir
25081
25082         prepare_remote_file || error "prepare remote file failed"
25083
25084         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25085         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
25086         $CHECKSTAT -t file $remote_file || error "check file failed"
25087 }
25088 run_test 310b "unlink remote file with multiple links while open"
25089
25090 test_310c() {
25091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25092         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
25093
25094         local remote_file=$DIR/$tdir/tgt_dir/b
25095
25096         mkdir -p $DIR/$tdir
25097
25098         prepare_remote_file || error "prepare remote file failed"
25099
25100         ln $remote_file $DIR/$tfile || error "link failed for remote file"
25101         multiop_bg_pause $remote_file O_uc ||
25102                         error "mulitop failed for remote file"
25103         MULTIPID=$!
25104         $MULTIOP $DIR/$tfile Ouc
25105         kill -USR1 $MULTIPID
25106         wait $MULTIPID
25107 }
25108 run_test 310c "open-unlink remote file with multiple links"
25109
25110 #LU-4825
25111 test_311() {
25112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
25113         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25114         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
25115                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
25116         remote_mds_nodsh && skip "remote MDS with nodsh"
25117
25118         local old_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25119         local mdts=$(comma_list $(mdts_nodes))
25120
25121         mkdir -p $DIR/$tdir
25122         $LFS setstripe -i 0 -c 1 $DIR/$tdir
25123         createmany -o $DIR/$tdir/$tfile. 1000
25124
25125         # statfs data is not real time, let's just calculate it
25126         old_iused=$((old_iused + 1000))
25127
25128         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25129                         osp.*OST0000*MDT0000.create_count")
25130         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
25131                                 osp.*OST0000*MDT0000.max_create_count")
25132         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
25133
25134         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
25135         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
25136         [ $index -ne 0 ] || error "$tfile stripe index is 0"
25137
25138         unlinkmany $DIR/$tdir/$tfile. 1000
25139
25140         do_nodes $mdts "$LCTL set_param -n \
25141                         osp.*OST0000*.max_create_count=$max_count"
25142         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
25143                 do_nodes $mdts "$LCTL set_param -n \
25144                                 osp.*OST0000*.create_count=$count"
25145         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
25146                         grep "=0" && error "create_count is zero"
25147
25148         local new_iused
25149         for i in $(seq 120); do
25150                 new_iused=$($LFS df -i | awk '/OST0000/ { print $3; exit; }')
25151                 # system may be too busy to destroy all objs in time, use
25152                 # a somewhat small value to not fail autotest
25153                 [ $((old_iused - new_iused)) -gt 400 ] && break
25154                 sleep 1
25155         done
25156
25157         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
25158         [ $((old_iused - new_iused)) -gt 400 ] ||
25159                 error "objs not destroyed after unlink"
25160 }
25161 run_test 311 "disable OSP precreate, and unlink should destroy objs"
25162
25163 zfs_get_objid()
25164 {
25165         local ost=$1
25166         local tf=$2
25167         local fid=($($LFS getstripe $tf | grep 0x))
25168         local seq=${fid[3]#0x}
25169         local objid=${fid[1]}
25170
25171         local vdevdir=$(dirname $(facet_vdevice $ost))
25172         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
25173         local zfs_zapid=$(do_facet $ost $cmd |
25174                           grep -w "/O/$seq/d$((objid%32))" -C 5 |
25175                           awk '/Object/{getline; print $1}')
25176         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
25177                           awk "/$objid = /"'{printf $3}')
25178
25179         echo $zfs_objid
25180 }
25181
25182 zfs_object_blksz() {
25183         local ost=$1
25184         local objid=$2
25185
25186         local vdevdir=$(dirname $(facet_vdevice $ost))
25187         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
25188         local blksz=$(do_facet $ost $cmd $objid |
25189                       awk '/dblk/{getline; printf $4}')
25190
25191         case "${blksz: -1}" in
25192                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
25193                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
25194                 *) ;;
25195         esac
25196
25197         echo $blksz
25198 }
25199
25200 test_312() { # LU-4856
25201         remote_ost_nodsh && skip "remote OST with nodsh"
25202         [[ "$ost1_FSTYPE" == "zfs" ]] || skip "the test only applies to zfs"
25203
25204         local max_blksz=$(do_facet ost1 \
25205                           $ZFS get -p recordsize $(facet_device ost1) |
25206                           awk '!/VALUE/{print $3}')
25207         local tf=$DIR/$tfile
25208
25209         $LFS setstripe -c1 $tf
25210         local facet="ost$(($($LFS getstripe -i $tf) + 1))"
25211
25212         # Get ZFS object id
25213         local zfs_objid=$(zfs_get_objid $facet $tf)
25214         # block size change by sequential overwrite
25215         local bs
25216
25217         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
25218                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
25219
25220                 local blksz=$(zfs_object_blksz $facet $zfs_objid)
25221                 [[ $blksz -eq $bs ]] || error "blksz error: $blksz, expected: $bs"
25222         done
25223         rm -f $tf
25224
25225         $LFS setstripe -c1 $tf
25226         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25227
25228         # block size change by sequential append write
25229         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
25230         zfs_objid=$(zfs_get_objid $facet $tf)
25231         local count
25232
25233         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
25234                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
25235                         oflag=sync conv=notrunc
25236
25237                 blksz=$(zfs_object_blksz $facet $zfs_objid)
25238                 (( $blksz == 2 * count * PAGE_SIZE )) ||
25239                         error "blksz error, actual $blksz, " \
25240                                 "expected: 2 * $count * $PAGE_SIZE"
25241         done
25242         rm -f $tf
25243
25244         # random write
25245         $LFS setstripe -c1 $tf
25246         facet="ost$(($($LFS getstripe -i $tf) + 1))"
25247         zfs_objid=$(zfs_get_objid $facet $tf)
25248
25249         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
25250         blksz=$(zfs_object_blksz $facet $zfs_objid)
25251         (( blksz == PAGE_SIZE )) ||
25252                 error "blksz error: $blksz, expected: $PAGE_SIZE"
25253
25254         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
25255         blksz=$(zfs_object_blksz $facet $zfs_objid)
25256         (( blksz == 65536 )) || error "blksz error: $blksz, expected: 64k"
25257
25258         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
25259         blksz=$(zfs_object_blksz $facet $zfs_objid)
25260         (( blksz == 65536 )) || error "rewrite error: $blksz, expected: 64k"
25261 }
25262 run_test 312 "make sure ZFS adjusts its block size by write pattern"
25263
25264 test_313() {
25265         remote_ost_nodsh && skip "remote OST with nodsh"
25266
25267         local file=$DIR/$tfile
25268
25269         rm -f $file
25270         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
25271
25272         # define OBD_FAIL_TGT_RCVD_EIO           0x720
25273         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25274         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
25275                 error "write should failed"
25276         do_facet ost1 "$LCTL set_param fail_loc=0"
25277         rm -f $file
25278 }
25279 run_test 313 "io should fail after last_rcvd update fail"
25280
25281 test_314() {
25282         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
25283
25284         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
25285         do_facet ost1 "$LCTL set_param fail_loc=0x720"
25286         rm -f $DIR/$tfile
25287         wait_delete_completed
25288         do_facet ost1 "$LCTL set_param fail_loc=0"
25289 }
25290 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
25291
25292 test_315() { # LU-618
25293         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
25294
25295         local file=$DIR/$tfile
25296         rm -f $file
25297
25298         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
25299                 error "multiop file write failed"
25300         $MULTIOP $file oO_RDONLY:r4063232_c &
25301         PID=$!
25302
25303         sleep 2
25304
25305         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
25306         kill -USR1 $PID
25307
25308         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
25309         rm -f $file
25310 }
25311 run_test 315 "read should be accounted"
25312
25313 test_316() {
25314         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25315         large_xattr_enabled || skip "ea_inode feature disabled"
25316
25317         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
25318         mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
25319         chown nobody $DIR/$tdir/d || error "chown $tdir/d failed"
25320         touch $DIR/$tdir/d/$tfile || error "touch $tdir/d/$tfile failed"
25321
25322         $LFS migrate -m1 $DIR/$tdir/d || error "lfs migrate -m1 failed"
25323 }
25324 run_test 316 "lfs migrate of file with large_xattr enabled"
25325
25326 test_317() {
25327         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
25328                 skip "Need MDS version at least 2.11.53"
25329         if [ "$ost1_FSTYPE" == "zfs" ]; then
25330                 skip "LU-10370: no implementation for ZFS"
25331         fi
25332
25333         local trunc_sz
25334         local grant_blk_size
25335
25336         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
25337                         awk '/grant_block_size:/ { print $2; exit; }')
25338         #
25339         # Create File of size 5M. Truncate it to below size's and verify
25340         # blocks count.
25341         #
25342         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
25343                 error "Create file $DIR/$tfile failed"
25344         stack_trap "rm -f $DIR/$tfile" EXIT
25345
25346         for trunc_sz in 2097152 4097 4000 509 0; do
25347                 $TRUNCATE $DIR/$tfile $trunc_sz ||
25348                         error "truncate $tfile to $trunc_sz failed"
25349                 local sz=$(stat --format=%s $DIR/$tfile)
25350                 local blk=$(stat --format=%b $DIR/$tfile)
25351                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
25352                                      grant_blk_size) * 8))
25353
25354                 if [[ $blk -ne $trunc_blk ]]; then
25355                         $(which stat) $DIR/$tfile
25356                         error "Expected Block $trunc_blk got $blk for $tfile"
25357                 fi
25358
25359                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25360                         error "Expected Size $trunc_sz got $sz for $tfile"
25361         done
25362
25363         #
25364         # sparse file test
25365         # Create file with a hole and write actual 65536 bytes which aligned
25366         # with 4K and 64K PAGE_SIZE. Block count must be 128.
25367         #
25368         local bs=65536
25369         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 seek=5 conv=fsync ||
25370                 error "Create file : $DIR/$tfile"
25371
25372         #
25373         # Truncate to size $trunc_sz bytes. Strip tail blocks and leave only 8
25374         # blocks. The block count must drop to 8.
25375         #
25376         trunc_sz=$(($(stat --format=%s $DIR/$tfile) -
25377                 ((bs - grant_blk_size) + 1)))
25378         $TRUNCATE $DIR/$tfile $trunc_sz ||
25379                 error "truncate $tfile to $trunc_sz failed"
25380
25381         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
25382         sz=$(stat --format=%s $DIR/$tfile)
25383         blk=$(stat --format=%b $DIR/$tfile)
25384
25385         if [[ $blk -ne $trunc_bsz ]]; then
25386                 $(which stat) $DIR/$tfile
25387                 error "Expected Block $trunc_bsz got $blk for $tfile"
25388         fi
25389
25390         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
25391                 error "Expected Size $trunc_sz got $sz for $tfile"
25392 }
25393 run_test 317 "Verify blocks get correctly update after truncate"
25394
25395 test_318() {
25396         local llite_name="llite.$($LFS getname $MOUNT | awk '{print $1}')"
25397         local old_max_active=$($LCTL get_param -n \
25398                             ${llite_name}.max_read_ahead_async_active \
25399                             2>/dev/null)
25400
25401         $LCTL set_param llite.*.max_read_ahead_async_active=256
25402         local max_active=$($LCTL get_param -n \
25403                            ${llite_name}.max_read_ahead_async_active \
25404                            2>/dev/null)
25405         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
25406
25407         $LCTL set_param llite.*.max_read_ahead_async_active=0 ||
25408                 error "set max_read_ahead_async_active should succeed"
25409
25410         $LCTL set_param llite.*.max_read_ahead_async_active=512
25411         max_active=$($LCTL get_param -n \
25412                      ${llite_name}.max_read_ahead_async_active 2>/dev/null)
25413         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
25414
25415         # restore @max_active
25416         [ $old_max_active -ne 0 ] && $LCTL set_param \
25417                 llite.*.max_read_ahead_async_active=$old_max_active
25418
25419         local old_threshold=$($LCTL get_param -n \
25420                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25421         local max_per_file_mb=$($LCTL get_param -n \
25422                 ${llite_name}.max_read_ahead_per_file_mb 2>/dev/null)
25423
25424         local invalid=$(($max_per_file_mb + 1))
25425         $LCTL set_param \
25426                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
25427                         && error "set $invalid should fail"
25428
25429         local valid=$(($invalid - 1))
25430         $LCTL set_param \
25431                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
25432                         error "set $valid should succeed"
25433         local threshold=$($LCTL get_param -n \
25434                 ${llite_name}.read_ahead_async_file_threshold_mb 2>/dev/null)
25435         [ $threshold -eq $valid ] || error \
25436                 "expect threshold $valid got $threshold"
25437         $LCTL set_param \
25438                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
25439 }
25440 run_test 318 "Verify async readahead tunables"
25441
25442 test_319() {
25443         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
25444
25445         local before=$(date +%s)
25446         local evict
25447         local mdir=$DIR/$tdir
25448         local file=$mdir/xxx
25449
25450         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
25451         touch $file
25452
25453 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
25454         $LCTL set_param fail_val=5 fail_loc=0x8000032c
25455         $LFS migrate -m1 $mdir &
25456
25457         sleep 1
25458         dd if=$file of=/dev/null
25459         wait
25460         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
25461           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
25462
25463         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
25464 }
25465 run_test 319 "lost lease lock on migrate error"
25466
25467 test_398a() { # LU-4198
25468         local ost1_imp=$(get_osc_import_name client ost1)
25469         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25470                          cut -d'.' -f2)
25471
25472         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25473         $LCTL set_param ldlm.namespaces.*.lru_size=clear
25474
25475         # Disabled: DIO does not push out buffered I/O pages, see LU-12587
25476         # request a new lock on client
25477         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
25478
25479         #dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct conv=notrunc
25480         #local lock_count=$($LCTL get_param -n \
25481         #                  ldlm.namespaces.$imp_name.lru_size)
25482         #[[ $lock_count -eq 0 ]] || error "lock should be cancelled by direct IO"
25483
25484         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25485
25486         # no lock cached, should use lockless DIO and not enqueue new lock
25487         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct \
25488                 conv=notrunc ||
25489                 error "dio write failed"
25490         lock_count=$($LCTL get_param -n \
25491                      ldlm.namespaces.$imp_name.lru_size)
25492         [[ $lock_count -eq 0 ]] || error "no lock should be held by direct IO"
25493
25494         $LCTL set_param ldlm.namespaces.*-OST0000-osc-ffff*.lru_size=clear
25495
25496         # no lock cached, should use locked DIO append
25497         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=direct oflag=append \
25498                 conv=notrunc || error "DIO append failed"
25499         lock_count=$($LCTL get_param -n \
25500                      ldlm.namespaces.*-OST0000-osc-ffff*.lru_size)
25501         [[ $lock_count -ne 0 ]] || error "lock still must be held by DIO append"
25502 }
25503 run_test 398a "direct IO should cancel lock otherwise lockless"
25504
25505 test_398b() { # LU-4198
25506         local before=$(date +%s)
25507         local njobs=4
25508         local size=48
25509
25510         which fio || skip_env "no fio installed"
25511         $LFS setstripe -c -1 -S 1M $DIR/$tfile
25512         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size
25513
25514         # Single page, multiple pages, stripe size, 4*stripe size
25515         for bsize in $(( $PAGE_SIZE )) $(( 4*$PAGE_SIZE )) 1048576 4194304; do
25516                 echo "mix direct rw ${bsize} by fio with $njobs jobs..."
25517                 fio --name=rand-rw --rw=randrw --bs=$bsize --direct=1 \
25518                         --numjobs=$njobs --fallocate=none \
25519                         --iodepth=16 --allow_file_create=0 \
25520                         --size=$((size/njobs))M \
25521                         --filename=$DIR/$tfile &
25522                 bg_pid=$!
25523
25524                 echo "mix buffer rw ${bsize} by fio with $njobs jobs..."
25525                 fio --name=rand-rw --rw=randrw --bs=$bsize \
25526                         --numjobs=$njobs --fallocate=none \
25527                         --iodepth=16 --allow_file_create=0 \
25528                         --size=$((size/njobs))M \
25529                         --filename=$DIR/$tfile || true
25530                 wait $bg_pid
25531         done
25532
25533         evict=$(do_facet client $LCTL get_param \
25534                 osc.$FSNAME-OST*-osc-*/state |
25535             awk -F"[ [,]" '/EVICTED ]$/ { if (t<$5) {t=$5;} } END { print t }')
25536
25537         [ -z "$evict" ] || [[ $evict -le $before ]] ||
25538                 (do_facet client $LCTL get_param \
25539                         osc.$FSNAME-OST*-osc-*/state;
25540                     error "eviction happened: $evict before:$before")
25541
25542         rm -f $DIR/$tfile
25543 }
25544 run_test 398b "DIO and buffer IO race"
25545
25546 test_398c() { # LU-4198
25547         local ost1_imp=$(get_osc_import_name client ost1)
25548         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
25549                          cut -d'.' -f2)
25550
25551         which fio || skip_env "no fio installed"
25552
25553         saved_debug=$($LCTL get_param -n debug)
25554         $LCTL set_param debug=0
25555
25556         local size=$(lctl get_param -n osc.$FSNAME-OST0000*.kbytesavail | head -1)
25557         ((size /= 1024)) # by megabytes
25558         ((size /= 2)) # write half of the OST at most
25559         [ $size -gt 40 ] && size=40 #reduce test time anyway
25560
25561         $LFS setstripe -c 1 $DIR/$tfile
25562
25563         # it seems like ldiskfs reserves more space than necessary if the
25564         # writing blocks are not mapped, so it extends the file firstly
25565         dd if=/dev/zero of=$DIR/$tfile bs=1M count=$size && sync
25566         cancel_lru_locks osc
25567
25568         # clear and verify rpc_stats later
25569         $LCTL set_param osc.${FSNAME}-OST0000-osc-ffff*.rpc_stats=clear
25570
25571         local njobs=4
25572         echo "writing ${size}M to OST0 by fio with $njobs jobs..."
25573         fio --name=rand-write --rw=randwrite --bs=$PAGE_SIZE --direct=1 \
25574                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25575                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25576                 --filename=$DIR/$tfile
25577         [ $? -eq 0 ] || error "fio write error"
25578
25579         [ $($LCTL get_param -n ldlm.namespaces.$imp_name.lock_count) -eq 0 ] ||
25580                 error "Locks were requested while doing AIO"
25581
25582         # get the percentage of 1-page I/O
25583         pct=$($LCTL get_param osc.${imp_name}.rpc_stats |
25584                 grep -A 1 'pages per rpc' | grep -v 'pages per rpc' |
25585                 awk '{print $7}')
25586         [ $pct -le 50 ] || error "$pct% of I/O are 1-page"
25587
25588         echo "mix rw ${size}M to OST0 by fio with $njobs jobs..."
25589         fio --name=rand-rw --rw=randrw --bs=$PAGE_SIZE --direct=1 \
25590                 --numjobs=$njobs --fallocate=none --ioengine=libaio \
25591                 --iodepth=16 --allow_file_create=0 --size=$((size/njobs))M \
25592                 --filename=$DIR/$tfile
25593         [ $? -eq 0 ] || error "fio mixed read write error"
25594
25595         echo "AIO with large block size ${size}M"
25596         fio --name=rand-rw --rw=randrw --bs=${size}M --direct=1 \
25597                 --numjobs=1 --fallocate=none --ioengine=libaio \
25598                 --iodepth=16 --allow_file_create=0 --size=${size}M \
25599                 --filename=$DIR/$tfile
25600         [ $? -eq 0 ] || error "fio large block size failed"
25601
25602         rm -f $DIR/$tfile
25603         $LCTL set_param debug="$saved_debug"
25604 }
25605 run_test 398c "run fio to test AIO"
25606
25607 test_398d() { #  LU-13846
25608         which aiocp || skip_env "no aiocp installed"
25609         local aio_file=$DIR/$tfile.aio
25610
25611         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25612
25613         dd if=/dev/urandom of=$DIR/$tfile bs=1M count=64
25614         aiocp -a $PAGE_SIZE -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file
25615         stack_trap "rm -f $DIR/$tfile $aio_file"
25616
25617         diff $DIR/$tfile $aio_file || error "file diff after aiocp"
25618
25619         # make sure we don't crash and fail properly
25620         aiocp -a 512 -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25621                 error "aio not aligned with PAGE SIZE should fail"
25622
25623         rm -f $DIR/$tfile $aio_file
25624 }
25625 run_test 398d "run aiocp to verify block size > stripe size"
25626
25627 test_398e() {
25628         dd if=/dev/zero of=$DIR/$tfile bs=1234 count=1
25629         touch $DIR/$tfile.new
25630         dd if=$DIR/$tfile of=$DIR/$tfile.new bs=1M count=1 oflag=direct
25631 }
25632 run_test 398e "O_Direct open cleared by fcntl doesn't cause hang"
25633
25634 test_398f() { #  LU-14687
25635         which aiocp || skip_env "no aiocp installed"
25636         local aio_file=$DIR/$tfile.aio
25637
25638         $LFS setstripe -c -1 -S 1M $DIR/$tfile $aio_file
25639
25640         dd if=/dev/zero of=$DIR/$tfile bs=1M count=64
25641         stack_trap "rm -f $DIR/$tfile $aio_file"
25642
25643         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25644         $LCTL set_param fail_loc=0x1418
25645         # make sure we don't crash and fail properly
25646         aiocp -b 64M -s 64M -f O_DIRECT $DIR/$tfile $aio_file &&
25647                 error "aio with page allocation failure succeeded"
25648         $LCTL set_param fail_loc=0
25649         diff $DIR/$tfile $aio_file
25650         [[ $? != 0 ]] || error "no diff after failed aiocp"
25651 }
25652 run_test 398f "verify aio handles ll_direct_rw_pages errors correctly"
25653
25654 # NB: To get the parallel DIO behavior in LU-13798, there must be > 1
25655 # stripe and i/o size must be > stripe size
25656 # Old style synchronous DIO waits after submitting each chunk, resulting in a
25657 # single RPC in flight.  This test shows async DIO submission is working by
25658 # showing multiple RPCs in flight.
25659 test_398g() { #  LU-13798
25660         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25661
25662         # We need to do some i/o first to acquire enough grant to put our RPCs
25663         # in flight; otherwise a new connection may not have enough grant
25664         # available
25665         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25666                 error "parallel dio failed"
25667         stack_trap "rm -f $DIR/$tfile"
25668
25669         # Reduce RPC size to 1M to avoid combination in to larger RPCs
25670         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25671         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25672         stack_trap "$LCTL set_param -n $pages_per_rpc"
25673
25674         # Recreate file so it's empty
25675         rm -f $DIR/$tfile
25676         $LFS setstripe -o 0,0 -S 1M $DIR/$tfile
25677         #Pause rpc completion to guarantee we see multiple rpcs in flight
25678         #define OBD_FAIL_OST_BRW_PAUSE_BULK
25679         do_facet ost1 $LCTL set_param fail_loc=0x214 fail_val=2
25680         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25681
25682         # Clear rpc stats
25683         $LCTL set_param osc.*.rpc_stats=c
25684
25685         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25686                 error "parallel dio failed"
25687         stack_trap "rm -f $DIR/$tfile"
25688
25689         $LCTL get_param osc.*-OST0000-*.rpc_stats
25690         pct=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25691                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25692                 grep "8:" | awk '{print $8}')
25693         # We look at the "8 rpcs in flight" field, and verify A) it is present
25694         # and B) it includes all RPCs.  This proves we had 8 RPCs in flight,
25695         # as expected for an 8M DIO to a file with 1M stripes.
25696         [ $pct -eq 100 ] || error "we should see 8 RPCs in flight"
25697
25698         # Verify turning off parallel dio works as expected
25699         # Clear rpc stats
25700         $LCTL set_param osc.*.rpc_stats=c
25701         $LCTL set_param llite.*.parallel_dio=0
25702         stack_trap '$LCTL set_param llite.*.parallel_dio=1'
25703
25704         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=1 oflag=direct ||
25705                 error "dio with parallel dio disabled failed"
25706
25707         # Ideally, we would see only one RPC in flight here, but there is an
25708         # unavoidable race between i/o completion and RPC in flight counting,
25709         # so while only 1 i/o is in flight at a time, the RPC in flight counter
25710         # will sometimes exceed 1 (3 or 4 is not rare on VM testing).
25711         # So instead we just verify it's always < 8.
25712         $LCTL get_param osc.*-OST0000-*.rpc_stats
25713         ret=$($LCTL get_param osc.*-OST0000-*.rpc_stats |
25714                 grep -A 8 'rpcs in flight' | grep -v 'rpcs in flight' |
25715                 grep '^$' -B1 | grep . | awk '{print $1}')
25716         [ $ret != "8:" ] ||
25717                 error "we should see fewer than 8 RPCs in flight (saw $ret)"
25718 }
25719 run_test 398g "verify parallel dio async RPC submission"
25720
25721 test_398h() { #  LU-13798
25722         local dio_file=$DIR/$tfile.dio
25723
25724         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25725
25726         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25727         stack_trap "rm -f $DIR/$tfile $dio_file"
25728
25729         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct ||
25730                 error "parallel dio failed"
25731         diff $DIR/$tfile $dio_file
25732         [[ $? == 0 ]] || error "file diff after aiocp"
25733 }
25734 run_test 398h "verify correctness of read & write with i/o size >> stripe size"
25735
25736 test_398i() { #  LU-13798
25737         local dio_file=$DIR/$tfile.dio
25738
25739         $LFS setstripe -C 2 -S 1M $DIR/$tfile $dio_file
25740
25741         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25742         stack_trap "rm -f $DIR/$tfile $dio_file"
25743
25744         #define OBD_FAIL_LLITE_PAGE_ALLOC 0x1418
25745         $LCTL set_param fail_loc=0x1418
25746         # make sure we don't crash and fail properly
25747         dd if=$DIR/$tfile of=$dio_file bs=8M count=8 iflag=direct oflag=direct &&
25748                 error "parallel dio page allocation failure succeeded"
25749         diff $DIR/$tfile $dio_file
25750         [[ $? != 0 ]] || error "no diff after failed aiocp"
25751 }
25752 run_test 398i "verify parallel dio handles ll_direct_rw_pages errors correctly"
25753
25754 test_398j() { #  LU-13798
25755         # Stripe size > RPC size but less than i/o size tests split across
25756         # stripes and RPCs for individual i/o op
25757         $LFS setstripe -o 0,0 -S 4M $DIR/$tfile $DIR/$tfile.2
25758
25759         # Reduce RPC size to 1M to guarantee split to multiple RPCs per stripe
25760         local pages_per_rpc=$($LCTL get_param osc.*-OST0000-*.max_pages_per_rpc)
25761         $LCTL set_param osc.*-OST0000-*.max_pages_per_rpc=1M
25762         stack_trap "$LCTL set_param -n $pages_per_rpc"
25763
25764         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25765                 error "parallel dio write failed"
25766         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.2"
25767
25768         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct ||
25769                 error "parallel dio read failed"
25770         diff $DIR/$tfile $DIR/$tfile.2
25771         [[ $? == 0 ]] || error "file diff after parallel dio read"
25772 }
25773 run_test 398j "test parallel dio where stripe size > rpc_size"
25774
25775 test_398k() { #  LU-13798
25776         wait_delete_completed
25777         wait_mds_ost_sync
25778
25779         # 4 stripe file; we will cause out of space on OST0
25780         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25781
25782         # Fill OST0 (if it's not too large)
25783         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25784                    head -n1)
25785         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25786                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25787         fi
25788         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25789         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25790                 error "dd should fill OST0"
25791         stack_trap "rm -f $DIR/$tfile.1"
25792
25793         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct
25794         err=$?
25795
25796         ls -la $DIR/$tfile
25797         $CHECKSTAT -t file -s 0 $DIR/$tfile ||
25798                 error "file is not 0 bytes in size"
25799
25800         # dd above should not succeed, but don't error until here so we can
25801         # get debug info above
25802         [[ $err != 0 ]] ||
25803                 error "parallel dio write with enospc succeeded"
25804         stack_trap "rm -f $DIR/$tfile"
25805 }
25806 run_test 398k "test enospc on first stripe"
25807
25808 test_398l() { #  LU-13798
25809         wait_delete_completed
25810         wait_mds_ost_sync
25811
25812         # 4 stripe file; we will cause out of space on OST0
25813         # Note the 1M stripe size and the > 1M i/o size mean this ENOSPC
25814         # happens on the second i/o chunk we issue
25815         $LFS setstripe -o 1,0,1,0 -S 1M $DIR/$tfile $DIR/$tfile.2
25816
25817         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=2 oflag=direct
25818         stack_trap "rm -f $DIR/$tfile"
25819
25820         # Fill OST0 (if it's not too large)
25821         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
25822                    head -n1)
25823         if [[ $ORIGFREE -gt $MAXFREE ]]; then
25824                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
25825         fi
25826         $LFS setstripe -i 0 -c 1 $DIR/$tfile.1
25827         dd if=/dev/zero of=$DIR/$tfile.1 bs=1024 count=$MAXFREE &&
25828                 error "dd should fill OST0"
25829         stack_trap "rm -f $DIR/$tfile.1"
25830
25831         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 oflag=direct
25832         err=$?
25833         stack_trap "rm -f $DIR/$tfile.2"
25834
25835         # Check that short write completed as expected
25836         ls -la $DIR/$tfile.2
25837         $CHECKSTAT -t file -s 1048576 $DIR/$tfile.2 ||
25838                 error "file is not 1M in size"
25839
25840         # dd above should not succeed, but don't error until here so we can
25841         # get debug info above
25842         [[ $err != 0 ]] ||
25843                 error "parallel dio write with enospc succeeded"
25844
25845         # Truncate source file to same length as output file and diff them
25846         $TRUNCATE $DIR/$tfile 1048576
25847         diff $DIR/$tfile $DIR/$tfile.2
25848         [[ $? == 0 ]] || error "data incorrect after short write"
25849 }
25850 run_test 398l "test enospc on intermediate stripe/RPC"
25851
25852 test_398m() { #  LU-13798
25853         $LFS setstripe -o 0,1,0,1 -S 1M $DIR/$tfile
25854
25855         # Set up failure on OST0, the first stripe:
25856         #define OBD_FAIL_OST_BRW_WRITE_BULK     0x20e
25857         #NB: Fail val is ost # + 1, because we cannot use cfs_fail_val = 0
25858         # OST0 is on ost1, OST1 is on ost2.
25859         # So this fail_val specifies OST0
25860         do_facet ost1 $LCTL set_param fail_loc=0x20e fail_val=1
25861         stack_trap "do_facet ost1 $LCTL set_param fail_loc=0"
25862
25863         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25864                 error "parallel dio write with failure on first stripe succeeded"
25865         stack_trap "rm -f $DIR/$tfile"
25866         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25867
25868         # Place data in file for read
25869         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25870                 error "parallel dio write failed"
25871
25872         # Fail read on OST0, first stripe
25873         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25874         do_facet ost1 $LCTL set_param fail_loc=0x20f fail_val=1
25875         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25876                 error "parallel dio read with error on first stripe succeeded"
25877         rm -f $DIR/$tfile.2
25878         do_facet ost1 $LCTL set_param fail_loc=0 fail_val=0
25879
25880         # Switch to testing on OST1, second stripe
25881         # Clear file contents, maintain striping
25882         echo > $DIR/$tfile
25883         # Set up failure on OST1, second stripe:
25884         do_facet ost2 $LCTL set_param fail_loc=0x20e fail_val=2
25885         stack_trap "do_facet ost2 $LCTL set_param fail_loc=0"
25886
25887         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct &&
25888                 error "parallel dio write with failure on second stripe succeeded"
25889         stack_trap "rm -f $DIR/$tfile"
25890         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25891
25892         # Place data in file for read
25893         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 oflag=direct ||
25894                 error "parallel dio write failed"
25895
25896         # Fail read on OST1, second stripe
25897         #define OBD_FAIL_OST_BRW_READ_BULK       0x20f
25898         do_facet ost2 $LCTL set_param fail_loc=0x20f fail_val=2
25899         dd if=$DIR/$tfile of=$DIR/$tfile.2 bs=8M count=8 iflag=direct &&
25900                 error "parallel dio read with error on second stripe succeeded"
25901         rm -f $DIR/$tfile.2
25902         do_facet ost2 $LCTL set_param fail_loc=0 fail_val=0
25903 }
25904 run_test 398m "test RPC failures with parallel dio"
25905
25906 # Parallel submission of DIO should not cause problems for append, but it's
25907 # important to verify.
25908 test_398n() { #  LU-13798
25909         $LFS setstripe -C 2 -S 1M $DIR/$tfile
25910
25911         dd if=/dev/urandom of=$DIR/$tfile bs=8M count=8 ||
25912                 error "dd to create source file failed"
25913         stack_trap "rm -f $DIR/$tfile"
25914
25915         dd if=$DIR/$tfile of=$DIR/$tfile.1 bs=8M count=8 oflag=direct oflag=append ||
25916                 error "parallel dio write with failure on second stripe succeeded"
25917         stack_trap "rm -f $DIR/$tfile $DIR/$tfile.1"
25918         diff $DIR/$tfile $DIR/$tfile.1
25919         [[ $? == 0 ]] || error "data incorrect after append"
25920
25921 }
25922 run_test 398n "test append with parallel DIO"
25923
25924 test_398o() {
25925         directio rdwr $DIR/$tfile 0 1 1 || error "bad KMS"
25926 }
25927 run_test 398o "right kms with DIO"
25928
25929 test_fake_rw() {
25930         local read_write=$1
25931         if [ "$read_write" = "write" ]; then
25932                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
25933         elif [ "$read_write" = "read" ]; then
25934                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
25935         else
25936                 error "argument error"
25937         fi
25938
25939         # turn off debug for performance testing
25940         local saved_debug=$($LCTL get_param -n debug)
25941         $LCTL set_param debug=0
25942
25943         $LFS setstripe -c 1 -i 0 $DIR/$tfile
25944
25945         # get ost1 size - $FSNAME-OST0000
25946         local ost1_avail_size=$($LFS df $DIR | awk /${ost1_svc}/'{ print $4 }')
25947         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
25948         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
25949
25950         if [ "$read_write" = "read" ]; then
25951                 $TRUNCATE $DIR/$tfile $(expr 1048576 \* $blocks)
25952         fi
25953
25954         local start_time=$(date +%s.%N)
25955         $dd_cmd bs=1M count=$blocks oflag=sync ||
25956                 error "real dd $read_write error"
25957         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
25958
25959         if [ "$read_write" = "write" ]; then
25960                 rm -f $DIR/$tfile
25961         fi
25962
25963         # define OBD_FAIL_OST_FAKE_RW           0x238
25964         do_facet ost1 $LCTL set_param fail_loc=0x238
25965
25966         local start_time=$(date +%s.%N)
25967         $dd_cmd bs=1M count=$blocks oflag=sync ||
25968                 error "fake dd $read_write error"
25969         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
25970
25971         if [ "$read_write" = "write" ]; then
25972                 # verify file size
25973                 cancel_lru_locks osc
25974                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
25975                         error "$tfile size not $blocks MB"
25976         fi
25977         do_facet ost1 $LCTL set_param fail_loc=0
25978
25979         echo "fake $read_write $duration_fake vs. normal $read_write" \
25980                 "$duration in seconds"
25981         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
25982                 error_not_in_vm "fake write is slower"
25983
25984         $LCTL set_param -n debug="$saved_debug"
25985         rm -f $DIR/$tfile
25986 }
25987 test_399a() { # LU-7655 for OST fake write
25988         remote_ost_nodsh && skip "remote OST with nodsh"
25989
25990         test_fake_rw write
25991 }
25992 run_test 399a "fake write should not be slower than normal write"
25993
25994 test_399b() { # LU-8726 for OST fake read
25995         remote_ost_nodsh && skip "remote OST with nodsh"
25996         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
25997                 skip_env "ldiskfs only test"
25998         fi
25999
26000         test_fake_rw read
26001 }
26002 run_test 399b "fake read should not be slower than normal read"
26003
26004 test_400a() { # LU-1606, was conf-sanity test_74
26005         if ! which $CC > /dev/null 2>&1; then
26006                 skip_env "$CC is not installed"
26007         fi
26008
26009         local extra_flags=''
26010         local out=$TMP/$tfile
26011         local prefix=/usr/include/lustre
26012         local prog
26013
26014         # Oleg removes .c files in his test rig so test if any c files exist
26015         [[ -n "$(ls -A $LUSTRE_TESTS_API_DIR)" ]] ||
26016                 skip_env "Needed .c test files are missing"
26017
26018         if ! [[ -d $prefix ]]; then
26019                 # Assume we're running in tree and fixup the include path.
26020                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi"
26021                 extra_flags+=" -I$LUSTRE/include/uapi -I$LUSTRE/include"
26022                 extra_flags+=" -L$LUSTRE/utils/.libs"
26023         fi
26024
26025         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
26026                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
26027                         error "client api broken"
26028         done
26029         rm -f $out
26030 }
26031 run_test 400a "Lustre client api program can compile and link"
26032
26033 test_400b() { # LU-1606, LU-5011
26034         local header
26035         local out=$TMP/$tfile
26036         local prefix=/usr/include/linux/lustre
26037
26038         # We use a hard coded prefix so that this test will not fail
26039         # when run in tree. There are headers in lustre/include/lustre/
26040         # that are not packaged (like lustre_idl.h) and have more
26041         # complicated include dependencies (like config.h and lnet/types.h).
26042         # Since this test about correct packaging we just skip them when
26043         # they don't exist (see below) rather than try to fixup cppflags.
26044
26045         if ! which $CC > /dev/null 2>&1; then
26046                 skip_env "$CC is not installed"
26047         fi
26048
26049         for header in $prefix/*.h; do
26050                 if ! [[ -f "$header" ]]; then
26051                         continue
26052                 fi
26053
26054                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
26055                         continue # lustre_ioctl.h is internal header
26056                 fi
26057
26058                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
26059                         error "cannot compile '$header'"
26060         done
26061         rm -f $out
26062 }
26063 run_test 400b "packaged headers can be compiled"
26064
26065 test_401a() { #LU-7437
26066         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
26067         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
26068
26069         #count the number of parameters by "list_param -R"
26070         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
26071         #count the number of parameters by listing proc files
26072         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
26073         echo "proc_dirs='$proc_dirs'"
26074         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
26075         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
26076                       sort -u | wc -l)
26077
26078         [ $params -eq $procs ] ||
26079                 error "found $params parameters vs. $procs proc files"
26080
26081         # test the list_param -D option only returns directories
26082         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
26083         #count the number of parameters by listing proc directories
26084         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
26085                 sort -u | wc -l)
26086
26087         [ $params -eq $procs ] ||
26088                 error "found $params parameters vs. $procs proc files"
26089 }
26090 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
26091
26092 test_401b() {
26093         # jobid_var may not allow arbitrary values, so use jobid_name
26094         # if available
26095         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26096                 local testname=jobid_name tmp='testing%p'
26097         else
26098                 local testname=jobid_var tmp=testing
26099         fi
26100
26101         local save=$($LCTL get_param -n $testname)
26102
26103         $LCTL set_param foo=bar $testname=$tmp bar=baz &&
26104                 error "no error returned when setting bad parameters"
26105
26106         local jobid_new=$($LCTL get_param -n foe $testname baz)
26107         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
26108
26109         $LCTL set_param -n fog=bam $testname=$save bat=fog
26110         local jobid_old=$($LCTL get_param -n foe $testname bag)
26111         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
26112 }
26113 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
26114
26115 test_401c() {
26116         # jobid_var may not allow arbitrary values, so use jobid_name
26117         # if available
26118         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26119                 local testname=jobid_name
26120         else
26121                 local testname=jobid_var
26122         fi
26123
26124         local jobid_var_old=$($LCTL get_param -n $testname)
26125         local jobid_var_new
26126
26127         $LCTL set_param $testname= &&
26128                 error "no error returned for 'set_param a='"
26129
26130         jobid_var_new=$($LCTL get_param -n $testname)
26131         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26132                 error "$testname was changed by setting without value"
26133
26134         $LCTL set_param $testname &&
26135                 error "no error returned for 'set_param a'"
26136
26137         jobid_var_new=$($LCTL get_param -n $testname)
26138         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
26139                 error "$testname was changed by setting without value"
26140 }
26141 run_test 401c "Verify 'lctl set_param' without value fails in either format."
26142
26143 test_401d() {
26144         # jobid_var may not allow arbitrary values, so use jobid_name
26145         # if available
26146         if $LCTL list_param jobid_name > /dev/null 2>&1; then
26147                 local testname=jobid_name new_value='foo=bar%p'
26148         else
26149                 local testname=jobid_var new_valuie=foo=bar
26150         fi
26151
26152         local jobid_var_old=$($LCTL get_param -n $testname)
26153         local jobid_var_new
26154
26155         $LCTL set_param $testname=$new_value ||
26156                 error "'set_param a=b' did not accept a value containing '='"
26157
26158         jobid_var_new=$($LCTL get_param -n $testname)
26159         [[ "$jobid_var_new" == "$new_value" ]] ||
26160                 error "'set_param a=b' failed on a value containing '='"
26161
26162         # Reset the $testname to test the other format
26163         $LCTL set_param $testname=$jobid_var_old
26164         jobid_var_new=$($LCTL get_param -n $testname)
26165         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26166                 error "failed to reset $testname"
26167
26168         $LCTL set_param $testname $new_value ||
26169                 error "'set_param a b' did not accept a value containing '='"
26170
26171         jobid_var_new=$($LCTL get_param -n $testname)
26172         [[ "$jobid_var_new" == "$new_value" ]] ||
26173                 error "'set_param a b' failed on a value containing '='"
26174
26175         $LCTL set_param $testname $jobid_var_old
26176         jobid_var_new=$($LCTL get_param -n $testname)
26177         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
26178                 error "failed to reset $testname"
26179 }
26180 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
26181
26182 test_401e() { # LU-14779
26183         $LCTL list_param -R "ldlm.namespaces.MGC*" ||
26184                 error "lctl list_param MGC* failed"
26185         $LCTL get_param "ldlm.namespaces.MGC*" || error "lctl get_param failed"
26186         $LCTL get_param "ldlm.namespaces.MGC*.lru_size" ||
26187                 error "lctl get_param lru_size failed"
26188 }
26189 run_test 401e "verify 'lctl get_param' works with NID in parameter"
26190
26191 test_402() {
26192         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
26193         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
26194                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
26195         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
26196                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
26197                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
26198         remote_mds_nodsh && skip "remote MDS with nodsh"
26199
26200         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
26201 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
26202         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
26203         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
26204                 echo "Touch failed - OK"
26205 }
26206 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
26207
26208 test_403() {
26209         local file1=$DIR/$tfile.1
26210         local file2=$DIR/$tfile.2
26211         local tfile=$TMP/$tfile
26212
26213         rm -f $file1 $file2 $tfile
26214
26215         touch $file1
26216         ln $file1 $file2
26217
26218         # 30 sec OBD_TIMEOUT in ll_getattr()
26219         # right before populating st_nlink
26220         $LCTL set_param fail_loc=0x80001409
26221         stat -c %h $file1 > $tfile &
26222
26223         # create an alias, drop all locks and reclaim the dentry
26224         < $file2
26225         cancel_lru_locks mdc
26226         cancel_lru_locks osc
26227         sysctl -w vm.drop_caches=2
26228
26229         wait
26230
26231         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
26232
26233         rm -f $tfile $file1 $file2
26234 }
26235 run_test 403 "i_nlink should not drop to zero due to aliasing"
26236
26237 test_404() { # LU-6601
26238         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
26239                 skip "Need server version newer than 2.8.52"
26240         remote_mds_nodsh && skip "remote MDS with nodsh"
26241
26242         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
26243                 awk '/osp .*-osc-MDT/ { print $4}')
26244
26245         local osp
26246         for osp in $mosps; do
26247                 echo "Deactivate: " $osp
26248                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
26249                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26250                         awk -vp=$osp '$4 == p { print $2 }')
26251                 [ $stat = IN ] || {
26252                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26253                         error "deactivate error"
26254                 }
26255                 echo "Activate: " $osp
26256                 do_facet $SINGLEMDS $LCTL --device %$osp activate
26257                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
26258                         awk -vp=$osp '$4 == p { print $2 }')
26259                 [ $stat = UP ] || {
26260                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
26261                         error "activate error"
26262                 }
26263         done
26264 }
26265 run_test 404 "validate manual {de}activated works properly for OSPs"
26266
26267 test_405() {
26268         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
26269         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
26270                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
26271                         skip "Layout swap lock is not supported"
26272
26273         check_swap_layouts_support
26274         check_swap_layout_no_dom $DIR
26275
26276         test_mkdir $DIR/$tdir
26277         swap_lock_test -d $DIR/$tdir ||
26278                 error "One layout swap locked test failed"
26279 }
26280 run_test 405 "Various layout swap lock tests"
26281
26282 test_406() {
26283         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26284         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
26285         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
26286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
26287         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
26288                 skip "Need MDS version at least 2.8.50"
26289
26290         local def_stripe_size=$($LFS getstripe -S $MOUNT)
26291         local test_pool=$TESTNAME
26292
26293         pool_add $test_pool || error "pool_add failed"
26294         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
26295                 error "pool_add_targets failed"
26296
26297         save_layout_restore_at_exit $MOUNT
26298
26299         # parent set default stripe count only, child will stripe from both
26300         # parent and fs default
26301         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
26302                 error "setstripe $MOUNT failed"
26303         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
26304         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
26305         for i in $(seq 10); do
26306                 local f=$DIR/$tdir/$tfile.$i
26307                 touch $f || error "touch failed"
26308                 local count=$($LFS getstripe -c $f)
26309                 [ $count -eq $OSTCOUNT ] ||
26310                         error "$f stripe count $count != $OSTCOUNT"
26311                 local offset=$($LFS getstripe -i $f)
26312                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
26313                 local size=$($LFS getstripe -S $f)
26314                 [ $size -eq $((def_stripe_size * 2)) ] ||
26315                         error "$f stripe size $size != $((def_stripe_size * 2))"
26316                 local pool=$($LFS getstripe -p $f)
26317                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
26318         done
26319
26320         # change fs default striping, delete parent default striping, now child
26321         # will stripe from new fs default striping only
26322         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
26323                 error "change $MOUNT default stripe failed"
26324         $LFS setstripe -c 0 $DIR/$tdir ||
26325                 error "delete $tdir default stripe failed"
26326         for i in $(seq 11 20); do
26327                 local f=$DIR/$tdir/$tfile.$i
26328                 touch $f || error "touch $f failed"
26329                 local count=$($LFS getstripe -c $f)
26330                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
26331                 local offset=$($LFS getstripe -i $f)
26332                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
26333                 local size=$($LFS getstripe -S $f)
26334                 [ $size -eq $def_stripe_size ] ||
26335                         error "$f stripe size $size != $def_stripe_size"
26336                 local pool=$($LFS getstripe -p $f)
26337                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
26338         done
26339
26340         unlinkmany $DIR/$tdir/$tfile. 1 20
26341
26342         local f=$DIR/$tdir/$tfile
26343         pool_remove_all_targets $test_pool $f
26344         pool_remove $test_pool $f
26345 }
26346 run_test 406 "DNE support fs default striping"
26347
26348 test_407() {
26349         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
26350         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
26351                 skip "Need MDS version at least 2.8.55"
26352         remote_mds_nodsh && skip "remote MDS with nodsh"
26353
26354         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
26355                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
26356         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
26357                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
26358         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
26359
26360         #define OBD_FAIL_DT_TXN_STOP    0x2019
26361         for idx in $(seq $MDSCOUNT); do
26362                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
26363         done
26364         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
26365         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
26366                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
26367         true
26368 }
26369 run_test 407 "transaction fail should cause operation fail"
26370
26371 test_408() {
26372         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
26373
26374         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
26375         lctl set_param fail_loc=0x8000040a
26376         # let ll_prepare_partial_page() fail
26377         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
26378
26379         rm -f $DIR/$tfile
26380
26381         # create at least 100 unused inodes so that
26382         # shrink_icache_memory(0) should not return 0
26383         touch $DIR/$tfile-{0..100}
26384         rm -f $DIR/$tfile-{0..100}
26385         sync
26386
26387         echo 2 > /proc/sys/vm/drop_caches
26388 }
26389 run_test 408 "drop_caches should not hang due to page leaks"
26390
26391 test_409()
26392 {
26393         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
26394
26395         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
26396         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
26397         touch $DIR/$tdir/guard || error "(2) Fail to create"
26398
26399         local PREFIX=$(str_repeat 'A' 128)
26400         echo "Create 1K hard links start at $(date)"
26401         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26402                 error "(3) Fail to hard link"
26403
26404         echo "Links count should be right although linkEA overflow"
26405         stat $DIR/$tdir/guard || error "(4) Fail to stat"
26406         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
26407         [ $linkcount -eq 1001 ] ||
26408                 error "(5) Unexpected hard links count: $linkcount"
26409
26410         echo "List all links start at $(date)"
26411         ls -l $DIR/$tdir/foo > /dev/null ||
26412                 error "(6) Fail to list $DIR/$tdir/foo"
26413
26414         echo "Unlink hard links start at $(date)"
26415         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
26416                 error "(7) Fail to unlink"
26417         echo "Unlink hard links finished at $(date)"
26418 }
26419 run_test 409 "Large amount of cross-MDTs hard links on the same file"
26420
26421 test_410()
26422 {
26423         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
26424                 skip "Need client version at least 2.9.59"
26425         [ -f $LUSTRE/tests/kernel/kinode.ko ] ||
26426                 skip "Need MODULES build"
26427
26428         # Create a file, and stat it from the kernel
26429         local testfile=$DIR/$tfile
26430         touch $testfile
26431
26432         local run_id=$RANDOM
26433         local my_ino=$(stat --format "%i" $testfile)
26434
26435         # Try to insert the module. This will always fail as the
26436         # module is designed to not be inserted.
26437         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
26438             &> /dev/null
26439
26440         # Anything but success is a test failure
26441         dmesg | grep -q \
26442             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
26443             error "no inode match"
26444 }
26445 run_test 410 "Test inode number returned from kernel thread"
26446
26447 cleanup_test411_cgroup() {
26448         trap 0
26449         rmdir "$1"
26450 }
26451
26452 test_411() {
26453         local cg_basedir=/sys/fs/cgroup/memory
26454         # LU-9966
26455         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
26456                 skip "no setup for cgroup"
26457
26458         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
26459                 error "test file creation failed"
26460         cancel_lru_locks osc
26461
26462         # Create a very small memory cgroup to force a slab allocation error
26463         local cgdir=$cg_basedir/osc_slab_alloc
26464         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
26465         trap "cleanup_test411_cgroup $cgdir" EXIT
26466         echo 2M > $cgdir/memory.kmem.limit_in_bytes
26467         echo 1M > $cgdir/memory.limit_in_bytes
26468
26469         # Should not LBUG, just be killed by oom-killer
26470         # dd will return 0 even allocation failure in some environment.
26471         # So don't check return value
26472         bash -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
26473         cleanup_test411_cgroup $cgdir
26474
26475         return 0
26476 }
26477 run_test 411 "Slab allocation error with cgroup does not LBUG"
26478
26479 test_412() {
26480         (( $MDSCOUNT > 1 )) || skip_env "needs >= 2 MDTs"
26481         (( $MDS1_VERSION >= $(version_code 2.10.55) )) ||
26482                 skip "Need server version at least 2.10.55"
26483
26484         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
26485                 error "mkdir failed"
26486         $LFS getdirstripe $DIR/$tdir
26487         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
26488         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
26489                 error "expect $((MDSCOUT - 1)) get $stripe_index"
26490         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
26491         [ $stripe_count -eq 2 ] ||
26492                 error "expect 2 get $stripe_count"
26493
26494         (( $MDS1_VERSION >= $(version_code 2.14.55) )) || return 0
26495
26496         local index
26497         local index2
26498
26499         # subdirs should be on the same MDT as parent
26500         for i in $(seq 0 $((MDSCOUNT - 1))); do
26501                 $LFS mkdir -i $i $DIR/$tdir/mdt$i || error "mkdir mdt$i failed"
26502                 mkdir $DIR/$tdir/mdt$i/sub || error "mkdir sub failed"
26503                 index=$($LFS getstripe -m $DIR/$tdir/mdt$i/sub)
26504                 (( index == i )) || error "mdt$i/sub on MDT$index"
26505         done
26506
26507         # stripe offset -1, ditto
26508         for i in {1..10}; do
26509                 $LFS mkdir -i -1 $DIR/$tdir/qos$i || error "mkdir qos$i failed"
26510                 index=$($LFS getstripe -m $DIR/$tdir/qos$i)
26511                 mkdir $DIR/$tdir/qos$i/sub || error "mkdir sub failed"
26512                 index2=$($LFS getstripe -m $DIR/$tdir/qos$i/sub)
26513                 (( index == index2 )) ||
26514                         error "qos$i on MDT$index, sub on MDT$index2"
26515         done
26516
26517         local testdir=$DIR/$tdir/inherit
26518
26519         $LFS mkdir -i 1 --max-inherit=3 $testdir || error "mkdir inherit failed"
26520         # inherit 2 levels
26521         for i in 1 2; do
26522                 testdir=$testdir/s$i
26523                 mkdir $testdir || error "mkdir $testdir failed"
26524                 index=$($LFS getstripe -m $testdir)
26525                 (( index == 1 )) ||
26526                         error "$testdir on MDT$index"
26527         done
26528
26529         # not inherit any more
26530         testdir=$testdir/s3
26531         mkdir $testdir || error "mkdir $testdir failed"
26532         getfattr -d -m dmv $testdir | grep dmv &&
26533                 error "default LMV set on $testdir" || true
26534 }
26535 run_test 412 "mkdir on specific MDTs"
26536
26537 TEST413_COUNT=${TEST413_COUNT:-200}
26538
26539 #
26540 # set_maxage() is used by test_413 only.
26541 # This is a helper function to set maxage. Does not return any value.
26542 # Input: maxage to set
26543 #
26544 set_maxage() {
26545         local lmv_qos_maxage
26546         local lod_qos_maxage
26547         local new_maxage=$1
26548
26549         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26550         $LCTL set_param lmv.*.qos_maxage=$new_maxage
26551         stack_trap "$LCTL set_param \
26552                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
26553         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26554                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26555         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26556                 lod.*.mdt_qos_maxage=$new_maxage
26557         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26558                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null"
26559 }
26560
26561 generate_uneven_mdts() {
26562         local threshold=$1
26563         local ffree
26564         local bavail
26565         local max
26566         local min
26567         local max_index
26568         local min_index
26569         local tmp
26570         local i
26571
26572         echo
26573         echo "Check for uneven MDTs: "
26574
26575         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26576         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26577         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26578
26579         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26580         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26581         max_index=0
26582         min_index=0
26583         for ((i = 1; i < ${#ffree[@]}; i++)); do
26584                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26585                 if [ $tmp -gt $max ]; then
26586                         max=$tmp
26587                         max_index=$i
26588                 fi
26589                 if [ $tmp -lt $min ]; then
26590                         min=$tmp
26591                         min_index=$i
26592                 fi
26593         done
26594
26595         (( min > 0 )) || skip "low space on MDT$min_index"
26596         (( ${ffree[min_index]} > 0 )) ||
26597                 skip "no free files on MDT$min_index"
26598         (( ${ffree[min_index]} < 10000000 )) ||
26599                 skip "too many free files on MDT$min_index"
26600
26601         # Check if we need to generate uneven MDTs
26602         local diff=$(((max - min) * 100 / min))
26603         local testdirp=$DIR/$tdir-fillmdt # parent fill folder
26604         local testdir # individual folder within $testdirp
26605         local start
26606         local cmd
26607
26608         # fallocate is faster to consume space on MDT, if available
26609         if check_fallocate_supported mds$((min_index + 1)); then
26610                 cmd="fallocate -l 128K "
26611         else
26612                 cmd="dd if=/dev/zero bs=128K count=1 of="
26613         fi
26614
26615         echo "using cmd $cmd"
26616         for (( i = 0; diff < threshold; i++ )); do
26617                 testdir=${testdirp}/$i
26618                 [ -d $testdir ] && continue
26619
26620                 (( i % 10 > 0 )) || { $LFS df; $LFS df -i; }
26621
26622                 mkdir -p $testdirp
26623                 # generate uneven MDTs, create till $threshold% diff
26624                 echo -n "weight diff=$diff% must be > $threshold% ..."
26625                 echo "Fill MDT$min_index with $TEST413_COUNT files: loop $i"
26626                 $LFS mkdir -i $min_index $testdir ||
26627                         error "mkdir $testdir failed"
26628                 $LFS setstripe -E 1M -L mdt $testdir ||
26629                         error "setstripe $testdir failed"
26630                 start=$SECONDS
26631                 for (( f = 0; f < TEST413_COUNT; f++ )); do
26632                         $cmd$testdir/f.$f &> /dev/null || error "$cmd $f failed"
26633                 done
26634                 sync; sleep 1; sync
26635
26636                 # wait for QOS to update
26637                 (( SECONDS < start + 2 )) && sleep $((start + 2 - SECONDS))
26638
26639                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
26640                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
26641                 max=$(((${ffree[max_index]} >> 8) *
26642                         (${bavail[max_index]} * bsize >> 16)))
26643                 min=$(((${ffree[min_index]} >> 8) *
26644                         (${bavail[min_index]} * bsize >> 16)))
26645                 (( min > 0 )) || skip "low space on MDT$min_index"
26646                 diff=$(((max - min) * 100 / min))
26647         done
26648
26649         echo "MDT filesfree available: ${ffree[*]}"
26650         echo "MDT blocks available: ${bavail[*]}"
26651         echo "weight diff=$diff%"
26652 }
26653
26654 test_qos_mkdir() {
26655         local mkdir_cmd=$1
26656         local stripe_count=$2
26657         local mdts=$(comma_list $(mdts_nodes))
26658
26659         local testdir
26660         local lmv_qos_prio_free
26661         local lmv_qos_threshold_rr
26662         local lod_qos_prio_free
26663         local lod_qos_threshold_rr
26664         local total
26665         local count
26666         local i
26667
26668         # @total is total directories created if it's testing plain
26669         # directories, otherwise it's total stripe object count for
26670         # striped directories test.
26671         # remote/striped directory unlinking is slow on zfs and may
26672         # timeout, test with fewer directories
26673         [ "$mds1_FSTYPE" = "zfs" ] && total=120 || total=240
26674
26675         lmv_qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
26676         lmv_qos_prio_free=${lmv_qos_prio_free%%%}
26677         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26678                 head -n1)
26679         lmv_qos_threshold_rr=${lmv_qos_threshold_rr%%%}
26680         stack_trap "$LCTL set_param \
26681                 lmv.*.qos_prio_free=$lmv_qos_prio_free > /dev/null"
26682         stack_trap "$LCTL set_param \
26683                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null"
26684
26685         lod_qos_prio_free=$(do_facet mds1 $LCTL get_param -n \
26686                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_prio_free | head -n1)
26687         lod_qos_prio_free=${lod_qos_prio_free%%%}
26688         lod_qos_threshold_rr=$(do_facet mds1 $LCTL get_param -n \
26689                 lod.$FSNAME-MDT0000-mdtlov.mdt_qos_threshold_rr | head -n1)
26690         lod_qos_threshold_rr=${lod_qos_threshold_rr%%%}
26691         stack_trap "do_nodes $mdts $LCTL set_param \
26692                 lod.*.mdt_qos_prio_free=$lod_qos_prio_free > /dev/null"
26693         stack_trap "do_nodes $mdts $LCTL set_param \
26694                 lod.*.mdt_qos_threshold_rr=$lod_qos_threshold_rr > /dev/null"
26695
26696         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
26697         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=100 > /dev/null
26698
26699         testdir=$DIR/$tdir-s$stripe_count/rr
26700
26701         local stripe_index=$($LFS getstripe -m $testdir)
26702         local test_mkdir_rr=true
26703
26704         getfattr -d -m dmv -e hex $testdir | grep dmv
26705         if (( $? == 0 && $MDS1_VERSION >= $(version_code 2.14.51) )); then
26706                 echo "defstripe: '$($LFS getdirstripe -D $testdir)'"
26707                 (( $($LFS getdirstripe -D --max-inherit-rr $testdir) == 0 )) &&
26708                         test_mkdir_rr=false
26709         fi
26710
26711         echo
26712         $test_mkdir_rr &&
26713                 echo "Mkdir (stripe_count $stripe_count) roundrobin:" ||
26714                 echo "Mkdir (stripe_count $stripe_count) on stripe $stripe_index"
26715
26716         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26717         for (( i = 0; i < total / stripe_count; i++ )); do
26718                 eval $mkdir_cmd $testdir/subdir$i ||
26719                         error "$mkdir_cmd subdir$i failed"
26720         done
26721
26722         for (( i = 0; i < $MDSCOUNT; i++ )); do
26723                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26724                 echo "$count directories created on MDT$i"
26725                 if $test_mkdir_rr; then
26726                         (( count == total / stripe_count / MDSCOUNT )) ||
26727                                 error "subdirs are not evenly distributed"
26728                 elif (( i == stripe_index )); then
26729                         (( count == total / stripe_count )) ||
26730                                 error "$count subdirs created on MDT$i"
26731                 else
26732                         (( count == 0 )) ||
26733                                 error "$count subdirs created on MDT$i"
26734                 fi
26735
26736                 if $test_mkdir_rr && [ $stripe_count -gt 1 ]; then
26737                         count=$($LFS getdirstripe $testdir/* |
26738                                 grep -c -P "^\s+$i\t")
26739                         echo "$count stripes created on MDT$i"
26740                         # deviation should < 5% of average
26741                         delta=$((count - total / MDSCOUNT))
26742                         (( ${delta#-} <= total / MDSCOUNT / 20 )) ||
26743                                 error "stripes are not evenly distributed"
26744                 fi
26745         done
26746
26747         echo
26748         echo "Check for uneven MDTs: "
26749
26750         local ffree
26751         local bavail
26752         local max
26753         local min
26754         local max_index
26755         local min_index
26756         local tmp
26757
26758         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26759         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26760         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26761
26762         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26763         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26764         max_index=0
26765         min_index=0
26766         for ((i = 1; i < ${#ffree[@]}; i++)); do
26767                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26768                 if [ $tmp -gt $max ]; then
26769                         max=$tmp
26770                         max_index=$i
26771                 fi
26772                 if [ $tmp -lt $min ]; then
26773                         min=$tmp
26774                         min_index=$i
26775                 fi
26776         done
26777         echo "stripe_count=$stripe_count min_idx=$min_index max_idx=$max_index"
26778
26779         (( min > 0 )) || skip "low space on MDT$min_index"
26780         (( ${ffree[min_index]} < 10000000 )) ||
26781                 skip "too many free files on MDT$min_index"
26782
26783         generate_uneven_mdts 120
26784
26785         echo "MDT filesfree available: ${ffree[*]}"
26786         echo "MDT blocks available: ${bavail[*]}"
26787         echo "weight diff=$(((max - min) * 100 / min))%"
26788         echo
26789         echo "Mkdir (stripe_count $stripe_count) with balanced space usage:"
26790
26791         $LCTL set_param lmv.*.qos_threshold_rr=0 > /dev/null
26792         $LCTL set_param lmv.*.qos_prio_free=100 > /dev/null
26793         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_threshold_rr=0 > /dev/null
26794         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_prio_free=100 > /dev/null
26795         # decrease statfs age, so that it can be updated in time
26796         $LCTL set_param lmv.*.qos_maxage=1 > /dev/null
26797         do_nodes $mdts $LCTL set_param lod.*.mdt_qos_maxage=1 > /dev/null
26798
26799         sleep 1
26800
26801         testdir=$DIR/$tdir-s$stripe_count/qos
26802
26803         stack_trap "unlinkmany -d $testdir/subdir $((total / stripe_count))"
26804         for (( i = 0; i < total / stripe_count; i++ )); do
26805                 eval $mkdir_cmd $testdir/subdir$i ||
26806                         error "$mkdir_cmd subdir$i failed"
26807         done
26808
26809         max=0
26810         for (( i = 0; i < $MDSCOUNT; i++ )); do
26811                 count=$($LFS getdirstripe -i $testdir/* | grep -c "^$i$")
26812                 (( count > max )) && max=$count
26813                 echo "$count directories created on MDT$i : curmax=$max"
26814         done
26815
26816         min=$($LFS getdirstripe -i $testdir/* | grep -c "^$min_index$")
26817
26818         # D-value should > 10% of average
26819         (( max - min > total / stripe_count / MDSCOUNT / 10 )) ||
26820                 error "subdirs shouldn't be evenly distributed: $max - $min <= $((total / stripe_count / MDSCOUNT / 10))"
26821
26822         # ditto for stripes
26823         if (( stripe_count > 1 )); then
26824                 max=0
26825                 for (( i = 0; i < $MDSCOUNT; i++ )); do
26826                         count=$($LFS getdirstripe $testdir/* |
26827                                 grep -c -P "^\s+$i\t")
26828                         (( count > max )) && max=$count
26829                         echo "$count stripes created on MDT$i"
26830                 done
26831
26832                 min=$($LFS getdirstripe $testdir/* |
26833                         grep -c -P "^\s+$min_index\t")
26834                 (( max - min > total / MDSCOUNT / 10 )) ||
26835                         error "stripes shouldn't be evenly distributed: $max - $min <= $((total / MDSCOUNT / 10))"
26836         fi
26837 }
26838
26839 most_full_mdt() {
26840         local ffree
26841         local bavail
26842         local bsize
26843         local min
26844         local min_index
26845         local tmp
26846
26847         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
26848         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
26849         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
26850
26851         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
26852         min_index=0
26853         for ((i = 1; i < ${#ffree[@]}; i++)); do
26854                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
26855                 (( tmp < min )) && min=$tmp && min_index=$i
26856         done
26857
26858         echo -n $min_index
26859 }
26860
26861 test_413a() {
26862         [ $MDSCOUNT -lt 2 ] &&
26863                 skip "We need at least 2 MDTs for this test"
26864
26865         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26866                 skip "Need server version at least 2.12.52"
26867
26868         local stripe_max=$((MDSCOUNT - 1))
26869         local stripe_count
26870
26871         # let caller set maxage for latest result
26872         set_maxage 1
26873
26874         # fill MDT unevenly
26875         generate_uneven_mdts 120
26876
26877         # test 4-stripe directory at most, otherwise it's too slow
26878         # We are being very defensive. Although Autotest uses 4 MDTs.
26879         # We make sure stripe_max does not go over 4.
26880         (( stripe_max > 4 )) && stripe_max=4
26881         # unlinking striped directory is slow on zfs, and may timeout, only test
26882         # plain directory
26883         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26884         for stripe_count in $(seq 1 $stripe_max); do
26885                 mkdir $DIR/$tdir-s$stripe_count || error "mkdir failed"
26886                 mkdir $DIR/$tdir-s$stripe_count/rr || error "mkdir failed"
26887                 $LFS mkdir -i $(most_full_mdt) $DIR/$tdir-s$stripe_count/qos ||
26888                         error "mkdir failed"
26889                 test_qos_mkdir "$LFS mkdir -i -1 -c $stripe_count" $stripe_count
26890         done
26891 }
26892 run_test 413a "QoS mkdir with 'lfs mkdir -i -1'"
26893
26894 test_413b() {
26895         [ $MDSCOUNT -lt 2 ] &&
26896                 skip "We need at least 2 MDTs for this test"
26897
26898         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
26899                 skip "Need server version at least 2.12.52"
26900
26901         local stripe_max=$((MDSCOUNT - 1))
26902         local testdir
26903         local stripe_count
26904
26905         # let caller set maxage for latest result
26906         set_maxage 1
26907
26908         # fill MDT unevenly
26909         generate_uneven_mdts 120
26910
26911         # test 4-stripe directory at most, otherwise it's too slow
26912         # We are being very defensive. Although Autotest uses 4 MDTs.
26913         # We make sure stripe_max does not go over 4.
26914         (( stripe_max > 4 )) && stripe_max=4
26915         [ "$mds1_FSTYPE" == "zfs" ] && stripe_max=1
26916         for stripe_count in $(seq 1 $stripe_max); do
26917                 testdir=$DIR/$tdir-s$stripe_count
26918                 mkdir $testdir || error "mkdir $testdir failed"
26919                 mkdir $testdir/rr || error "mkdir rr failed"
26920                 $LFS mkdir -i $(most_full_mdt) $testdir/qos ||
26921                         error "mkdir qos failed"
26922                 $LFS setdirstripe -D -c $stripe_count --max-inherit-rr 2 \
26923                         $testdir/rr || error "setdirstripe rr failed"
26924                 $LFS setdirstripe -D -c $stripe_count $testdir/qos ||
26925                         error "setdirstripe failed"
26926                 test_qos_mkdir "mkdir" $stripe_count
26927         done
26928 }
26929 run_test 413b "QoS mkdir under dir whose default LMV starting MDT offset is -1"
26930
26931 test_413c() {
26932         (( $MDSCOUNT >= 2 )) ||
26933                 skip "We need at least 2 MDTs for this test"
26934
26935         (( $MDS1_VERSION >= $(version_code 2.14.51) )) ||
26936                 skip "Need server version at least 2.14.51"
26937
26938         local testdir
26939         local inherit
26940         local inherit_rr
26941         local lmv_qos_maxage
26942         local lod_qos_maxage
26943
26944         # let caller set maxage for latest result
26945         lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
26946         $LCTL set_param lmv.*.qos_maxage=1
26947         stack_trap "$LCTL set_param \
26948                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null" RETURN
26949         lod_qos_maxage=$(do_facet mds1 $LCTL get_param -n \
26950                 lod.$FSNAME-MDT0000-mdtlov.qos_maxage | awk '{ print $1 }')
26951         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26952                 lod.*.mdt_qos_maxage=1
26953         stack_trap "do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param \
26954                 lod.*.mdt_qos_maxage=$lod_qos_maxage > /dev/null" RETURN
26955
26956         # fill MDT unevenly
26957         generate_uneven_mdts 120
26958
26959         testdir=$DIR/${tdir}-s1
26960         mkdir $testdir || error "mkdir $testdir failed"
26961         mkdir $testdir/rr || error "mkdir rr failed"
26962         $LFS mkdir -i $(most_full_mdt) $testdir/qos || error "mkdir qos failed"
26963         # default max_inherit is -1, default max_inherit_rr is 0
26964         $LFS setdirstripe -D -c 1 $testdir/rr ||
26965                 error "setdirstripe rr failed"
26966         $LFS setdirstripe -D -c 1 -i -1 -X 2 --max-inherit-rr 1 $testdir/qos ||
26967                 error "setdirstripe qos failed"
26968         test_qos_mkdir "mkdir" 1
26969
26970         mkdir $testdir/rr/level1 || error "mkdir rr/level1 failed"
26971         inherit=$($LFS getdirstripe -D -X $testdir/rr/level1)
26972         (( $inherit == -1 )) || error "rr/level1 inherit $inherit != -1"
26973         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/rr/level1)
26974         (( $inherit_rr == 0 )) || error "rr/level1 inherit-rr $inherit_rr != 0"
26975
26976         mkdir $testdir/qos/level1 || error "mkdir qos/level1 failed"
26977         inherit=$($LFS getdirstripe -D -X $testdir/qos/level1)
26978         (( $inherit == 1 )) || error "qos/level1 inherit $inherit != 1"
26979         inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir/qos/level1)
26980         (( $inherit_rr == 0 )) || error "qos/level1 inherit-rr $inherit_rr != 0"
26981         mkdir $testdir/qos/level1/level2 || error "mkdir level2 failed"
26982         getfattr -d -m dmv -e hex $testdir/qos/level1/level2 | grep dmv &&
26983                 error "level2 shouldn't have default LMV" || true
26984 }
26985 run_test 413c "mkdir with default LMV max inherit rr"
26986
26987 test_413d() {
26988         (( MDSCOUNT >= 2 )) ||
26989                 skip "We need at least 2 MDTs for this test"
26990
26991         (( MDS1_VERSION >= $(version_code 2.14.51) )) ||
26992                 skip "Need server version at least 2.14.51"
26993
26994         local lmv_qos_threshold_rr
26995
26996         lmv_qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr |
26997                 head -n1)
26998         stack_trap "$LCTL set_param \
26999                 lmv.*.qos_threshold_rr=$lmv_qos_threshold_rr > /dev/null" EXIT
27000
27001         $LCTL set_param lmv.*.qos_threshold_rr=100 > /dev/null
27002         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
27003         getfattr -d -m dmv -e hex $DIR/$tdir | grep dmv &&
27004                 error "$tdir shouldn't have default LMV"
27005         createmany -d $DIR/$tdir/sub $((100 * MDSCOUNT)) ||
27006                 error "mkdir sub failed"
27007
27008         local count=$($LFS getstripe -m $DIR/$tdir/* | grep -c ^0)
27009
27010         (( count == 100 )) || error "$count subdirs on MDT0"
27011 }
27012 run_test 413d "inherit ROOT default LMV"
27013
27014 test_413e() {
27015         (( MDSCOUNT >= 2 )) ||
27016                 skip "We need at least 2 MDTs for this test"
27017         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27018                 skip "Need server version at least 2.14.55"
27019
27020         local testdir=$DIR/$tdir
27021         local tmpfile=$TMP/temp.setdirstripe.stderr.$$
27022         local max_inherit
27023         local sub_max_inherit
27024
27025         mkdir -p $testdir || error "failed to create $testdir"
27026
27027         # set default max-inherit to -1 if stripe count is 0 or 1
27028         $LFS setdirstripe -D -c 1 $testdir ||
27029                 error "failed to set default LMV"
27030         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27031         (( max_inherit == -1 )) ||
27032                 error "wrong max_inherit value $max_inherit"
27033
27034         # set default max_inherit to a fixed value if stripe count is not 0 or 1
27035         $LFS setdirstripe -D -c -1 $testdir ||
27036                 error "failed to set default LMV"
27037         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27038         (( max_inherit > 0 )) ||
27039                 error "wrong max_inherit value $max_inherit"
27040
27041         # and the subdir will decrease the max_inherit by 1
27042         mkdir -p $testdir/subdir-1 || error "failed to make subdir"
27043         sub_max_inherit=$($LFS getdirstripe -D --max-inherit $testdir/subdir-1)
27044         (( sub_max_inherit == max_inherit - 1)) ||
27045                 error "wrong max-inherit of subdir $sub_max_inherit"
27046
27047         # check specified --max-inherit and warning message
27048         stack_trap "rm -f $tmpfile"
27049         $LFS setdirstripe -D -c 2 --max-inherit=-1 $testdir 2> $tmpfile ||
27050                 error "failed to set default LMV"
27051         max_inherit=$($LFS getdirstripe -D --max-inherit $testdir)
27052         (( max_inherit == -1 )) ||
27053                 error "wrong max_inherit value $max_inherit"
27054
27055         # check the warning messages
27056         if ! [[ $(cat $tmpfile) =~ "max-inherit=" ]]; then
27057                 error "failed to detect warning string"
27058         fi
27059 }
27060 run_test 413e "check default max-inherit value"
27061
27062 test_fs_dmv_inherit()
27063 {
27064         local testdir=$DIR/$tdir
27065
27066         local count
27067         local inherit
27068         local inherit_rr
27069
27070         for i in 1 2; do
27071                 mkdir $testdir || error "mkdir $testdir failed"
27072                 count=$($LFS getdirstripe -D -c $testdir)
27073                 (( count == 1 )) ||
27074                         error "$testdir default LMV count mismatch $count != 1"
27075                 inherit=$($LFS getdirstripe -D -X $testdir)
27076                 (( inherit == 3 - i )) ||
27077                         error "$testdir default LMV max-inherit $inherit != $((3 - i))"
27078                 inherit_rr=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27079                 (( inherit_rr == 3 - i )) ||
27080                         error "$testdir default LMV max-inherit-rr $inherit_rr != $((3 - i))"
27081                 testdir=$testdir/sub
27082         done
27083
27084         mkdir $testdir || error "mkdir $testdir failed"
27085         count=$($LFS getdirstripe -D -c $testdir)
27086         (( count == 0 )) ||
27087                 error "$testdir default LMV count not zero: $count"
27088 }
27089
27090 test_413f() {
27091         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27092
27093         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27094                 skip "Need server version at least 2.14.55"
27095
27096         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27097                 error "dump $DIR default LMV failed"
27098         stack_trap "setfattr --restore=$TMP/dmv.ea"
27099
27100         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27101                 error "set $DIR default LMV failed"
27102
27103         test_fs_dmv_inherit
27104 }
27105 run_test 413f "lfs getdirstripe -D list ROOT default LMV if it's not set on dir"
27106
27107 test_413g() {
27108         (( MDSCOUNT >= 2 )) || skip "We need at least 2 MDTs for this test"
27109
27110         mkdir -p $DIR/$tdir/l2/l3/l4 || error "mkdir $tdir/l1/l2/l3 failed"
27111         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27112                 error "dump $DIR default LMV failed"
27113         stack_trap "setfattr --restore=$TMP/dmv.ea"
27114
27115         $LFS setdirstripe -D -i -1 -c 1 -X 3 --max-inherit-rr 3 $DIR ||
27116                 error "set $DIR default LMV failed"
27117
27118         FILESET="$FILESET/$tdir/l2/l3/l4" mount_client $MOUNT2 ||
27119                 error "mount $MOUNT2 failed"
27120         stack_trap "umount_client $MOUNT2"
27121
27122         local saved_DIR=$DIR
27123
27124         export DIR=$MOUNT2
27125
27126         stack_trap "export DIR=$saved_DIR"
27127
27128         # first check filesystem-wide default LMV inheritance
27129         test_fs_dmv_inherit || error "incorrect fs default LMV inheritance"
27130
27131         # then check subdirs are spread to all MDTs
27132         createmany -d $DIR/s $((MDSCOUNT * 100)) || error "createmany failed"
27133
27134         local count=$($LFS getstripe -m $DIR/s* | sort -u | wc -l)
27135
27136         (( $count == $MDSCOUNT )) || error "dirs are spread to $count MDTs"
27137 }
27138 run_test 413g "enforce ROOT default LMV on subdir mount"
27139
27140 test_413h() {
27141         (( MDSCOUNT >= 2 )) ||
27142                 skip "We need at least 2 MDTs for this test"
27143
27144         (( MDS1_VERSION >= $(version_code 2.15.50.6) )) ||
27145                 skip "Need server version at least 2.15.50.6"
27146
27147         local lmv_qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
27148
27149         stack_trap "$LCTL set_param \
27150                 lmv.*.qos_maxage=$lmv_qos_maxage > /dev/null"
27151         $LCTL set_param lmv.*.qos_maxage=1
27152
27153         local depth=5
27154         local rr_depth=4
27155         local dir=$DIR/$tdir/l1/l2/l3/l4/l5
27156         local count=$((MDSCOUNT * 20))
27157
27158         generate_uneven_mdts 50
27159
27160         mkdir -p $dir || error "mkdir $dir failed"
27161         stack_trap "rm -rf $dir"
27162         $LFS setdirstripe -D -c 1 -i -1 --max-inherit=$depth \
27163                 --max-inherit-rr=$rr_depth $dir
27164
27165         for ((d=0; d < depth + 2; d++)); do
27166                 log "dir=$dir:"
27167                 for ((sub=0; sub < count; sub++)); do
27168                         mkdir $dir/d$sub
27169                 done
27170                 $LFS getdirstripe -i $dir/d* | sort | uniq -c | sort -nr
27171                 local num=($($LFS getdirstripe -i $dir/d* | sort | uniq -c))
27172                 # subdirs within $rr_depth should be created round-robin
27173                 if (( d < rr_depth )); then
27174                         (( ${num[0]} != count )) ||
27175                                 error "all objects created on MDT ${num[1]}"
27176                 fi
27177
27178                 dir=$dir/d0
27179         done
27180 }
27181 run_test 413h "don't stick to parent for round-robin dirs"
27182
27183 test_413i() {
27184         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
27185
27186         (( MDS1_VERSION >= $(version_code 2.14.55) )) ||
27187                 skip "Need server version at least 2.14.55"
27188
27189         getfattr -d -m trusted.dmv --absolute-names $DIR > $TMP/dmv.ea ||
27190                 error "dump $DIR default LMV failed"
27191         stack_trap "setfattr --restore=$TMP/dmv.ea"
27192
27193         local testdir=$DIR/$tdir
27194         local def_max_rr=1
27195         local def_max=3
27196         local count
27197
27198         $LFS setdirstripe -D -i-1 -c1 --max-inherit=$def_max \
27199                 --max-inherit-rr=$def_max_rr $DIR ||
27200                 error "set $DIR default LMV failed"
27201
27202         for i in $(seq 2 3); do
27203                 def_max=$((def_max - 1))
27204                 (( def_max_rr == 0 )) || def_max_rr=$((def_max_rr - 1))
27205
27206                 mkdir $testdir
27207                 # RR is decremented and keeps zeroed once exhausted
27208                 count=$($LFS getdirstripe -D --max-inherit-rr $testdir)
27209                 (( count == def_max_rr )) ||
27210                         error_noexit "$testdir: max-inherit-rr $count != $def_max_rr"
27211
27212                 # max-inherit is decremented
27213                 count=$($LFS getdirstripe -D --max-inherit $testdir)
27214                 (( count == def_max )) ||
27215                         error_noexit "$testdir: max-inherit $count != $def_max"
27216
27217                 testdir=$testdir/d$i
27218         done
27219
27220         # d3 is the last inherited from ROOT, no inheritance anymore
27221         # i.e. no the default layout anymore
27222         mkdir -p $testdir/d4/d5
27223         count=$($LFS getdirstripe -D --max-inherit $testdir)
27224         (( count == -1 )) ||
27225                 error_noexit "$testdir: max-inherit $count != -1"
27226
27227         local p_count=$($LFS getdirstripe -i $testdir)
27228
27229         for i in $(seq 4 5); do
27230                 testdir=$testdir/d$i
27231
27232                 # the root default layout is not applied once exhausted
27233                 count=$($LFS getdirstripe -i $testdir)
27234                 (( count == p_count )) ||
27235                         error_noexit "$testdir: stripe-offset $count != parent offset $p_count"
27236         done
27237
27238         $LFS setdirstripe -i 0 $DIR/d2
27239         count=$($LFS getdirstripe -D --max-inherit $DIR/d2)
27240         (( count == -1 )) ||
27241                 error_noexit "$DIR/d2: max-inherit non-striped default $count != -1"
27242 }
27243 run_test 413i "check default layout inheritance"
27244
27245 test_413z() {
27246         local pids=""
27247         local subdir
27248         local pid
27249
27250         for subdir in $(\ls -1 -d $DIR/d413*-fillmdt/*); do
27251                 unlinkmany $subdir/f. $TEST413_COUNT &
27252                 pids="$pids $!"
27253         done
27254
27255         for pid in $pids; do
27256                 wait $pid
27257         done
27258
27259         true
27260 }
27261 run_test 413z "413 test cleanup"
27262
27263 test_414() {
27264 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
27265         $LCTL set_param fail_loc=0x80000521
27266         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27267         rm -f $DIR/$tfile
27268 }
27269 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
27270
27271 test_415() {
27272         [[ $PARALLEL == "yes" ]] && skip "skip parallel run"
27273         (( $MDS1_VERSION >= $(version_code 2.11.52) )) ||
27274                 skip "Need server version at least 2.11.52"
27275
27276         # LU-11102
27277         local total=500
27278         local max=120
27279
27280         # this test may be slow on ZFS
27281         [[ "$mds1_FSTYPE" == "zfs" ]] && total=50
27282
27283         # though this test is designed for striped directory, let's test normal
27284         # directory too since lock is always saved as CoS lock.
27285         test_mkdir $DIR/$tdir || error "mkdir $tdir"
27286         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
27287         stack_trap "unlinkmany $DIR/$tdir/$tfile. $total || true"
27288         # if looping with ONLY_REPEAT, wait for previous deletions to finish
27289         wait_delete_completed_mds
27290
27291         # run a loop without concurrent touch to measure rename duration.
27292         # only for test debug/robustness, NOT part of COS functional test.
27293         local start_time=$SECONDS
27294         for ((i = 0; i < total; i++)); do
27295                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
27296                         > /dev/null
27297         done
27298         local baseline=$((SECONDS - start_time))
27299         echo "rename $total files without 'touch' took $baseline sec"
27300
27301         (
27302                 while true; do
27303                         touch $DIR/$tdir
27304                 done
27305         ) &
27306         local setattr_pid=$!
27307
27308         # rename files back to original name so unlinkmany works
27309         start_time=$SECONDS
27310         for ((i = 0; i < total; i++)); do
27311                 mrename $DIR/$tdir/$tfile-new.$i $DIR/$tdir/$tfile.$i\
27312                         > /dev/null
27313         done
27314         local duration=$((SECONDS - start_time))
27315
27316         kill -9 $setattr_pid
27317
27318         echo "rename $total files with 'touch' took $duration sec"
27319         (( max > 2 * baseline )) || max=$((2 * baseline + 5))
27320         (( duration <= max )) || error "rename took $duration > $max sec"
27321 }
27322 run_test 415 "lock revoke is not missing"
27323
27324 test_416() {
27325         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
27326                 skip "Need server version at least 2.11.55"
27327
27328         # define OBD_FAIL_OSD_TXN_START    0x19a
27329         do_facet mds1 lctl set_param fail_loc=0x19a
27330
27331         lfs mkdir -c $MDSCOUNT $DIR/$tdir
27332
27333         true
27334 }
27335 run_test 416 "transaction start failure won't cause system hung"
27336
27337 cleanup_417() {
27338         trap 0
27339         do_nodes $(comma_list $(mdts_nodes)) \
27340                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
27341         do_nodes $(comma_list $(mdts_nodes)) \
27342                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
27343         do_nodes $(comma_list $(mdts_nodes)) \
27344                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
27345 }
27346
27347 test_417() {
27348         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27349         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
27350                 skip "Need MDS version at least 2.11.56"
27351
27352         trap cleanup_417 RETURN EXIT
27353
27354         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
27355         do_nodes $(comma_list $(mdts_nodes)) \
27356                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
27357         $LFS migrate -m 0 $DIR/$tdir.1 &&
27358                 error "migrate dir $tdir.1 should fail"
27359
27360         do_nodes $(comma_list $(mdts_nodes)) \
27361                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
27362         $LFS mkdir -i 1 $DIR/$tdir.2 &&
27363                 error "create remote dir $tdir.2 should fail"
27364
27365         do_nodes $(comma_list $(mdts_nodes)) \
27366                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
27367         $LFS mkdir -c 2 $DIR/$tdir.3 &&
27368                 error "create striped dir $tdir.3 should fail"
27369         true
27370 }
27371 run_test 417 "disable remote dir, striped dir and dir migration"
27372
27373 # Checks that the outputs of df [-i] and lfs df [-i] match
27374 #
27375 # usage: check_lfs_df <blocks | inodes> <mountpoint>
27376 check_lfs_df() {
27377         local dir=$2
27378         local inodes
27379         local df_out
27380         local lfs_df_out
27381         local count
27382         local passed=false
27383
27384         # blocks or inodes
27385         [ "$1" == "blocks" ] && inodes= || inodes="-i"
27386
27387         for count in {1..100}; do
27388                 do_nodes "$CLIENTS" \
27389                         $LCTL set_param ldlm.namespaces.*.lru_size=clear
27390                 sync; sleep 0.2
27391
27392                 # read the lines of interest
27393                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
27394                         error "df $inodes $dir | tail -n +2 failed"
27395                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
27396                         error "lfs df $inodes $dir | grep summary: failed"
27397
27398                 # skip first substrings of each output as they are different
27399                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
27400                 # compare the two outputs
27401                 passed=true
27402                 #  skip "available" on MDT until LU-13997 is fixed.
27403                 #for i in {1..5}; do
27404                 for i in 1 2 4 5; do
27405                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
27406                 done
27407                 $passed && break
27408         done
27409
27410         if ! $passed; then
27411                 df -P $inodes $dir
27412                 echo
27413                 lfs df $inodes $dir
27414                 error "df and lfs df $1 output mismatch: "      \
27415                       "df ${inodes}: ${df_out[*]}, "            \
27416                       "lfs df ${inodes}: ${lfs_df_out[*]}"
27417         fi
27418 }
27419
27420 test_418() {
27421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27422
27423         local dir=$DIR/$tdir
27424         local numfiles=$((RANDOM % 4096 + 2))
27425         local numblocks=$((RANDOM % 256 + 1))
27426
27427         wait_delete_completed
27428         test_mkdir $dir
27429
27430         # check block output
27431         check_lfs_df blocks $dir
27432         # check inode output
27433         check_lfs_df inodes $dir
27434
27435         # create a single file and retest
27436         echo "Creating a single file and testing"
27437         createmany -o $dir/$tfile- 1 &>/dev/null ||
27438                 error "creating 1 file in $dir failed"
27439         check_lfs_df blocks $dir
27440         check_lfs_df inodes $dir
27441
27442         # create a random number of files
27443         echo "Creating $((numfiles - 1)) files and testing"
27444         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
27445                 error "creating $((numfiles - 1)) files in $dir failed"
27446
27447         # write a random number of blocks to the first test file
27448         echo "Writing $numblocks 4K blocks and testing"
27449         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
27450                 count=$numblocks &>/dev/null ||
27451                 error "dd to $dir/${tfile}-0 failed"
27452
27453         # retest
27454         check_lfs_df blocks $dir
27455         check_lfs_df inodes $dir
27456
27457         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
27458                 error "unlinking $numfiles files in $dir failed"
27459 }
27460 run_test 418 "df and lfs df outputs match"
27461
27462 test_419()
27463 {
27464         local dir=$DIR/$tdir
27465
27466         mkdir -p $dir
27467         touch $dir/file
27468
27469         cancel_lru_locks mdc
27470
27471         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
27472         $LCTL set_param fail_loc=0x1410
27473         cat $dir/file
27474         $LCTL set_param fail_loc=0
27475         rm -rf $dir
27476 }
27477 run_test 419 "Verify open file by name doesn't crash kernel"
27478
27479 test_420()
27480 {
27481         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
27482                 skip "Need MDS version at least 2.12.53"
27483
27484         local SAVE_UMASK=$(umask)
27485         local dir=$DIR/$tdir
27486         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
27487
27488         mkdir -p $dir
27489         umask 0000
27490         mkdir -m03777 $dir/testdir
27491         ls -dn $dir/testdir
27492         # Need to remove trailing '.' when SELinux is enabled
27493         local dirperms=$(ls -dn $dir/testdir |
27494                          awk '{ sub(/\.$/, "", $1); print $1}')
27495         [ $dirperms == "drwxrwsrwt" ] ||
27496                 error "incorrect perms on $dir/testdir"
27497
27498         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
27499                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
27500         ls -n $dir/testdir/testfile
27501         local fileperms=$(ls -n $dir/testdir/testfile |
27502                           awk '{ sub(/\.$/, "", $1); print $1}')
27503         [ $fileperms == "-rwxr-xr-x" ] ||
27504                 error "incorrect perms on $dir/testdir/testfile"
27505
27506         umask $SAVE_UMASK
27507 }
27508 run_test 420 "clear SGID bit on non-directories for non-members"
27509
27510 test_421a() {
27511         local cnt
27512         local fid1
27513         local fid2
27514
27515         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27516                 skip "Need MDS version at least 2.12.54"
27517
27518         test_mkdir $DIR/$tdir
27519         createmany -o $DIR/$tdir/f 3
27520         cnt=$(ls -1 $DIR/$tdir | wc -l)
27521         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27522
27523         fid1=$(lfs path2fid $DIR/$tdir/f1)
27524         fid2=$(lfs path2fid $DIR/$tdir/f2)
27525         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
27526
27527         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
27528         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
27529
27530         cnt=$(ls -1 $DIR/$tdir | wc -l)
27531         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27532
27533         rm -f $DIR/$tdir/f3 || error "can't remove f3"
27534         createmany -o $DIR/$tdir/f 3
27535         cnt=$(ls -1 $DIR/$tdir | wc -l)
27536         [ $cnt != 3 ] && error "unexpected #files: $cnt"
27537
27538         fid1=$(lfs path2fid $DIR/$tdir/f1)
27539         fid2=$(lfs path2fid $DIR/$tdir/f2)
27540         echo "remove using fsname $FSNAME"
27541         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
27542
27543         cnt=$(ls -1 $DIR/$tdir | wc -l)
27544         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
27545 }
27546 run_test 421a "simple rm by fid"
27547
27548 test_421b() {
27549         local cnt
27550         local FID1
27551         local FID2
27552
27553         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27554                 skip "Need MDS version at least 2.12.54"
27555
27556         test_mkdir $DIR/$tdir
27557         createmany -o $DIR/$tdir/f 3
27558         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
27559         MULTIPID=$!
27560
27561         FID1=$(lfs path2fid $DIR/$tdir/f1)
27562         FID2=$(lfs path2fid $DIR/$tdir/f2)
27563         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
27564
27565         kill -USR1 $MULTIPID
27566         wait
27567
27568         cnt=$(ls $DIR/$tdir | wc -l)
27569         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
27570 }
27571 run_test 421b "rm by fid on open file"
27572
27573 test_421c() {
27574         local cnt
27575         local FIDS
27576
27577         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27578                 skip "Need MDS version at least 2.12.54"
27579
27580         test_mkdir $DIR/$tdir
27581         createmany -o $DIR/$tdir/f 3
27582         touch $DIR/$tdir/$tfile
27583         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
27584         cnt=$(ls -1 $DIR/$tdir | wc -l)
27585         [ $cnt != 184 ] && error "unexpected #files: $cnt"
27586
27587         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
27588         $LFS rmfid $DIR $FID1 || error "rmfid failed"
27589
27590         cnt=$(ls $DIR/$tdir | wc -l)
27591         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
27592 }
27593 run_test 421c "rm by fid against hardlinked files"
27594
27595 test_421d() {
27596         local cnt
27597         local FIDS
27598
27599         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27600                 skip "Need MDS version at least 2.12.54"
27601
27602         test_mkdir $DIR/$tdir
27603         createmany -o $DIR/$tdir/f 4097
27604         cnt=$(ls -1 $DIR/$tdir | wc -l)
27605         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
27606
27607         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
27608         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27609
27610         cnt=$(ls $DIR/$tdir | wc -l)
27611         rm -rf $DIR/$tdir
27612         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27613 }
27614 run_test 421d "rmfid en masse"
27615
27616 test_421e() {
27617         local cnt
27618         local FID
27619
27620         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27621         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27622                 skip "Need MDS version at least 2.12.54"
27623
27624         mkdir -p $DIR/$tdir
27625         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27626         createmany -o $DIR/$tdir/striped_dir/f 512
27627         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27628         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27629
27630         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27631                 sed "s/[/][^:]*://g")
27632         $LFS rmfid $DIR $FIDS || error "rmfid failed"
27633
27634         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27635         rm -rf $DIR/$tdir
27636         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27637 }
27638 run_test 421e "rmfid in DNE"
27639
27640 test_421f() {
27641         local cnt
27642         local FID
27643
27644         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27645                 skip "Need MDS version at least 2.12.54"
27646
27647         test_mkdir $DIR/$tdir
27648         touch $DIR/$tdir/f
27649         cnt=$(ls -1 $DIR/$tdir | wc -l)
27650         [ $cnt != 1 ] && error "unexpected #files: $cnt"
27651
27652         FID=$(lfs path2fid $DIR/$tdir/f)
27653         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
27654         # rmfid should fail
27655         cnt=$(ls -1 $DIR/$tdir | wc -l)
27656         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
27657
27658         chmod a+rw $DIR/$tdir
27659         ls -la $DIR/$tdir
27660         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
27661         # rmfid should fail
27662         cnt=$(ls -1 $DIR/$tdir | wc -l)
27663         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
27664
27665         rm -f $DIR/$tdir/f
27666         $RUNAS touch $DIR/$tdir/f
27667         FID=$(lfs path2fid $DIR/$tdir/f)
27668         echo "rmfid as root"
27669         $LFS rmfid $DIR $FID || error "rmfid as root failed"
27670         cnt=$(ls -1 $DIR/$tdir | wc -l)
27671         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
27672
27673         rm -f $DIR/$tdir/f
27674         $RUNAS touch $DIR/$tdir/f
27675         cnt=$(ls -1 $DIR/$tdir | wc -l)
27676         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
27677         FID=$(lfs path2fid $DIR/$tdir/f)
27678         # rmfid w/o user_fid2path mount option should fail
27679         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
27680         cnt=$(ls -1 $DIR/$tdir | wc -l)
27681         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
27682
27683         tmpdir=$(mktemp -d /tmp/lustre-XXXXXX)
27684         stack_trap "rmdir $tmpdir"
27685         mount_client $tmpdir "$MOUNT_OPTS,user_fid2path" ||
27686                 error "failed to mount client'"
27687         stack_trap "umount_client $tmpdir"
27688
27689         $RUNAS $LFS rmfid $tmpdir $FID || error "rmfid failed"
27690         # rmfid should succeed
27691         cnt=$(ls -1 $tmpdir/$tdir | wc -l)
27692         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
27693
27694         # rmfid shouldn't allow to remove files due to dir's permission
27695         chmod a+rwx $tmpdir/$tdir
27696         touch $tmpdir/$tdir/f
27697         ls -la $tmpdir/$tdir
27698         FID=$(lfs path2fid $tmpdir/$tdir/f)
27699         $RUNAS $LFS rmfid $tmpdir $FID && error "rmfid didn't fail"
27700         return 0
27701 }
27702 run_test 421f "rmfid checks permissions"
27703
27704 test_421g() {
27705         local cnt
27706         local FIDS
27707
27708         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
27709         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
27710                 skip "Need MDS version at least 2.12.54"
27711
27712         mkdir -p $DIR/$tdir
27713         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
27714         createmany -o $DIR/$tdir/striped_dir/f 512
27715         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27716         [ $cnt != 512 ] && error "unexpected #files: $cnt"
27717
27718         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
27719                 sed "s/[/][^:]*://g")
27720
27721         rm -f $DIR/$tdir/striped_dir/f1*
27722         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
27723         removed=$((512 - cnt))
27724
27725         # few files have been just removed, so we expect
27726         # rmfid to fail on their fids
27727         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
27728         [ $removed != $errors ] && error "$errors != $removed"
27729
27730         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
27731         rm -rf $DIR/$tdir
27732         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
27733 }
27734 run_test 421g "rmfid to return errors properly"
27735
27736 test_421h() {
27737         local mount_other
27738         local mount_ret
27739         local rmfid_ret
27740         local old_fid
27741         local fidA
27742         local fidB
27743         local fidC
27744         local fidD
27745
27746         (( MDS1_VERSION >= $(version_code 2.15.53) )) ||
27747                 skip "Need MDS version at least 2.15.53"
27748
27749         test_mkdir $DIR/$tdir
27750         test_mkdir $DIR/$tdir/subdir
27751         touch $DIR/$tdir/subdir/file0
27752         old_fid=$(lfs path2fid $DIR/$tdir/subdir/file0 | sed "s/[/][^:]*://g")
27753         echo File $DIR/$tdir/subdir/file0 FID $old_fid
27754         rm -f $DIR/$tdir/subdir/file0
27755         touch $DIR/$tdir/subdir/fileA
27756         fidA=$(lfs path2fid $DIR/$tdir/subdir/fileA | sed "s/[/][^:]*://g")
27757         echo File $DIR/$tdir/subdir/fileA FID $fidA
27758         touch $DIR/$tdir/subdir/fileB
27759         fidB=$(lfs path2fid $DIR/$tdir/subdir/fileB | sed "s/[/][^:]*://g")
27760         echo File $DIR/$tdir/subdir/fileB FID $fidB
27761         ln $DIR/$tdir/subdir/fileB $DIR/$tdir/subdir/fileB_hl
27762         touch $DIR/$tdir/subdir/fileC
27763         fidC=$(lfs path2fid $DIR/$tdir/subdir/fileC | sed "s/[/][^:]*://g")
27764         echo File $DIR/$tdir/subdir/fileC FID $fidC
27765         ln $DIR/$tdir/subdir/fileC $DIR/$tdir/fileC
27766         touch $DIR/$tdir/fileD
27767         fidD=$(lfs path2fid $DIR/$tdir/fileD | sed "s/[/][^:]*://g")
27768         echo File $DIR/$tdir/fileD FID $fidD
27769
27770         # mount another client mount point with subdirectory mount
27771         export FILESET=/$tdir/subdir
27772         mount_other=${MOUNT}_other
27773         mount_client $mount_other ${MOUNT_OPTS}
27774         mount_ret=$?
27775         export FILESET=""
27776         (( mount_ret == 0 )) || error "mount $mount_other failed"
27777
27778         echo Removing FIDs:
27779         echo $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27780         $LFS rmfid $mount_other $old_fid $fidA $fidD $fidB $fidC
27781         rmfid_ret=$?
27782
27783         umount_client $mount_other || error "umount $mount_other failed"
27784
27785         (( rmfid_ret != 0 )) || error "rmfid should have failed"
27786
27787         # fileA should have been deleted
27788         stat $DIR/$tdir/subdir/fileA && error "fileA not deleted"
27789
27790         # fileB should have been deleted
27791         stat $DIR/$tdir/subdir/fileB && error "fileB not deleted"
27792
27793         # fileC should not have been deleted, fid also exists outside of fileset
27794         stat $DIR/$tdir/subdir/fileC || error "fileC deleted"
27795
27796         # fileD should not have been deleted, it exists outside of fileset
27797         stat $DIR/$tdir/fileD || error "fileD deleted"
27798 }
27799 run_test 421h "rmfid with fileset mount"
27800
27801 test_422() {
27802         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d1
27803         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d2
27804         test_mkdir -i 0 -c 1 -p $DIR/$tdir/d3
27805         dd if=/dev/zero of=$DIR/$tdir/d1/file1 bs=1k count=1
27806         dd if=/dev/zero of=$DIR/$tdir/d2/file1 bs=1k count=1
27807
27808         local amc=$(at_max_get client)
27809         local amo=$(at_max_get mds1)
27810         local timeout=`lctl get_param -n timeout`
27811
27812         at_max_set 0 client
27813         at_max_set 0 mds1
27814
27815 #define OBD_FAIL_PTLRPC_PAUSE_REQ        0x50a
27816         do_facet mds1 $LCTL set_param fail_loc=0x8000050a \
27817                         fail_val=$(((2*timeout + 10)*1000))
27818         touch $DIR/$tdir/d3/file &
27819         sleep 2
27820 #define OBD_FAIL_TGT_REPLY_DATA_RACE     0x722
27821         do_facet mds1 $LCTL set_param fail_loc=0x80000722 \
27822                         fail_val=$((2*timeout + 5))
27823         mv $DIR/$tdir/d1/file1 $DIR/$tdir/d1/file2 &
27824         local pid=$!
27825         sleep 1
27826         kill -9 $pid
27827         sleep $((2 * timeout))
27828         echo kill $pid
27829         kill -9 $pid
27830         lctl mark touch
27831         touch $DIR/$tdir/d2/file3
27832         touch $DIR/$tdir/d2/file4
27833         touch $DIR/$tdir/d2/file5
27834
27835         wait
27836         at_max_set $amc client
27837         at_max_set $amo mds1
27838
27839         # LU-12838 - verify the ptlrpc thread watchdog is not always throttled
27840         do_facet mds1 "dmesg | grep 'Dumping the stack trace for debugging'" ||
27841                 error "Watchdog is always throttled"
27842 }
27843 run_test 422 "kill a process with RPC in progress"
27844
27845 stat_test() {
27846     df -h $MOUNT &
27847     df -h $MOUNT &
27848     df -h $MOUNT &
27849     df -h $MOUNT &
27850     df -h $MOUNT &
27851     df -h $MOUNT &
27852 }
27853
27854 test_423() {
27855     local _stats
27856     # ensure statfs cache is expired
27857     sleep 2;
27858
27859     _stats=$(stat_test | grep $MOUNT | sort -u | wc -l)
27860     [[ ${_stats} -ne 1 ]] && error "statfs wrong"
27861
27862     return 0
27863 }
27864 run_test 423 "statfs should return a right data"
27865
27866 test_424() {
27867 #define OBD_FAIL_PTLRPC_BULK_REPLY_ATTACH      0x522 | OBD_FAIL_ONCE
27868         $LCTL set_param fail_loc=0x80000522
27869         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
27870         rm -f $DIR/$tfile
27871 }
27872 run_test 424 "simulate ENOMEM in ptl_send_rpc bulk reply ME attach"
27873
27874 test_425() {
27875         test_mkdir -c -1 $DIR/$tdir
27876         $LFS setstripe -c -1 $DIR/$tdir
27877
27878         lru_resize_disable "" 100
27879         stack_trap "lru_resize_enable" EXIT
27880
27881         sleep 5
27882
27883         for i in $(seq $((MDSCOUNT * 125))); do
27884                 local t=$DIR/$tdir/$tfile_$i
27885
27886                 dd if=/dev/zero of=$t bs=4K count=1 > /dev/null 2>&1 ||
27887                         error_noexit "Create file $t"
27888         done
27889         stack_trap "rm -rf $DIR/$tdir" EXIT
27890
27891         for oscparam in $($LCTL list_param ldlm.namespaces.*osc-[-0-9a-f]*); do
27892                 local lru_size=$($LCTL get_param -n $oscparam.lru_size)
27893                 local lock_count=$($LCTL get_param -n $oscparam.lock_count)
27894
27895                 [ $lock_count -le $lru_size ] ||
27896                         error "osc lock count $lock_count > lru size $lru_size"
27897         done
27898
27899         for mdcparam in $($LCTL list_param ldlm.namespaces.*mdc-*); do
27900                 local lru_size=$($LCTL get_param -n $mdcparam.lru_size)
27901                 local lock_count=$($LCTL get_param -n $mdcparam.lock_count)
27902
27903                 [ $lock_count -le $lru_size ] ||
27904                         error "mdc lock count $lock_count > lru size $lru_size"
27905         done
27906 }
27907 run_test 425 "lock count should not exceed lru size"
27908
27909 test_426() {
27910         splice-test -r $DIR/$tfile
27911         splice-test -rd $DIR/$tfile
27912         splice-test $DIR/$tfile
27913         splice-test -d $DIR/$tfile
27914 }
27915 run_test 426 "splice test on Lustre"
27916
27917 test_427() {
27918         [ $MDSCOUNT -ge 2 ] || skip "needs >= 2 MDTs"
27919         (( $MDS1_VERSION >= $(version_code 2.12.4) )) ||
27920                 skip "Need MDS version at least 2.12.4"
27921         local log
27922
27923         mkdir $DIR/$tdir
27924         mkdir $DIR/$tdir/1
27925         mkdir $DIR/$tdir/2
27926         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/1/dir
27927         test_mkdir -c $MDSCOUNT -i 1 $DIR/$tdir/2/dir2
27928
27929         $LFS getdirstripe $DIR/$tdir/1/dir
27930
27931         #first setfattr for creating updatelog
27932         setfattr -n user.attr0 -v "some text" $DIR/$tdir/1/dir
27933
27934 #define OBD_FAIL_OUT_OBJECT_MISS        0x1708
27935         do_nodes $(comma_list $(mdts_nodes)) $LCTL set_param fail_loc=0x80001708
27936         setfattr -n user.attr1 -v "some text" $DIR/$tdir/1/dir &
27937         setfattr -n user.attr2 -v "another attr"  $DIR/$tdir/2/dir2 &
27938
27939         sleep 2
27940         fail mds2
27941         wait_recovery_complete mds2 $((2*TIMEOUT))
27942
27943         log=$(do_facet mds1 dmesg | tac | sed "/${TESTNAME//_/ }/,$ d")
27944         echo $log | grep "get update log failed" &&
27945                 error "update log corruption is detected" || true
27946 }
27947 run_test 427 "Failed DNE2 update request shouldn't corrupt updatelog"
27948
27949 test_428() {
27950         [ $PARALLEL == "yes" ] && skip "skip parallel run"
27951         local cache_limit=$CACHE_MAX
27952
27953         stack_trap "$LCTL set_param -n llite.*.max_cached_mb=$cache_limit"
27954         $LCTL set_param -n llite.*.max_cached_mb=64
27955
27956         mkdir $DIR/$tdir
27957         $LFS setstripe -c 1 $DIR/$tdir
27958         eval touch $DIR/$tdir/$tfile.{1..$OSTCOUNT}
27959         stack_trap "rm -f $DIR/$tdir/$tfile.*"
27960         #test write
27961         for f in $(seq 4); do
27962                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$f bs=128M count=1 &
27963         done
27964         wait
27965
27966         cancel_lru_locks osc
27967         # Test read
27968         for f in $(seq 4); do
27969                 dd if=$DIR/$tdir/$tfile.$f of=/dev/null bs=128M count=1 &
27970         done
27971         wait
27972 }
27973 run_test 428 "large block size IO should not hang"
27974
27975 test_429() { # LU-7915 / LU-10948
27976         local ll_opencache_threshold_count="llite.*.opencache_threshold_count"
27977         local testfile=$DIR/$tfile
27978         local mdc_rpcstats="mdc.$FSNAME-MDT0000-*.stats"
27979         local new_flag=1
27980         local first_rpc
27981         local second_rpc
27982         local third_rpc
27983
27984         $LCTL get_param $ll_opencache_threshold_count ||
27985                 skip "client does not have opencache parameter"
27986
27987         set_opencache $new_flag
27988         stack_trap "restore_opencache"
27989         [ $($LCTL get_param -n $ll_opencache_threshold_count) == $new_flag ] ||
27990                 error "enable opencache failed"
27991         touch $testfile
27992         # drop MDC DLM locks
27993         cancel_lru_locks mdc
27994         # clear MDC RPC stats counters
27995         $LCTL set_param $mdc_rpcstats=clear
27996
27997         # According to the current implementation, we need to run 3 times
27998         # open & close file to verify if opencache is enabled correctly.
27999         # 1st, RPCs are sent for lookup/open and open handle is released on
28000         #      close finally.
28001         # 2nd, RPC is sent for open, MDS_OPEN_LOCK is fetched automatically,
28002         #      so open handle won't be released thereafter.
28003         # 3rd, No RPC is sent out.
28004         $MULTIOP $testfile oc || error "multiop failed"
28005         first_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28006         echo "1st: $first_rpc RPCs in flight"
28007
28008         $MULTIOP $testfile oc || error "multiop failed"
28009         second_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28010         echo "2nd: $second_rpc RPCs in flight"
28011
28012         $MULTIOP $testfile oc || error "multiop failed"
28013         third_rpc=$(calc_stats $mdc_rpcstats ldlm_ibits_enqueue)
28014         echo "3rd: $third_rpc RPCs in flight"
28015
28016         #verify no MDC RPC is sent
28017         [[ $second_rpc == $third_rpc ]] || error "MDC RPC is still sent"
28018 }
28019 run_test 429 "verify if opencache flag on client side does work"
28020
28021 lseek_test_430() {
28022         local offset
28023         local file=$1
28024
28025         # data at [200K, 400K)
28026         dd if=/dev/urandom of=$file bs=256K count=1 seek=1 ||
28027                 error "256K->512K dd fails"
28028         # data at [2M, 3M)
28029         dd if=/dev/urandom of=$file bs=1M count=1 seek=2 ||
28030                 error "2M->3M dd fails"
28031         # data at [4M, 5M)
28032         dd if=/dev/urandom of=$file bs=1M count=1 seek=4 ||
28033                 error "4M->5M dd fails"
28034         echo "Data at 256K...512K, 2M...3M and 4M...5M"
28035         # start at first component hole #1
28036         printf "Seeking hole from 1000 ... "
28037         offset=$(lseek_test -l 1000 $file)
28038         echo $offset
28039         [[ $offset == 1000 ]] || error "offset $offset != 1000"
28040         printf "Seeking data from 1000 ... "
28041         offset=$(lseek_test -d 1000 $file)
28042         echo $offset
28043         [[ $offset == 262144 ]] || error "offset $offset != 262144"
28044
28045         # start at first component data block
28046         printf "Seeking hole from 300000 ... "
28047         offset=$(lseek_test -l 300000 $file)
28048         echo $offset
28049         [[ $offset == 524288 ]] || error "offset $offset != 524288"
28050         printf "Seeking data from 300000 ... "
28051         offset=$(lseek_test -d 300000 $file)
28052         echo $offset
28053         [[ $offset == 300000 ]] || error "offset $offset != 300000"
28054
28055         # start at the first component but beyond end of object size
28056         printf "Seeking hole from 1000000 ... "
28057         offset=$(lseek_test -l 1000000 $file)
28058         echo $offset
28059         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28060         printf "Seeking data from 1000000 ... "
28061         offset=$(lseek_test -d 1000000 $file)
28062         echo $offset
28063         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28064
28065         # start at second component stripe 2 (empty file)
28066         printf "Seeking hole from 1500000 ... "
28067         offset=$(lseek_test -l 1500000 $file)
28068         echo $offset
28069         [[ $offset == 1500000 ]] || error "offset $offset != 1500000"
28070         printf "Seeking data from 1500000 ... "
28071         offset=$(lseek_test -d 1500000 $file)
28072         echo $offset
28073         [[ $offset == 2097152 ]] || error "offset $offset != 2097152"
28074
28075         # start at second component stripe 1 (all data)
28076         printf "Seeking hole from 3000000 ... "
28077         offset=$(lseek_test -l 3000000 $file)
28078         echo $offset
28079         [[ $offset == 3145728 ]] || error "offset $offset != 3145728"
28080         printf "Seeking data from 3000000 ... "
28081         offset=$(lseek_test -d 3000000 $file)
28082         echo $offset
28083         [[ $offset == 3000000 ]] || error "offset $offset != 3000000"
28084
28085         dd if=/dev/urandom of=$file bs=640K count=1 seek=1 ||
28086                 error "2nd dd fails"
28087         echo "Add data block at 640K...1280K"
28088
28089         # start at before new data block, in hole
28090         printf "Seeking hole from 600000 ... "
28091         offset=$(lseek_test -l 600000 $file)
28092         echo $offset
28093         [[ $offset == 600000 ]] || error "offset $offset != 600000"
28094         printf "Seeking data from 600000 ... "
28095         offset=$(lseek_test -d 600000 $file)
28096         echo $offset
28097         [[ $offset == 655360 ]] || error "offset $offset != 655360"
28098
28099         # start at the first component new data block
28100         printf "Seeking hole from 1000000 ... "
28101         offset=$(lseek_test -l 1000000 $file)
28102         echo $offset
28103         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28104         printf "Seeking data from 1000000 ... "
28105         offset=$(lseek_test -d 1000000 $file)
28106         echo $offset
28107         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28108
28109         # start at second component stripe 2, new data
28110         printf "Seeking hole from 1200000 ... "
28111         offset=$(lseek_test -l 1200000 $file)
28112         echo $offset
28113         [[ $offset == 1310720 ]] || error "offset $offset != 1310720"
28114         printf "Seeking data from 1200000 ... "
28115         offset=$(lseek_test -d 1200000 $file)
28116         echo $offset
28117         [[ $offset == 1200000 ]] || error "offset $offset != 1200000"
28118
28119         # start beyond file end
28120         printf "Using offset > filesize ... "
28121         lseek_test -l 4000000 $file && error "lseek should fail"
28122         printf "Using offset > filesize ... "
28123         lseek_test -d 4000000 $file && error "lseek should fail"
28124
28125         printf "Done\n\n"
28126 }
28127
28128 test_430a() {
28129         $LCTL get_param mdc.*.import | grep -q 'connect_flags:.*seek' ||
28130                 skip "MDT does not support SEEK_HOLE"
28131
28132         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28133                 skip "OST does not support SEEK_HOLE"
28134
28135         local file=$DIR/$tdir/$tfile
28136
28137         mkdir -p $DIR/$tdir
28138
28139         $LFS setstripe -E 1M -L mdt -E eof -c2 $file
28140         # OST stripe #1 will have continuous data at [1M, 3M)
28141         # OST stripe #2 is empty
28142         echo "Component #1: 1M DoM, component #2: EOF, 2 stripes 1M"
28143         lseek_test_430 $file
28144         rm $file
28145         $LFS setstripe -E 1M -c2 -S 64K -E 10M -c2 -S 1M $file
28146         echo "Component #1: 1M, 2 stripes 64K, component #2: EOF, 2 stripes 1M"
28147         lseek_test_430 $file
28148         rm $file
28149         $LFS setstripe -c2 -S 512K $file
28150         echo "Two stripes, stripe size 512K"
28151         lseek_test_430 $file
28152         rm $file
28153         # FLR with stale mirror
28154         $LFS setstripe -N -E 512K -c1 -S 64K -E eof -c2 -S 512K \
28155                        -N -c2 -S 1M $file
28156         echo "Mirrored file:"
28157         echo "Component #1: 512K, stripe 64K, component #2: EOF, 2 stripes 512K"
28158         echo "Plain 2 stripes 1M"
28159         lseek_test_430 $file
28160         rm $file
28161 }
28162 run_test 430a "lseek: SEEK_DATA/SEEK_HOLE basic functionality"
28163
28164 test_430b() {
28165         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28166                 skip "OST does not support SEEK_HOLE"
28167
28168         local offset
28169         local file=$DIR/$tdir/$tfile
28170
28171         mkdir -p $DIR/$tdir
28172         # Empty layout lseek should fail
28173         $MCREATE $file
28174         # seek from 0
28175         printf "Seeking hole from 0 ... "
28176         lseek_test -l 0 $file && error "lseek should fail"
28177         printf "Seeking data from 0 ... "
28178         lseek_test -d 0 $file && error "lseek should fail"
28179         rm $file
28180
28181         # 1M-hole file
28182         $LFS setstripe -E 1M -c2 -E eof $file
28183         $TRUNCATE $file 1048576
28184         printf "Seeking hole from 1000000 ... "
28185         offset=$(lseek_test -l 1000000 $file)
28186         echo $offset
28187         [[ $offset == 1000000 ]] || error "offset $offset != 1000000"
28188         printf "Seeking data from 1000000 ... "
28189         lseek_test -d 1000000 $file && error "lseek should fail"
28190         rm $file
28191
28192         # full component followed by non-inited one
28193         $LFS setstripe -E 1M -c2 -E eof $file
28194         dd if=/dev/urandom of=$file bs=1M count=1
28195         printf "Seeking hole from 1000000 ... "
28196         offset=$(lseek_test -l 1000000 $file)
28197         echo $offset
28198         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28199         printf "Seeking hole from 1048576 ... "
28200         lseek_test -l 1048576 $file && error "lseek should fail"
28201         # init second component and truncate back
28202         echo "123" >> $file
28203         $TRUNCATE $file 1048576
28204         printf "Seeking hole from 1000000 ... "
28205         offset=$(lseek_test -l 1000000 $file)
28206         echo $offset
28207         [[ $offset == 1048576 ]] || error "offset $offset != 1048576"
28208         printf "Seeking hole from 1048576 ... "
28209         lseek_test -l 1048576 $file && error "lseek should fail"
28210         # boundary checks for big values
28211         dd if=/dev/urandom of=$file.10g bs=1 count=1 seek=10G
28212         offset=$(lseek_test -d 0 $file.10g)
28213         [[ $offset == 10737418240 ]] || error "offset $offset != 10737418240"
28214         dd if=/dev/urandom of=$file.100g bs=1 count=1 seek=100G
28215         offset=$(lseek_test -d 0 $file.100g)
28216         [[ $offset == 107374182400 ]] || error "offset $offset != 107374182400"
28217         return 0
28218 }
28219 run_test 430b "lseek: SEEK_DATA/SEEK_HOLE special cases"
28220
28221 test_430c() {
28222         $LCTL get_param osc.*.import | grep -q 'connect_flags:.*seek' ||
28223                 skip "OST does not support SEEK_HOLE"
28224
28225         local file=$DIR/$tdir/$tfile
28226         local start
28227
28228         mkdir -p $DIR/$tdir
28229         dd if=/dev/urandom of=$file bs=1k count=1 seek=5M
28230
28231         # cp version 8.33+ prefers lseek over fiemap
28232         if [[ $(cp --version | head -n1 | sed "s/[^0-9]//g") -ge 833 ]]; then
28233                 start=$SECONDS
28234                 time cp $file /dev/null
28235                 (( SECONDS - start < 5 )) ||
28236                         error "cp: too long runtime $((SECONDS - start))"
28237
28238         fi
28239         # tar version 1.29+ supports SEEK_HOLE/DATA
28240         if [[ $(tar --version | head -n1 | sed "s/[^0-9]//g") -ge 129 ]]; then
28241                 start=$SECONDS
28242                 time tar cS $file - | cat > /dev/null
28243                 (( SECONDS - start < 5 )) ||
28244                         error "tar: too long runtime $((SECONDS - start))"
28245         fi
28246 }
28247 run_test 430c "lseek: external tools check"
28248
28249 test_431() { # LU-14187
28250         local file=$DIR/$tdir/$tfile
28251
28252         mkdir -p $DIR/$tdir
28253         $LFS setstripe -c 1 -i 0 $file || error "lfs setstripe failed"
28254         dd if=/dev/urandom of=$file bs=4k count=1
28255         dd if=/dev/urandom of=$file bs=4k count=1 seek=10 conv=notrunc
28256         dd if=/dev/urandom of=$file bs=4k count=1 seek=12 conv=notrunc
28257         #define OBD_FAIL_OST_RESTART_IO 0x251
28258         do_facet ost1 "$LCTL set_param fail_loc=0x251"
28259         $LFS setstripe -c 1 -i 0 $file.0 || error "lfs setstripe failed"
28260         cp $file $file.0
28261         cancel_lru_locks
28262         sync_all_data
28263         echo 3 > /proc/sys/vm/drop_caches
28264         diff  $file $file.0 || error "data diff"
28265 }
28266 run_test 431 "Restart transaction for IO"
28267
28268 cleanup_test_432() {
28269         do_facet mgs $LCTL nodemap_activate 0
28270         wait_nm_sync active
28271 }
28272
28273 test_432() {
28274         local tmpdir=$TMP/dir432
28275
28276         (( $MDS1_VERSION >= $(version_code 2.14.52) )) ||
28277                 skip "Need MDS version at least 2.14.52"
28278
28279         stack_trap cleanup_test_432 EXIT
28280         mkdir $DIR/$tdir
28281         mkdir $tmpdir
28282
28283         do_facet mgs $LCTL nodemap_activate 1
28284         wait_nm_sync active
28285         do_facet mgs $LCTL nodemap_modify --name default \
28286                 --property admin --value 1
28287         do_facet mgs $LCTL nodemap_modify --name default \
28288                 --property trusted --value 1
28289         cancel_lru_locks mdc
28290         wait_nm_sync default admin_nodemap
28291         wait_nm_sync default trusted_nodemap
28292
28293         if [ $(mv $tmpdir $DIR/$tdir/ 2>&1 |
28294                grep -ci "Operation not permitted") -ne 0 ]; then
28295                 error "mv $tmpdir $DIR/$tdir/ hits 'Operation not permitted'"
28296         fi
28297 }
28298 run_test 432 "mv dir from outside Lustre"
28299
28300 test_433() {
28301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28302
28303         [[ -n "$($LCTL list_param llite.*.inode_cache 2>/dev/null)" ]] ||
28304                 skip "inode cache not supported"
28305
28306         $LCTL set_param llite.*.inode_cache=0
28307         stack_trap "$LCTL set_param llite.*.inode_cache=1"
28308
28309         local count=256
28310         local before
28311         local after
28312
28313         cancel_lru_locks mdc
28314         test_mkdir $DIR/$tdir || error "mkdir $tdir"
28315         createmany -m $DIR/$tdir/f $count
28316         createmany -d $DIR/$tdir/d $count
28317         ls -l $DIR/$tdir > /dev/null
28318         stack_trap "rm -rf $DIR/$tdir"
28319
28320         before=$(num_objects)
28321         cancel_lru_locks mdc
28322         after=$(num_objects)
28323
28324         # sometimes even @before is less than 2 * count
28325         while (( before - after < count )); do
28326                 sleep 1
28327                 after=$(num_objects)
28328                 wait=$((wait + 1))
28329                 (( wait % 5 == 0 )) && echo "wait $wait seconds objects: $after"
28330                 if (( wait > 60 )); then
28331                         error "inode slab grew from $before to $after"
28332                 fi
28333         done
28334
28335         echo "lustre_inode_cache $before objs before lock cancel, $after after"
28336 }
28337 run_test 433 "ldlm lock cancel releases dentries and inodes"
28338
28339 test_434() {
28340         local file
28341         local getxattr_count
28342         local mdc_stat_param="mdc.$FSNAME-MDT0000*.md_stats"
28343         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
28344
28345         [[ $(getenforce) == "Disabled" ]] ||
28346                 skip "lsm selinux module have to be disabled for this test"
28347
28348         test_mkdir -i 0 -c1 $DIR/$tdir/ ||
28349                 error "fail to create $DIR/$tdir/ on MDT0000"
28350
28351         touch $DIR/$tdir/$tfile-{001..100}
28352
28353         # disable the xattr cache
28354         save_lustre_params client "llite.*.xattr_cache" > $p
28355         lctl set_param llite.*.xattr_cache=0
28356         stack_trap "restore_lustre_params < $p; rm -f $p" EXIT
28357
28358         # clear clients mdc stats
28359         clear_stats $mdc_stat_param ||
28360                 error "fail to clear stats on mdc MDT0000"
28361
28362         for file in $DIR/$tdir/$tfile-{001..100}; do
28363                 getfattr -n security.selinux $file |&
28364                         grep -q "Operation not supported" ||
28365                         error "getxattr on security.selinux should return EOPNOTSUPP"
28366         done
28367
28368         getxattr_count=$(calc_stats $mdc_stat_param "getxattr")
28369         (( getxattr_count < 100 )) ||
28370                 error "client sent $getxattr_count getxattr RPCs to the MDS"
28371 }
28372 run_test 434 "Client should not send RPCs for security.selinux with SElinux disabled"
28373
28374 test_440() {
28375         if [[ -f $LUSTRE/scripts/bash-completion/lustre ]]; then
28376                 source $LUSTRE/scripts/bash-completion/lustre
28377         elif [[ -f /usr/share/bash-completion/completions/lustre ]]; then
28378                 source /usr/share/bash-completion/completions/lustre
28379         else
28380                 skip "bash completion scripts not found"
28381         fi
28382
28383         local lctl_completions
28384         local lfs_completions
28385
28386         lctl_completions=$(_lustre_cmds lctl)
28387         if [[ ! $lctl_completions =~ "get_param" ]]; then
28388                 error "lctl bash completion failed"
28389         fi
28390
28391         lfs_completions=$(_lustre_cmds lfs)
28392         if [[ ! $lfs_completions =~ "setstripe" ]]; then
28393                 error "lfs bash completion failed"
28394         fi
28395 }
28396 run_test 440 "bash completion for lfs, lctl"
28397
28398 prep_801() {
28399         [[ $MDS1_VERSION -lt $(version_code 2.9.55) ]] ||
28400         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
28401                 skip "Need server version at least 2.9.55"
28402
28403         start_full_debug_logging
28404 }
28405
28406 post_801() {
28407         stop_full_debug_logging
28408 }
28409
28410 barrier_stat() {
28411         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28412                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28413                            awk '/The barrier for/ { print $7 }')
28414                 echo $st
28415         else
28416                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
28417                 echo \'$st\'
28418         fi
28419 }
28420
28421 barrier_expired() {
28422         local expired
28423
28424         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
28425                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
28426                           awk '/will be expired/ { print $7 }')
28427         else
28428                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
28429         fi
28430
28431         echo $expired
28432 }
28433
28434 test_801a() {
28435         prep_801
28436
28437         echo "Start barrier_freeze at: $(date)"
28438         #define OBD_FAIL_BARRIER_DELAY          0x2202
28439         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28440         # Do not reduce barrier time - See LU-11873
28441         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
28442
28443         sleep 2
28444         local b_status=$(barrier_stat)
28445         echo "Got barrier status at: $(date)"
28446         [ "$b_status" = "'freezing_p1'" ] ||
28447                 error "(1) unexpected barrier status $b_status"
28448
28449         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28450         wait
28451         b_status=$(barrier_stat)
28452         [ "$b_status" = "'frozen'" ] ||
28453                 error "(2) unexpected barrier status $b_status"
28454
28455         local expired=$(barrier_expired)
28456         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
28457         sleep $((expired + 3))
28458
28459         b_status=$(barrier_stat)
28460         [ "$b_status" = "'expired'" ] ||
28461                 error "(3) unexpected barrier status $b_status"
28462
28463         # Do not reduce barrier time - See LU-11873
28464         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
28465                 error "(4) fail to freeze barrier"
28466
28467         b_status=$(barrier_stat)
28468         [ "$b_status" = "'frozen'" ] ||
28469                 error "(5) unexpected barrier status $b_status"
28470
28471         echo "Start barrier_thaw at: $(date)"
28472         #define OBD_FAIL_BARRIER_DELAY          0x2202
28473         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
28474         do_facet mgs $LCTL barrier_thaw $FSNAME &
28475
28476         sleep 2
28477         b_status=$(barrier_stat)
28478         echo "Got barrier status at: $(date)"
28479         [ "$b_status" = "'thawing'" ] ||
28480                 error "(6) unexpected barrier status $b_status"
28481
28482         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
28483         wait
28484         b_status=$(barrier_stat)
28485         [ "$b_status" = "'thawed'" ] ||
28486                 error "(7) unexpected barrier status $b_status"
28487
28488         #define OBD_FAIL_BARRIER_FAILURE        0x2203
28489         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
28490         do_facet mgs $LCTL barrier_freeze $FSNAME
28491
28492         b_status=$(barrier_stat)
28493         [ "$b_status" = "'failed'" ] ||
28494                 error "(8) unexpected barrier status $b_status"
28495
28496         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
28497         do_facet mgs $LCTL barrier_thaw $FSNAME
28498
28499         post_801
28500 }
28501 run_test 801a "write barrier user interfaces and stat machine"
28502
28503 test_801b() {
28504         prep_801
28505
28506         mkdir $DIR/$tdir || error "(1) fail to mkdir"
28507         createmany -d $DIR/$tdir/d 6 || error "(2) fail to mkdir"
28508         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
28509         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
28510         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
28511
28512         cancel_lru_locks mdc
28513
28514         # 180 seconds should be long enough
28515         do_facet mgs $LCTL barrier_freeze $FSNAME 180
28516
28517         local b_status=$(barrier_stat)
28518         [ "$b_status" = "'frozen'" ] ||
28519                 error "(6) unexpected barrier status $b_status"
28520
28521         mkdir $DIR/$tdir/d0/d10 &
28522         mkdir_pid=$!
28523
28524         touch $DIR/$tdir/d1/f13 &
28525         touch_pid=$!
28526
28527         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
28528         ln_pid=$!
28529
28530         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
28531         mv_pid=$!
28532
28533         rm -f $DIR/$tdir/d4/f12 &
28534         rm_pid=$!
28535
28536         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
28537
28538         # To guarantee taht the 'stat' is not blocked
28539         b_status=$(barrier_stat)
28540         [ "$b_status" = "'frozen'" ] ||
28541                 error "(8) unexpected barrier status $b_status"
28542
28543         # let above commands to run at background
28544         sleep 5
28545
28546         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
28547         ps -p $touch_pid || error "(10) touch should be blocked"
28548         ps -p $ln_pid || error "(11) link should be blocked"
28549         ps -p $mv_pid || error "(12) rename should be blocked"
28550         ps -p $rm_pid || error "(13) unlink should be blocked"
28551
28552         b_status=$(barrier_stat)
28553         [ "$b_status" = "'frozen'" ] ||
28554                 error "(14) unexpected barrier status $b_status"
28555
28556         do_facet mgs $LCTL barrier_thaw $FSNAME
28557         b_status=$(barrier_stat)
28558         [ "$b_status" = "'thawed'" ] ||
28559                 error "(15) unexpected barrier status $b_status"
28560
28561         wait $mkdir_pid || error "(16) mkdir should succeed"
28562         wait $touch_pid || error "(17) touch should succeed"
28563         wait $ln_pid || error "(18) link should succeed"
28564         wait $mv_pid || error "(19) rename should succeed"
28565         wait $rm_pid || error "(20) unlink should succeed"
28566
28567         post_801
28568 }
28569 run_test 801b "modification will be blocked by write barrier"
28570
28571 test_801c() {
28572         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28573
28574         prep_801
28575
28576         stop mds2 || error "(1) Fail to stop mds2"
28577
28578         do_facet mgs $LCTL barrier_freeze $FSNAME 30
28579
28580         local b_status=$(barrier_stat)
28581         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
28582                 do_facet mgs $LCTL barrier_thaw $FSNAME
28583                 error "(2) unexpected barrier status $b_status"
28584         }
28585
28586         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28587                 error "(3) Fail to rescan barrier bitmap"
28588
28589         # Do not reduce barrier time - See LU-11873
28590         do_facet mgs $LCTL barrier_freeze $FSNAME 20
28591
28592         b_status=$(barrier_stat)
28593         [ "$b_status" = "'frozen'" ] ||
28594                 error "(4) unexpected barrier status $b_status"
28595
28596         do_facet mgs $LCTL barrier_thaw $FSNAME
28597         b_status=$(barrier_stat)
28598         [ "$b_status" = "'thawed'" ] ||
28599                 error "(5) unexpected barrier status $b_status"
28600
28601         local devname=$(mdsdevname 2)
28602
28603         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
28604
28605         do_facet mgs $LCTL barrier_rescan $FSNAME ||
28606                 error "(7) Fail to rescan barrier bitmap"
28607
28608         post_801
28609 }
28610 run_test 801c "rescan barrier bitmap"
28611
28612 test_802b() {
28613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28614         remote_mds_nodsh && skip "remote MDS with nodsh"
28615
28616         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
28617                 skip "readonly option not available"
28618
28619         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
28620
28621         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
28622                 error "(2) Fail to copy"
28623
28624         # write back all cached data before setting MDT to readonly
28625         cancel_lru_locks
28626         sync_all_data
28627
28628         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
28629         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
28630
28631         echo "Modify should be refused"
28632         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
28633
28634         echo "Read should be allowed"
28635         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
28636                 error "(7) Read should succeed under ro mode"
28637
28638         # disable readonly
28639         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
28640 }
28641 run_test 802b "be able to set MDTs to readonly"
28642
28643 test_803a() {
28644         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28645         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28646                 skip "MDS needs to be newer than 2.10.54"
28647
28648         mkdir_on_mdt0 $DIR/$tdir
28649         # Create some objects on all MDTs to trigger related logs objects
28650         for idx in $(seq $MDSCOUNT); do
28651                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
28652                         $DIR/$tdir/dir${idx} ||
28653                         error "Fail to create $DIR/$tdir/dir${idx}"
28654         done
28655
28656         wait_delete_completed # ensure old test cleanups are finished
28657         sleep 3
28658         echo "before create:"
28659         $LFS df -i $MOUNT
28660         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28661
28662         for i in {1..10}; do
28663                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
28664                         error "Fail to create $DIR/$tdir/foo$i"
28665         done
28666
28667         # sync ZFS-on-MDS to refresh statfs data
28668         wait_zfs_commit mds1
28669         sleep 3
28670         echo "after create:"
28671         $LFS df -i $MOUNT
28672         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28673
28674         # allow for an llog to be cleaned up during the test
28675         [ $after_used -ge $((before_used + 10 - 1)) ] ||
28676                 error "before ($before_used) + 10 > after ($after_used)"
28677
28678         for i in {1..10}; do
28679                 rm -rf $DIR/$tdir/foo$i ||
28680                         error "Fail to remove $DIR/$tdir/foo$i"
28681         done
28682
28683         # sync ZFS-on-MDS to refresh statfs data
28684         wait_zfs_commit mds1
28685         wait_delete_completed
28686         sleep 3 # avoid MDT return cached statfs
28687         echo "after unlink:"
28688         $LFS df -i $MOUNT
28689         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
28690
28691         # allow for an llog to be created during the test
28692         [ $after_used -le $((before_used + 1)) ] ||
28693                 error "after ($after_used) > before ($before_used) + 1"
28694 }
28695 run_test 803a "verify agent object for remote object"
28696
28697 test_803b() {
28698         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28699         [ $MDS1_VERSION -lt $(version_code 2.13.56) ] &&
28700                 skip "MDS needs to be newer than 2.13.56"
28701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
28702
28703         for i in $(seq 0 $((MDSCOUNT - 1))); do
28704                 $LFS mkdir -i $i $DIR/$tdir.$i || error "mkdir $tdir.$i"
28705         done
28706
28707         local before=0
28708         local after=0
28709
28710         local tmp
28711
28712         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28713         for i in $(seq 0 $((MDSCOUNT - 1))); do
28714                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28715                         awk '/getattr/ { print $2 }')
28716                 before=$((before + tmp))
28717         done
28718         stat $DIR/$tdir.* >/dev/null || error "stat $tdir.*"
28719         for i in $(seq 0 $((MDSCOUNT - 1))); do
28720                 tmp=$(do_facet mds$i $LCTL get_param mdt.*-MDT000$i.md_stats |
28721                         awk '/getattr/ { print $2 }')
28722                 after=$((after + tmp))
28723         done
28724
28725         [ $before -eq $after ] || error "getattr count $before != $after"
28726 }
28727 run_test 803b "remote object can getattr from cache"
28728
28729 test_804() {
28730         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
28731         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
28732                 skip "MDS needs to be newer than 2.10.54"
28733         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
28734
28735         mkdir -p $DIR/$tdir
28736         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
28737                 error "Fail to create $DIR/$tdir/dir0"
28738
28739         local fid=$($LFS path2fid $DIR/$tdir/dir0)
28740         local dev=$(mdsdevname 2)
28741
28742         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28743                 grep ${fid} || error "NOT found agent entry for dir0"
28744
28745         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
28746                 error "Fail to create $DIR/$tdir/dir1"
28747
28748         touch $DIR/$tdir/dir1/foo0 ||
28749                 error "Fail to create $DIR/$tdir/dir1/foo0"
28750         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
28751         local rc=0
28752
28753         for idx in $(seq $MDSCOUNT); do
28754                 dev=$(mdsdevname $idx)
28755                 do_facet mds${idx} \
28756                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28757                         grep ${fid} && rc=$idx
28758         done
28759
28760         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
28761                 error "Fail to rename foo0 to foo1"
28762         if [ $rc -eq 0 ]; then
28763                 for idx in $(seq $MDSCOUNT); do
28764                         dev=$(mdsdevname $idx)
28765                         do_facet mds${idx} \
28766                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28767                         grep ${fid} && rc=$idx
28768                 done
28769         fi
28770
28771         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
28772                 error "Fail to rename foo1 to foo2"
28773         if [ $rc -eq 0 ]; then
28774                 for idx in $(seq $MDSCOUNT); do
28775                         dev=$(mdsdevname $idx)
28776                         do_facet mds${idx} \
28777                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
28778                         grep ${fid} && rc=$idx
28779                 done
28780         fi
28781
28782         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
28783
28784         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
28785                 error "Fail to link to $DIR/$tdir/dir1/foo2"
28786         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
28787                 error "Fail to rename foo2 to foo0"
28788         unlink $DIR/$tdir/dir1/foo0 ||
28789                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
28790         rm -rf $DIR/$tdir/dir0 ||
28791                 error "Fail to rm $DIR/$tdir/dir0"
28792
28793         for idx in $(seq $MDSCOUNT); do
28794                 rc=0
28795
28796                 stop mds${idx}
28797                 dev=$(mdsdevname $idx)
28798                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
28799                         rc=$?
28800                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
28801                         error "mount mds$idx failed"
28802                 df $MOUNT > /dev/null 2>&1
28803
28804                 # e2fsck should not return error
28805                 [ $rc -eq 0 ] ||
28806                         error "e2fsck detected error on MDT${idx}: rc=$rc"
28807         done
28808 }
28809 run_test 804 "verify agent entry for remote entry"
28810
28811 cleanup_805() {
28812         do_facet $SINGLEMDS zfs set quota=$old $fsset
28813         unlinkmany $DIR/$tdir/f- 1000000
28814         trap 0
28815 }
28816
28817 test_805() {
28818         local zfs_version=$(do_facet mds1 cat /sys/module/zfs/version)
28819         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
28820         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
28821                 skip "netfree not implemented before 0.7"
28822         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
28823                 skip "Need MDS version at least 2.10.57"
28824
28825         local fsset
28826         local freekb
28827         local usedkb
28828         local old
28829         local quota
28830         local pref="osd-zfs.$FSNAME-MDT0000."
28831
28832         # limit available space on MDS dataset to meet nospace issue
28833         # quickly. then ZFS 0.7.2 can use reserved space if asked
28834         # properly (using netfree flag in osd_declare_destroy()
28835         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
28836         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
28837                 gawk '{print $3}')
28838         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
28839         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
28840         let "usedkb=usedkb-freekb"
28841         let "freekb=freekb/2"
28842         if let "freekb > 5000"; then
28843                 let "freekb=5000"
28844         fi
28845         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
28846         trap cleanup_805 EXIT
28847         mkdir_on_mdt0 $DIR/$tdir
28848         $LFS setstripe -E 1M -c2 -E 4M -c2 -E -1 -c2 $DIR/$tdir ||
28849                 error "Can't set PFL layout"
28850         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
28851         rm -rf $DIR/$tdir || error "not able to remove"
28852         do_facet $SINGLEMDS zfs set quota=$old $fsset
28853         trap 0
28854 }
28855 run_test 805 "ZFS can remove from full fs"
28856
28857 # Size-on-MDS test
28858 check_lsom_data()
28859 {
28860         local file=$1
28861         local expect=$(stat -c %s $file)
28862
28863         check_lsom_size $1 $expect
28864
28865         local blocks=$($LFS getsom -b $file)
28866         expect=$(stat -c %b $file)
28867         [[ $blocks == $expect ]] ||
28868                 error "$file expected blocks: $expect, got: $blocks"
28869 }
28870
28871 check_lsom_size()
28872 {
28873         local size
28874         local expect=$2
28875
28876         cancel_lru_locks mdc
28877
28878         size=$($LFS getsom -s $1)
28879         [[ $size == $expect ]] ||
28880                 error "$file expected size: $expect, got: $size"
28881 }
28882
28883 test_806() {
28884         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28885                 skip "Need MDS version at least 2.11.52"
28886
28887         local bs=1048576
28888
28889         $LFS setstripe -c-1 $DIR/$tfile || error "setstripe $tfile failed"
28890
28891         # Disable opencache
28892         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
28893         save_lustre_params client "llite.*.opencache_threshold_count" > $save
28894         lctl set_param llite.*.opencache_threshold_count=0
28895         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
28896
28897         # single-threaded write
28898         echo "Test SOM for single-threaded write"
28899         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
28900                 error "write $tfile failed"
28901         check_lsom_size $DIR/$tfile $bs
28902
28903         local num=32
28904         local size=$(($num * $bs))
28905         local offset=0
28906         local i
28907
28908         echo "Test SOM for single client multi-threaded($num) write"
28909         $TRUNCATE $DIR/$tfile 0
28910         for ((i = 0; i < $num; i++)); do
28911                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28912                 local pids[$i]=$!
28913                 offset=$((offset + $bs))
28914         done
28915         for (( i=0; i < $num; i++ )); do
28916                 wait ${pids[$i]}
28917         done
28918         check_lsom_size $DIR/$tfile $size
28919
28920         $TRUNCATE $DIR/$tfile 0
28921         for ((i = 0; i < $num; i++)); do
28922                 offset=$((offset - $bs))
28923                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28924                 local pids[$i]=$!
28925         done
28926         for (( i=0; i < $num; i++ )); do
28927                 wait ${pids[$i]}
28928         done
28929         check_lsom_size $DIR/$tfile $size
28930
28931         # multi-client writes
28932         num=$(get_node_count ${CLIENTS//,/ })
28933         size=$(($num * $bs))
28934         offset=0
28935         i=0
28936
28937         echo "Test SOM for multi-client ($num) writes"
28938         $TRUNCATE $DIR/$tfile 0
28939         for client in ${CLIENTS//,/ }; do
28940                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28941                 local pids[$i]=$!
28942                 i=$((i + 1))
28943                 offset=$((offset + $bs))
28944         done
28945         for (( i=0; i < $num; i++ )); do
28946                 wait ${pids[$i]}
28947         done
28948         check_lsom_size $DIR/$tfile $offset
28949
28950         i=0
28951         $TRUNCATE $DIR/$tfile 0
28952         for client in ${CLIENTS//,/ }; do
28953                 offset=$((offset - $bs))
28954                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
28955                 local pids[$i]=$!
28956                 i=$((i + 1))
28957         done
28958         for (( i=0; i < $num; i++ )); do
28959                 wait ${pids[$i]}
28960         done
28961         check_lsom_size $DIR/$tfile $size
28962
28963         # verify SOM blocks count
28964         echo "Verify SOM block count"
28965         $TRUNCATE $DIR/$tfile 0
28966         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs))YSc ||
28967                 error "failed to write file $tfile with fdatasync and fstat"
28968         check_lsom_data $DIR/$tfile
28969
28970         $TRUNCATE $DIR/$tfile 0
28971         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w$((bs * 2))Yc ||
28972                 error "failed to write file $tfile with fdatasync"
28973         check_lsom_data $DIR/$tfile
28974
28975         $TRUNCATE $DIR/$tfile 0
28976         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:O_SYNC:w$((bs * 3))c ||
28977                 error "failed to write file $tfile with sync IO"
28978         check_lsom_data $DIR/$tfile
28979
28980         # verify truncate
28981         echo "Test SOM for truncate"
28982         # use ftruncate to sync blocks on close request
28983         $MULTIOP $DIR/$tfile oO_WRONLY:T16384c
28984         check_lsom_size $DIR/$tfile 16384
28985         check_lsom_data $DIR/$tfile
28986
28987         $TRUNCATE $DIR/$tfile 1234
28988         check_lsom_size $DIR/$tfile 1234
28989         # sync blocks on the MDT
28990         $MULTIOP $DIR/$tfile oc
28991         check_lsom_data $DIR/$tfile
28992 }
28993 run_test 806 "Verify Lazy Size on MDS"
28994
28995 test_807() {
28996         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
28997         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
28998                 skip "Need MDS version at least 2.11.52"
28999
29000         # Registration step
29001         changelog_register || error "changelog_register failed"
29002         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
29003         changelog_users $SINGLEMDS | grep -q $cl_user ||
29004                 error "User $cl_user not found in changelog_users"
29005
29006         rm -rf $DIR/$tdir || error "rm $tdir failed"
29007         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29008         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
29009         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
29010         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
29011                 error "truncate $tdir/trunc failed"
29012
29013         local bs=1048576
29014         echo "Test SOM for single-threaded write with fsync"
29015         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
29016                 error "write $tfile failed"
29017         sync;sync;sync
29018
29019         # multi-client wirtes
29020         local num=$(get_node_count ${CLIENTS//,/ })
29021         local offset=0
29022         local i=0
29023
29024         echo "Test SOM for multi-client ($num) writes"
29025         touch $DIR/$tfile || error "touch $tfile failed"
29026         $TRUNCATE $DIR/$tfile 0
29027         for client in ${CLIENTS//,/ }; do
29028                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
29029                 local pids[$i]=$!
29030                 i=$((i + 1))
29031                 offset=$((offset + $bs))
29032         done
29033         for (( i=0; i < $num; i++ )); do
29034                 wait ${pids[$i]}
29035         done
29036
29037         do_rpc_nodes "$CLIENTS" cancel_lru_locks osc
29038         do_nodes "$CLIENTS" "sync ; sleep 5 ; sync"
29039         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
29040         check_lsom_data $DIR/$tdir/trunc
29041         check_lsom_data $DIR/$tdir/single_dd
29042         check_lsom_data $DIR/$tfile
29043
29044         rm -rf $DIR/$tdir
29045         # Deregistration step
29046         changelog_deregister || error "changelog_deregister failed"
29047 }
29048 run_test 807 "verify LSOM syncing tool"
29049
29050 check_som_nologged()
29051 {
29052         local lines=$($LFS changelog $FSNAME-MDT0000 |
29053                 grep 'x=trusted.som' | wc -l)
29054         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
29055 }
29056
29057 test_808() {
29058         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
29059                 skip "Need MDS version at least 2.11.55"
29060
29061         # Registration step
29062         changelog_register || error "changelog_register failed"
29063
29064         touch $DIR/$tfile || error "touch $tfile failed"
29065         check_som_nologged
29066
29067         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
29068                 error "write $tfile failed"
29069         check_som_nologged
29070
29071         $TRUNCATE $DIR/$tfile 1234
29072         check_som_nologged
29073
29074         $TRUNCATE $DIR/$tfile 1048576
29075         check_som_nologged
29076
29077         # Deregistration step
29078         changelog_deregister || error "changelog_deregister failed"
29079 }
29080 run_test 808 "Check trusted.som xattr not logged in Changelogs"
29081
29082 check_som_nodata()
29083 {
29084         $LFS getsom $1
29085         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
29086 }
29087
29088 test_809() {
29089         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
29090                 skip "Need MDS version at least 2.11.56"
29091
29092         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
29093                 error "failed to create DoM-only file $DIR/$tfile"
29094         touch $DIR/$tfile || error "touch $tfile failed"
29095         check_som_nodata $DIR/$tfile
29096
29097         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
29098                 error "write $tfile failed"
29099         check_som_nodata $DIR/$tfile
29100
29101         $TRUNCATE $DIR/$tfile 1234
29102         check_som_nodata $DIR/$tfile
29103
29104         $TRUNCATE $DIR/$tfile 4097
29105         check_som_nodata $DIR/$file
29106 }
29107 run_test 809 "Verify no SOM xattr store for DoM-only files"
29108
29109 test_810() {
29110         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29111         $GSS && skip_env "could not run with gss"
29112         [[ $OST1_VERSION -gt $(version_code 2.12.58) ]] ||
29113                 skip "OST < 2.12.58 doesn't align checksum"
29114
29115         set_checksums 1
29116         stack_trap "set_checksums $ORIG_CSUM" EXIT
29117         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
29118
29119         local csum
29120         local before
29121         local after
29122         for csum in $CKSUM_TYPES; do
29123                 #define OBD_FAIL_OSC_NO_GRANT   0x411
29124                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
29125                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
29126                         eval set -- $i
29127                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
29128                         before=$(md5sum $DIR/$tfile)
29129                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
29130                         after=$(md5sum $DIR/$tfile)
29131                         [ "$before" == "$after" ] ||
29132                                 error "$csum: $before != $after bs=$1 seek=$2"
29133                 done
29134         done
29135 }
29136 run_test 810 "partial page writes on ZFS (LU-11663)"
29137
29138 test_812a() {
29139         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29140                 skip "OST < 2.12.51 doesn't support this fail_loc"
29141
29142         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29143         # ensure ost1 is connected
29144         stat $DIR/$tfile >/dev/null || error "can't stat"
29145         wait_osc_import_state client ost1 FULL
29146         # no locks, no reqs to let the connection idle
29147         cancel_lru_locks osc
29148
29149         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29150 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29151         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29152         wait_osc_import_state client ost1 CONNECTING
29153         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29154
29155         stat $DIR/$tfile >/dev/null || error "can't stat file"
29156 }
29157 run_test 812a "do not drop reqs generated when imp is going to idle (LU-11951)"
29158
29159 test_812b() { # LU-12378
29160         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
29161                 skip "OST < 2.12.51 doesn't support this fail_loc"
29162
29163         $LFS setstripe -c 1 -i 0 $DIR/$tfile || error "setstripe failed"
29164         # ensure ost1 is connected
29165         stat $DIR/$tfile >/dev/null || error "can't stat"
29166         wait_osc_import_state client ost1 FULL
29167         # no locks, no reqs to let the connection idle
29168         cancel_lru_locks osc
29169
29170         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
29171 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
29172         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
29173         wait_osc_import_state client ost1 CONNECTING
29174         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
29175
29176         $LFS quota -u 0 $DIR/ || error "lfs quota should succeed"
29177         wait_osc_import_state client ost1 IDLE
29178 }
29179 run_test 812b "do not drop no resend request for idle connect"
29180
29181 test_812c() {
29182         local old
29183
29184         old=$($LCTL get_param -n osc.*.idle_timeout | head -n 1)
29185
29186         $LFS setstripe -c 1 -o 0 $DIR/$tfile
29187         $LFS getstripe $DIR/$tfile
29188         $LCTL set_param osc.*.idle_timeout=10
29189         stack_trap "$LCTL set_param osc.*.idle_timeout=$old" EXIT
29190         # ensure ost1 is connected
29191         stat $DIR/$tfile >/dev/null || error "can't stat"
29192         wait_osc_import_state client ost1 FULL
29193         # no locks, no reqs to let the connection idle
29194         cancel_lru_locks osc
29195
29196 #define OBD_FAIL_PTLRPC_IDLE_RACE        0x533
29197         $LCTL set_param fail_loc=0x80000533
29198         sleep 15
29199         dd if=/dev/zero of=$DIR/$tfile count=1 conv=sync || error "dd failed"
29200 }
29201 run_test 812c "idle import vs lock enqueue race"
29202
29203 test_813() {
29204         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
29205         [ -z "$file_heat_sav" ] && skip "no file heat support"
29206
29207         local readsample
29208         local writesample
29209         local readbyte
29210         local writebyte
29211         local readsample1
29212         local writesample1
29213         local readbyte1
29214         local writebyte1
29215
29216         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
29217         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
29218
29219         $LCTL set_param -n llite.*.file_heat=1
29220         echo "Turn on file heat"
29221         echo "Period second: $period_second, Decay percentage: $decay_pct"
29222
29223         echo "QQQQ" > $DIR/$tfile
29224         echo "QQQQ" > $DIR/$tfile
29225         echo "QQQQ" > $DIR/$tfile
29226         cat $DIR/$tfile > /dev/null
29227         cat $DIR/$tfile > /dev/null
29228         cat $DIR/$tfile > /dev/null
29229         cat $DIR/$tfile > /dev/null
29230
29231         local out=$($LFS heat_get $DIR/$tfile)
29232
29233         $LFS heat_get $DIR/$tfile
29234         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29235         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29236         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29237         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29238
29239         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
29240         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
29241         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
29242         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
29243
29244         sleep $((period_second + 3))
29245         echo "Sleep $((period_second + 3)) seconds..."
29246         # The recursion formula to calculate the heat of the file f is as
29247         # follow:
29248         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
29249         # Where Hi is the heat value in the period between time points i*I and
29250         # (i+1)*I; Ci is the access count in the period; the symbol P refers
29251         # to the weight of Ci.
29252         out=$($LFS heat_get $DIR/$tfile)
29253         $LFS heat_get $DIR/$tfile
29254         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29255         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29256         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29257         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29258
29259         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
29260                 error "read sample ($readsample) is wrong"
29261         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
29262                 error "write sample ($writesample) is wrong"
29263         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
29264                 error "read bytes ($readbyte) is wrong"
29265         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
29266                 error "write bytes ($writebyte) is wrong"
29267
29268         echo "QQQQ" > $DIR/$tfile
29269         echo "QQQQ" > $DIR/$tfile
29270         echo "QQQQ" > $DIR/$tfile
29271         cat $DIR/$tfile > /dev/null
29272         cat $DIR/$tfile > /dev/null
29273         cat $DIR/$tfile > /dev/null
29274         cat $DIR/$tfile > /dev/null
29275
29276         sleep $((period_second + 3))
29277         echo "Sleep $((period_second + 3)) seconds..."
29278
29279         out=$($LFS heat_get $DIR/$tfile)
29280         $LFS heat_get $DIR/$tfile
29281         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29282         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29283         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29284         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29285
29286         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
29287                 4 * $decay_pct) / 100") -eq 1 ] ||
29288                 error "read sample ($readsample1) is wrong"
29289         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
29290                 3 * $decay_pct) / 100") -eq 1 ] ||
29291                 error "write sample ($writesample1) is wrong"
29292         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
29293                 20 * $decay_pct) / 100") -eq 1 ] ||
29294                 error "read bytes ($readbyte1) is wrong"
29295         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
29296                 15 * $decay_pct) / 100") -eq 1 ] ||
29297                 error "write bytes ($writebyte1) is wrong"
29298
29299         echo "Turn off file heat for the file $DIR/$tfile"
29300         $LFS heat_set -o $DIR/$tfile
29301
29302         echo "QQQQ" > $DIR/$tfile
29303         echo "QQQQ" > $DIR/$tfile
29304         echo "QQQQ" > $DIR/$tfile
29305         cat $DIR/$tfile > /dev/null
29306         cat $DIR/$tfile > /dev/null
29307         cat $DIR/$tfile > /dev/null
29308         cat $DIR/$tfile > /dev/null
29309
29310         out=$($LFS heat_get $DIR/$tfile)
29311         $LFS heat_get $DIR/$tfile
29312         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29313         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29314         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29315         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29316
29317         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29318         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29319         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29320         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29321
29322         echo "Trun on file heat for the file $DIR/$tfile"
29323         $LFS heat_set -O $DIR/$tfile
29324
29325         echo "QQQQ" > $DIR/$tfile
29326         echo "QQQQ" > $DIR/$tfile
29327         echo "QQQQ" > $DIR/$tfile
29328         cat $DIR/$tfile > /dev/null
29329         cat $DIR/$tfile > /dev/null
29330         cat $DIR/$tfile > /dev/null
29331         cat $DIR/$tfile > /dev/null
29332
29333         out=$($LFS heat_get $DIR/$tfile)
29334         $LFS heat_get $DIR/$tfile
29335         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29336         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29337         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29338         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29339
29340         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
29341         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
29342         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
29343         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
29344
29345         $LFS heat_set -c $DIR/$tfile
29346         $LCTL set_param -n llite.*.file_heat=0
29347         echo "Turn off file heat support for the Lustre filesystem"
29348
29349         echo "QQQQ" > $DIR/$tfile
29350         echo "QQQQ" > $DIR/$tfile
29351         echo "QQQQ" > $DIR/$tfile
29352         cat $DIR/$tfile > /dev/null
29353         cat $DIR/$tfile > /dev/null
29354         cat $DIR/$tfile > /dev/null
29355         cat $DIR/$tfile > /dev/null
29356
29357         out=$($LFS heat_get $DIR/$tfile)
29358         $LFS heat_get $DIR/$tfile
29359         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
29360         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
29361         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
29362         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
29363
29364         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
29365         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
29366         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
29367         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
29368
29369         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
29370         rm -f $DIR/$tfile
29371 }
29372 run_test 813 "File heat verfication"
29373
29374 test_814()
29375 {
29376         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
29377         echo -n y >> $DIR/$tfile
29378         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
29379         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
29380 }
29381 run_test 814 "sparse cp works as expected (LU-12361)"
29382
29383 test_815()
29384 {
29385         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
29386         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
29387 }
29388 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
29389
29390 test_816() {
29391         local ost1_imp=$(get_osc_import_name client ost1)
29392         local imp_name=$($LCTL list_param osc.$ost1_imp | head -n1 |
29393                          cut -d'.' -f2)
29394
29395         $LFS setstripe -c 1 -i 0 $DIR/$tfile
29396         # ensure ost1 is connected
29397
29398         stat $DIR/$tfile >/dev/null || error "can't stat"
29399         wait_osc_import_state client ost1 FULL
29400         # no locks, no reqs to let the connection idle
29401         cancel_lru_locks osc
29402         lru_resize_disable osc
29403         local before
29404         local now
29405         before=$($LCTL get_param -n \
29406                  ldlm.namespaces.$imp_name.lru_size)
29407
29408         wait_osc_import_state client ost1 IDLE
29409         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
29410         now=$($LCTL get_param -n \
29411               ldlm.namespaces.$imp_name.lru_size)
29412         [ $before == $now ] || error "lru_size changed $before != $now"
29413 }
29414 run_test 816 "do not reset lru_resize on idle reconnect"
29415
29416 cleanup_817() {
29417         umount $tmpdir
29418         exportfs -u localhost:$DIR/nfsexp
29419         rm -rf $DIR/nfsexp
29420 }
29421
29422 test_817() {
29423         systemctl restart nfs-server.service || skip "failed to restart nfsd"
29424
29425         mkdir -p $DIR/nfsexp
29426         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
29427                 error "failed to export nfs"
29428
29429         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
29430         stack_trap cleanup_817 EXIT
29431
29432         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
29433                 error "failed to mount nfs to $tmpdir"
29434
29435         cp /bin/true $tmpdir
29436         $DIR/nfsexp/true || error "failed to execute 'true' command"
29437 }
29438 run_test 817 "nfsd won't cache write lock for exec file"
29439
29440 test_818() {
29441         test_mkdir -i0 -c1 $DIR/$tdir
29442         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
29443         $LFS setstripe -c1 -i1 $DIR/$tdir/$tfile
29444         stop $SINGLEMDS
29445
29446         # restore osp-syn threads
29447         stack_trap "fail $SINGLEMDS"
29448
29449         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
29450         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
29451         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
29452                 error "start $SINGLEMDS failed"
29453         rm -rf $DIR/$tdir
29454
29455         local testid=$(echo $TESTNAME | tr '_' ' ')
29456
29457         do_facet mds1 dmesg | tac | sed "/$testid/,$ d" |
29458                 grep "run LFSCK" || error "run LFSCK is not suggested"
29459 }
29460 run_test 818 "unlink with failed llog"
29461
29462 test_819a() {
29463         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29464         cancel_lru_locks osc
29465         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29466         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29467         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
29468         rm -f $TDIR/$tfile
29469 }
29470 run_test 819a "too big niobuf in read"
29471
29472 test_819b() {
29473         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
29474         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
29475         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29476         cancel_lru_locks osc
29477         sleep 1
29478         rm -f $TDIR/$tfile
29479 }
29480 run_test 819b "too big niobuf in write"
29481
29482
29483 function test_820_start_ost() {
29484         sleep 5
29485
29486         for num in $(seq $OSTCOUNT); do
29487                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS
29488         done
29489 }
29490
29491 test_820() {
29492         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
29493
29494         mkdir $DIR/$tdir
29495         umount_client $MOUNT || error "umount failed"
29496         for num in $(seq $OSTCOUNT); do
29497                 stop ost$num
29498         done
29499
29500         # mount client with no active OSTs
29501         # so that the client can't initialize max LOV EA size
29502         # from OSC notifications
29503         mount_client $MOUNT || error "mount failed"
29504         # delay OST starting to keep this 0 max EA size for a while
29505         test_820_start_ost &
29506
29507         # create a directory on MDS2
29508         test_mkdir -i 1 -c1 $DIR/$tdir/mds2 ||
29509                 error "Failed to create directory"
29510         # open intent should update default EA size
29511         # see mdc_update_max_ea_from_body()
29512         # notice this is the very first RPC to MDS2
29513         out=$(cp /etc/services $DIR/$tdir/mds2 2>&1)
29514         ret=$?
29515         echo $out
29516         # With SSK, this situation can lead to -EPERM being returned.
29517         # In that case, simply retry.
29518         if [ $ret -ne 0 ] && $SHARED_KEY; then
29519                 if echo "$out" | grep -q "not permitted"; then
29520                         cp /etc/services $DIR/$tdir/mds2
29521                         ret=$?
29522                 fi
29523         fi
29524         [ $ret -eq 0 ] || error "Failed to copy files to mds$n"
29525 }
29526 run_test 820 "update max EA from open intent"
29527
29528 test_823() {
29529         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29530         local OST_MAX_PRECREATE=20000
29531
29532         (( $MDS1_VERSION >= $(version_code 2.14.56) )) ||
29533                 skip "Need MDS version at least 2.14.56"
29534
29535         save_lustre_params mds1 \
29536                 "osp.$FSNAME-OST*-osc-MDT0000.max_create_count" > $p
29537         do_facet $SINGLEMDS "$LCTL set_param -n \
29538                 osp.$FSNAME-OST*MDT0000.max_create_count=0"
29539         do_facet $SINGLEMDS "$LCTL set_param -n \
29540                 osp.$FSNAME-OST0000*MDT0000.max_create_count=$OST_MAX_PRECREATE"
29541
29542         stack_trap "restore_lustre_params < $p; rm $p"
29543
29544         do_facet $SINGLEMDS "$LCTL set_param -n \
29545                 osp.$FSNAME-OST*-osc-MDT*.create_count=100200"
29546
29547         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29548                       osp.$FSNAME-OST0000*MDT0000.create_count")
29549         local max=$(do_facet $SINGLEMDS "$LCTL get_param -n \
29550                     osp.$FSNAME-OST0000*MDT0000.max_create_count")
29551         local expect_count=$(((($max/2)/256) * 256))
29552
29553         log "setting create_count to 100200:"
29554         log " -result- count: $count with max: $max, expecting: $expect_count"
29555
29556         [[ $count -eq expect_count ]] ||
29557                 error "Create count not set to max precreate."
29558 }
29559 run_test 823 "Setting create_count > OST_MAX_PRECREATE is lowered to maximum"
29560
29561 test_831() {
29562         [[ $MDS1_VERSION -lt $(version_code 2.14.56) ]] &&
29563                 skip "Need MDS version 2.14.56"
29564
29565         local sync_changes=$(do_facet $SINGLEMDS \
29566                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29567
29568         [ "$sync_changes" -gt 100 ] &&
29569                 skip "Sync changes $sync_changes > 100 already"
29570
29571         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
29572
29573         $LFS mkdir -i 0 $DIR/$tdir
29574         $LFS setstripe -c 1 -i 0 $DIR/$tdir
29575
29576         save_lustre_params mds1 \
29577                 "osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes" > $p
29578         save_lustre_params mds1 \
29579                 "osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress" >> $p
29580
29581         do_facet mds1 "$LCTL set_param -n \
29582                 osp.$FSNAME-OST*-osc-MDT0000.max_sync_changes=100 \
29583                 osp.$FSNAME-OST*-osc-MDT0000.max_rpcs_in_progress=128"
29584         stack_trap "restore_lustre_params < $p" EXIT
29585
29586         createmany -o $DIR/$tdir/f- 1000
29587         unlinkmany $DIR/$tdir/f- 1000 &
29588         local UNLINK_PID=$!
29589
29590         while sleep 1; do
29591                 sync_changes=$(do_facet mds1 \
29592                 $LCTL get_param -n osp.$FSNAME-OST0000-osc-MDT0000.sync_changes)
29593                 # the check in the code is racy, fail the test
29594                 # if the value above the limit by 10.
29595                 [ $sync_changes -gt 110 ] && {
29596                         kill -2 $UNLINK_PID
29597                         wait
29598                         error "osp changes throttling failed, $sync_changes>110"
29599                 }
29600                 kill -0 $UNLINK_PID 2> /dev/null || break
29601         done
29602         wait
29603 }
29604 run_test 831 "throttling unlink/setattr queuing on OSP"
29605
29606 test_832() {
29607         (( $MDSCOUNT >= 2 )) || skip "needs >= 2 MDTs"
29608         (( $MDS1_VERSION >= $(version_code 2.15.52) )) ||
29609                 skip "Need MDS version 2.15.52+"
29610         is_rmentry_supported || skip "rm_entry not supported"
29611
29612         mkdir_on_mdt0 $DIR/$tdir || error "mkdir $tdir failed"
29613         mkdir $DIR/$tdir/local_dir || error "mkdir local_dir failed"
29614         mkdir_on_mdt -i 1 $DIR/$tdir/remote_dir ||
29615                 error "mkdir remote_dir failed"
29616         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/striped_dir ||
29617                 error "mkdir striped_dir failed"
29618         touch $DIR/$tdir/file || error "touch file failed"
29619         $LFS rm_entry $DIR/$tdir/* || error "lfs rm_entry $tdir/* failed"
29620         [ -z "$(ls -A $DIR/$tdir)" ] || error "$tdir not empty"
29621 }
29622 run_test 832 "lfs rm_entry"
29623
29624 #
29625 # tests that do cleanup/setup should be run at the end
29626 #
29627
29628 test_900() {
29629         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29630         local ls
29631
29632         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
29633         $LCTL set_param fail_loc=0x903
29634
29635         cancel_lru_locks MGC
29636
29637         FAIL_ON_ERROR=true cleanup
29638         FAIL_ON_ERROR=true setup
29639 }
29640 run_test 900 "umount should not race with any mgc requeue thread"
29641
29642 # LUS-6253/LU-11185
29643 test_901() {
29644         local old
29645         local count
29646         local oldc
29647         local newc
29648         local olds
29649         local news
29650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
29651
29652         # some get_param have a bug to handle dot in param name
29653         cancel_lru_locks MGC
29654         old=$(mount -t lustre | wc -l)
29655         # 1 config+sptlrpc
29656         # 2 params
29657         # 3 nodemap
29658         # 4 IR
29659         old=$((old * 4))
29660         oldc=0
29661         count=0
29662         while [ $old -ne $oldc ]; do
29663                 oldc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29664                 sleep 1
29665                 ((count++))
29666                 if [ $count -ge $TIMEOUT ]; then
29667                         error "too large timeout"
29668                 fi
29669         done
29670         umount_client $MOUNT || error "umount failed"
29671         mount_client $MOUNT || error "mount failed"
29672         cancel_lru_locks MGC
29673         newc=$($LCTL get_param -n 'ldlm.namespaces.MGC*.lock_count')
29674
29675         [ $oldc -lt $newc ] && error "mgc lock leak ($oldc != $newc)"
29676
29677         return 0
29678 }
29679 run_test 901 "don't leak a mgc lock on client umount"
29680
29681 # LU-13377
29682 test_902() {
29683         [ $CLIENT_VERSION -lt $(version_code 2.13.52) ] &&
29684                 skip "client does not have LU-13377 fix"
29685         #define OBD_FAIL_LLITE_SHORT_COMMIT 0x1415
29686         $LCTL set_param fail_loc=0x1415
29687         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
29688         cancel_lru_locks osc
29689         rm -f $DIR/$tfile
29690 }
29691 run_test 902 "test short write doesn't hang lustre"
29692
29693 # LU-14711
29694 test_903() {
29695         $LFS setstripe -i 0 -c 1 $DIR/$tfile $DIR/${tfile}-2
29696         echo "blah" > $DIR/${tfile}-2
29697         dd if=/dev/zero of=$DIR/$tfile bs=1M count=6 conv=fsync
29698         #define OBD_FAIL_OSC_SLOW_PAGE_EVICT 0x417
29699         $LCTL set_param fail_loc=0x417 fail_val=20
29700
29701         mv $DIR/${tfile}-2 $DIR/$tfile # Destroys the big object
29702         sleep 1 # To start the destroy
29703         wait_destroy_complete 150 || error "Destroy taking too long"
29704         cat $DIR/$tfile > /dev/null || error "Evicted"
29705 }
29706 run_test 903 "Test long page discard does not cause evictions"
29707
29708 test_904() {
29709         [ "$mds1_FSTYPE" == "ldiskfs" ] || skip "ldiskfs only test"
29710         do_facet mds1 $DEBUGFS -R features $(mdsdevname 1) |
29711                 grep -q project || skip "skip project quota not supported"
29712
29713         local testfile="$DIR/$tdir/$tfile"
29714         local xattr="trusted.projid"
29715         local projid
29716         local mdts=$(comma_list $(mdts_nodes))
29717         local saved=$(do_facet mds1 $LCTL get_param -n \
29718                 osd-ldiskfs.*MDT0000.enable_projid_xattr)
29719
29720         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=0
29721         stack_trap "do_nodes $mdts $LCTL set_param \
29722                 osd-ldiskfs.*MDT*.enable_projid_xattr=$saved"
29723
29724         mkdir -p $DIR/$tdir
29725         touch $testfile
29726         #hide projid xattr on server
29727         $LFS project -p 1 $testfile ||
29728                 error "set $testfile project id failed"
29729         getfattr -m - $testfile | grep $xattr &&
29730                 error "do not show trusted.projid when disabled on server"
29731         do_nodes $mdts $LCTL set_param osd-ldiskfs.*MDT*.enable_projid_xattr=1
29732         #should be hidden when projid is 0
29733         $LFS project -p 0 $testfile ||
29734                 error "set $testfile project id failed"
29735         getfattr -m - $testfile | grep $xattr &&
29736                 error "do not show trusted.projid with project ID 0"
29737
29738         #still can getxattr explicitly
29739         projid=$(getfattr -n $xattr $testfile |
29740                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29741         [ $projid == "0" ] ||
29742                 error "projid expected 0 not $projid"
29743
29744         #set the projid via setxattr
29745         setfattr -n $xattr -v "1000" $testfile ||
29746                 error "setattr failed with $?"
29747         projid=($($LFS project $testfile))
29748         [ ${projid[0]} == "1000" ] ||
29749                 error "projid expected 1000 not $projid"
29750
29751         #check the new projid via getxattr
29752         $LFS project -p 1001 $testfile ||
29753                 error "set $testfile project id failed"
29754         getfattr -m - $testfile | grep $xattr ||
29755                 error "should show trusted.projid when project ID != 0"
29756         projid=$(getfattr -n $xattr $testfile |
29757                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29758         [ $projid == "1001" ] ||
29759                 error "projid expected 1001 not $projid"
29760
29761         #try to set invalid projid
29762         setfattr -n $xattr -v "4294967295" $testfile &&
29763                 error "set invalid projid should fail"
29764
29765         #remove the xattr means setting projid to 0
29766         setfattr -x $xattr $testfile ||
29767                 error "setfattr failed with $?"
29768         projid=($($LFS project $testfile))
29769         [ ${projid[0]} == "0" ] ||
29770                 error "projid expected 0 not $projid"
29771
29772         #should be hidden when parent has inherit flag and same projid
29773         $LFS project -srp 1002 $DIR/$tdir ||
29774                 error "set $tdir project id failed"
29775         getfattr -m - $testfile | grep $xattr &&
29776                 error "do not show trusted.projid with inherit flag"
29777
29778         #still can getxattr explicitly
29779         projid=$(getfattr -n $xattr $testfile |
29780                 sed -n 's/^trusted\.projid="\(.*\)"/\1/p')
29781         [ $projid == "1002" ] ||
29782                 error "projid expected 1002 not $projid"
29783 }
29784 run_test 904 "virtual project ID xattr"
29785
29786 # LU-8582
29787 test_905() {
29788         (( $OST1_VERSION >= $(version_code 2.8.54) )) ||
29789                 skip "lustre < 2.8.54 does not support ladvise"
29790
29791         remote_ost_nodsh && skip "remote OST with nodsh"
29792         $LFS setstripe -c -1 -i 0 $DIR/$tfile || error "setstripe failed"
29793
29794         $LFS ladvise -a willread $DIR/$tfile || error "ladvise does not work"
29795
29796         #define OBD_FAIL_OST_OPCODE 0x253
29797         # OST_LADVISE = 21
29798         do_facet ost1 "$LCTL set_param fail_val=21 fail_loc=0x0253"
29799         $LFS ladvise -a willread $DIR/$tfile &&
29800                 error "unexpected success of ladvise with fault injection"
29801         $LFS ladvise -a willread $DIR/$tfile |&
29802                 grep -q "Operation not supported"
29803         (( $? == 0 )) || error "unexpected stderr of ladvise with fault injection"
29804 }
29805 run_test 905 "bad or new opcode should not stuck client"
29806
29807 test_906() {
29808         grep -q io_uring_setup /proc/kallsyms ||
29809                 skip "Client OS does not support io_uring I/O engine"
29810         io_uring_probe || skip "kernel does not support io_uring fully"
29811         which fio || skip_env "no fio installed"
29812         fio --enghelp | grep -q io_uring ||
29813                 skip_env "fio does not support io_uring I/O engine"
29814
29815         local file=$DIR/$tfile
29816         local ioengine="io_uring"
29817         local numjobs=2
29818         local size=50M
29819
29820         fio --name=seqwrite --ioengine=$ioengine        \
29821                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29822                 --iodepth=64 --size=$size --filename=$file --rw=write ||
29823                 error "fio seqwrite $file failed"
29824
29825         fio --name=seqread --ioengine=$ioengine \
29826                 --bs=$PAGE_SIZE --direct=1 --numjobs=$numjobs   \
29827                 --iodepth=64 --size=$size --filename=$file --rw=read ||
29828                 error "fio seqread $file failed"
29829
29830         rm -f $file || error "rm -f $file failed"
29831 }
29832 run_test 906 "Simple test for io_uring I/O engine via fio"
29833
29834 complete $SECONDS
29835 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
29836 check_and_cleanup_lustre
29837 if [ "$I_MOUNTED" != "yes" ]; then
29838         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
29839 fi
29840 exit_status